xref: /petsc/src/sys/error/pstack.c (revision 811af0c4b09a35de4306c442f88bd09fdc09897d)
1d9262e54SJed Brown 
227104ee2SJacob Faibussowitsch #include <petsc/private/petscimpl.h> /*I  "petscsys.h"   I*/
3d9262e54SJed Brown 
427104ee2SJacob Faibussowitsch #if PetscDefined(USE_DEBUG)
527104ee2SJacob Faibussowitsch PetscStack petscstack;
627104ee2SJacob Faibussowitsch #endif
715681b3cSBarry Smith 
8e04113cfSBarry Smith #if defined(PETSC_HAVE_SAWS)
9e04113cfSBarry Smith #include <petscviewersaws.h>
1015681b3cSBarry Smith 
112657e9d9SBarry Smith static PetscBool amsmemstack = PETSC_FALSE;
1215681b3cSBarry Smith 
1315681b3cSBarry Smith /*@C
14e04113cfSBarry Smith    PetscStackSAWsGrantAccess - Grants access of the PETSc stack frames to the SAWs publisher
1515681b3cSBarry Smith 
16*811af0c4SBarry Smith    Collective on `PETSC_COMM_WORLD`?
1715681b3cSBarry Smith 
1815681b3cSBarry Smith    Level: developer
1915681b3cSBarry Smith 
20*811af0c4SBarry Smith    Developers Note:
21*811af0c4SBarry Smith    Cannot use `PetscFunctionBegin`/`PetrscFunctionReturn()` or `PetscCallSAWs()` since it may be used within those routines
2215681b3cSBarry Smith 
23db781477SPatrick Sanan .seealso: `PetscObjectSetName()`, `PetscObjectSAWsViewOff()`, `PetscObjectSAWsTakeAccess()`
2415681b3cSBarry Smith @*/
259371c9d4SSatish Balay void PetscStackSAWsGrantAccess(void) {
26ec957eceSBarry Smith   if (amsmemstack) {
2716ad0300SBarry Smith     /* ignore any errors from SAWs */
289a492a5cSBarry Smith     SAWs_Unlock();
2915681b3cSBarry Smith   }
30d9262e54SJed Brown }
31d9262e54SJed Brown 
3215681b3cSBarry Smith /*@C
33586f9135SBarry Smith    PetscStackSAWsTakeAccess - Takes access of the PETSc stack frames from the SAWs publisher
3415681b3cSBarry Smith 
35*811af0c4SBarry Smith    Collective on `PETSC_COMM_WORLD`?
3615681b3cSBarry Smith 
3715681b3cSBarry Smith    Level: developer
3815681b3cSBarry Smith 
39*811af0c4SBarry Smith    Developers Note:
40*811af0c4SBarry Smith    Cannot use `PetscFunctionBegin`/`PetscFunctionReturn()` or `PetscCallSAWs()` since it may be used within those routines
4115681b3cSBarry Smith 
42db781477SPatrick Sanan .seealso: `PetscObjectSetName()`, `PetscObjectSAWsViewOff()`, `PetscObjectSAWsTakeAccess()`
4315681b3cSBarry Smith @*/
449371c9d4SSatish Balay void PetscStackSAWsTakeAccess(void) {
45ec957eceSBarry Smith   if (amsmemstack) {
4616ad0300SBarry Smith     /* ignore any errors from SAWs */
479a492a5cSBarry Smith     SAWs_Lock();
4815681b3cSBarry Smith   }
4915681b3cSBarry Smith }
5015681b3cSBarry Smith 
519371c9d4SSatish Balay PetscErrorCode PetscStackViewSAWs(void) {
52d45a07a7SBarry Smith   PetscMPIInt rank;
5315681b3cSBarry Smith 
549566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_rank(PETSC_COMM_WORLD, &rank));
55d45a07a7SBarry Smith   if (rank) return 0;
5627104ee2SJacob Faibussowitsch #if PetscDefined(USE_DEBUG)
57792fecdfSBarry Smith   PetscCallSAWs(SAWs_Register, ("/PETSc/Stack/functions", petscstack.function, 20, SAWs_READ, SAWs_STRING));
58792fecdfSBarry Smith   PetscCallSAWs(SAWs_Register, ("/PETSc/Stack/__current_size", &petscstack.currentsize, 1, SAWs_READ, SAWs_INT));
5927104ee2SJacob Faibussowitsch #endif
602657e9d9SBarry Smith   amsmemstack = PETSC_TRUE;
6115681b3cSBarry Smith   return 0;
6215681b3cSBarry Smith }
6315681b3cSBarry Smith 
649371c9d4SSatish Balay PetscErrorCode PetscStackSAWsViewOff(void) {
65d9262e54SJed Brown   PetscFunctionBegin;
66d45a07a7SBarry Smith   if (!amsmemstack) PetscFunctionReturn(0);
67792fecdfSBarry Smith   PetscCallSAWs(SAWs_Delete, ("/PETSc/Stack"));
682657e9d9SBarry Smith   amsmemstack = PETSC_FALSE;
69d9262e54SJed Brown   PetscFunctionReturn(0);
70d9262e54SJed Brown }
7127104ee2SJacob Faibussowitsch #endif /* PETSC_HAVE_SAWS */
72d9262e54SJed Brown 
7327104ee2SJacob Faibussowitsch #if PetscDefined(USE_DEBUG)
749371c9d4SSatish Balay PetscErrorCode PetscStackSetCheck(PetscBool check) {
7527104ee2SJacob Faibussowitsch   petscstack.check = check;
7627104ee2SJacob Faibussowitsch   return 0;
777fdeb8b9SBarry Smith }
7815681b3cSBarry Smith 
799371c9d4SSatish Balay PetscErrorCode PetscStackReset(void) {
8027104ee2SJacob Faibussowitsch   memset(&petscstack, 0, sizeof(petscstack));
8174b43855SShri Abhyankar   return 0;
8274b43855SShri Abhyankar }
8374b43855SShri Abhyankar 
84586f9135SBarry Smith /*@C
85586f9135SBarry Smith    PetscStackView - Print the current (default) PETSc stack to an ASCII file
86586f9135SBarry Smith 
87586f9135SBarry Smith    Not Collective
88586f9135SBarry Smith 
89586f9135SBarry Smith    Input Parameter:
90586f9135SBarry Smith .   file - the file pointer, or `NULL` to use `PETSC_STDOUT`
91586f9135SBarry Smith 
92586f9135SBarry Smith    Level: developer
93586f9135SBarry Smith 
94586f9135SBarry Smith    Notes:
95586f9135SBarry Smith    In debug mode PETSc maintains a stack of the current function calls that can be used to help to quickly see where a problem has
96586f9135SBarry Smith    occurred, for example, when a signal is received. It is recommended to use the debugger if extensive information is needed to
97586f9135SBarry Smith    help debug the problem.
98586f9135SBarry Smith 
99586f9135SBarry Smith    The default stack is a global variable called `petscstack`.
100586f9135SBarry Smith 
101586f9135SBarry Smith .seealso: `PetscAttachDebugger()`, `PetscStackCopy()`, `PetscStackPrint()`, `PetscStackSAWsGrantAccess()`, `PetscStackSAWsTakeAccess()`
102586f9135SBarry Smith @*/
1039371c9d4SSatish Balay PetscErrorCode PetscStackView(FILE *file) {
104639ff905SBarry Smith   if (!file) file = PETSC_STDOUT;
10527104ee2SJacob Faibussowitsch   if (petscstack.currentsize < 0) {
10627104ee2SJacob Faibussowitsch     /* < 0 is absolutely a corrupted stack, but this function is usually called in an error
10727104ee2SJacob Faibussowitsch      * handler, which are not capable of recovering from errors so best we can do is print
10827104ee2SJacob Faibussowitsch      * this warning */
10927104ee2SJacob Faibussowitsch     fprintf(file, "PetscStack is definitely corrupted with stack size %d\n", petscstack.currentsize);
11027104ee2SJacob Faibussowitsch   } else if (petscstack.currentsize == 0) {
111d9262e54SJed Brown     if (file == PETSC_STDOUT) {
1127a746cd8SPierre Jolivet       (*PetscErrorPrintf)("No error traceback is available, the problem could be in the main program. \n");
1136d07e311SBarry Smith     } else {
1147a746cd8SPierre Jolivet       fprintf(file, "No error traceback is available, the problem could be in the main program. \n");
1156d07e311SBarry Smith     }
1166d07e311SBarry Smith   } else {
117ef1023bdSBarry Smith     char *ptr;
118ef1023bdSBarry Smith 
1196d07e311SBarry Smith     if (file == PETSC_STDOUT) {
120660278c0SBarry Smith       (*PetscErrorPrintf)("The line numbers in the error traceback are not always exact.\n");
12127104ee2SJacob Faibussowitsch       for (int i = petscstack.currentsize - 1, j = 1; i >= 0; --i, ++j) {
122660278c0SBarry Smith         if (petscstack.file[i]) (*PetscErrorPrintf)("#%d %s() at %s:%d\n", j, petscstack.function[i], PetscCIFilename(petscstack.file[i]), PetscCILinenumber(petscstack.line[i]));
123ef1023bdSBarry Smith         else {
124ef1023bdSBarry Smith           PetscStrstr(petscstack.function[i], " ", &ptr);
125ef1023bdSBarry Smith           if (!ptr) (*PetscErrorPrintf)("#%d %s()\n", j, petscstack.function[i]);
126ef1023bdSBarry Smith           else (*PetscErrorPrintf)("#%d %s\n", j, petscstack.function[i]);
127ef1023bdSBarry Smith         }
12827104ee2SJacob Faibussowitsch       }
129d9262e54SJed Brown     } else {
130660278c0SBarry Smith       fprintf(file, "The line numbers in the error traceback are not always exact.\n");
13127104ee2SJacob Faibussowitsch       for (int i = petscstack.currentsize - 1, j = 1; i >= 0; --i, ++j) {
132660278c0SBarry Smith         if (petscstack.file[i]) fprintf(file, "[%d] #%d %s() at %s:%d\n", PetscGlobalRank, j, petscstack.function[i], PetscCIFilename(petscstack.file[i]), PetscCILinenumber(petscstack.line[i]));
133ef1023bdSBarry Smith         else {
134ef1023bdSBarry Smith           PetscStrstr(petscstack.function[i], " ", &ptr);
135ef1023bdSBarry Smith           if (!ptr) fprintf(file, "[%d] #%d %s()\n", PetscGlobalRank, j, petscstack.function[i]);
136ef1023bdSBarry Smith           else fprintf(file, "[%d] #%d %s\n", PetscGlobalRank, j, petscstack.function[i]);
137ef1023bdSBarry Smith         }
138d9262e54SJed Brown       }
1396d07e311SBarry Smith     }
1407d5f7e0cSShri Abhyankar   }
141d9262e54SJed Brown   return 0;
142d9262e54SJed Brown }
143d9262e54SJed Brown 
144586f9135SBarry Smith /*@C
145586f9135SBarry Smith    PetscStackCopy - Copy the information from one PETSc stack to another
146586f9135SBarry Smith 
147586f9135SBarry Smith    Not Collective
148586f9135SBarry Smith 
149586f9135SBarry Smith    Input Parameter:
150586f9135SBarry Smith .   sint - the stack to be copied from
151586f9135SBarry Smith 
152586f9135SBarry Smith    Output Parameter:
153586f9135SBarry Smith .   sout - the stack to be copied to, this stack must already exist
154586f9135SBarry Smith 
155586f9135SBarry Smith    Level: developer
156586f9135SBarry Smith 
157*811af0c4SBarry Smith    Note:
158586f9135SBarry Smith    In debug mode PETSc maintains a stack of the current function calls that can be used to help to quickly see where a problem has
159586f9135SBarry Smith    occurred, for example, when a signal is received. It is recommended to use the debugger if extensive information is needed to
160586f9135SBarry Smith    help debug the problem.
161586f9135SBarry Smith 
162586f9135SBarry Smith .seealso: `PetscAttachDebugger()`, `PetscStackView()`
163586f9135SBarry Smith @*/
1649371c9d4SSatish Balay PetscErrorCode PetscStackCopy(PetscStack *sint, PetscStack *sout) {
16527104ee2SJacob Faibussowitsch   if (sint) {
16627104ee2SJacob Faibussowitsch     for (int i = 0; i < sint->currentsize; ++i) {
167d9262e54SJed Brown       sout->function[i]     = sint->function[i];
168d9262e54SJed Brown       sout->file[i]         = sint->file[i];
169d9262e54SJed Brown       sout->line[i]         = sint->line[i];
170a8d2bbe5SBarry Smith       sout->petscroutine[i] = sint->petscroutine[i];
171d9262e54SJed Brown     }
172d9262e54SJed Brown     sout->currentsize = sint->currentsize;
17327104ee2SJacob Faibussowitsch   } else {
17427104ee2SJacob Faibussowitsch     sout->currentsize = 0;
175d9262e54SJed Brown   }
176d9262e54SJed Brown   return 0;
177d9262e54SJed Brown }
178d9262e54SJed Brown 
179586f9135SBarry Smith /*@C
180586f9135SBarry Smith    PetscStackPrint - Prints a given PETSc stack to an ASCII file
181586f9135SBarry Smith 
182586f9135SBarry Smith    Not Collective
183586f9135SBarry Smith 
184586f9135SBarry Smith    Input Parameters:
185586f9135SBarry Smith +   sint - the PETSc stack to print
186586f9135SBarry Smith -  file - the file pointer
187586f9135SBarry Smith 
188586f9135SBarry Smith    Level: developer
189586f9135SBarry Smith 
190586f9135SBarry Smith    Notes:
191586f9135SBarry Smith    In debug mode PETSc maintains a stack of the current function calls that can be used to help to quickly see where a problem has
192586f9135SBarry Smith    occurred, for example, when a signal is received. It is recommended to use the debugger if extensive information is needed to
193586f9135SBarry Smith    help debug the problem.
194586f9135SBarry Smith 
195586f9135SBarry Smith    The default stack is a global variable called `petscstack`.
196586f9135SBarry Smith 
197586f9135SBarry Smith    Developer Note:
198586f9135SBarry Smith    `PetscStackPrint()` and `PetscStackView()` should be merged into a single API.
199586f9135SBarry Smith 
200586f9135SBarry Smith .seealso: `PetscAttachDebugger()`, `PetscStackCopy()`, `PetscStackView()`
201586f9135SBarry Smith @*/
2029371c9d4SSatish Balay PetscErrorCode PetscStackPrint(PetscStack *sint, FILE *fp) {
20327104ee2SJacob Faibussowitsch   if (sint) {
20427104ee2SJacob Faibussowitsch     for (int i = sint->currentsize - 2; i >= 0; --i) {
205660278c0SBarry Smith       if (sint->file[i]) fprintf(fp, "      [%d]  %s() at %s:%d\n", PetscGlobalRank, sint->function[i], PetscCIFilename(sint->file[i]), PetscCILinenumber(sint->line[i]));
206ef1023bdSBarry Smith       else fprintf(fp, "      [%d]  %s()\n", PetscGlobalRank, sint->function[i]);
20727104ee2SJacob Faibussowitsch     }
20827104ee2SJacob Faibussowitsch   }
209d9262e54SJed Brown   return 0;
210d9262e54SJed Brown }
21127104ee2SJacob Faibussowitsch #endif /* PetscDefined(USE_DEBUG) */
212