xref: /petsc/src/sys/error/pstack.c (revision 792fecdfe9134cce4d631112660ddd34f063bc17) !
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 
1615681b3cSBarry Smith    Collective on PETSC_COMM_WORLD?
1715681b3cSBarry Smith 
1815681b3cSBarry Smith    Level: developer
1915681b3cSBarry Smith 
20*792fecdfSBarry Smith    Developers Note: Cannot use PetscFunctionBegin/Return() or PetscCallSAWs() since it may be used within those routines
2115681b3cSBarry Smith 
22db781477SPatrick Sanan .seealso: `PetscObjectSetName()`, `PetscObjectSAWsViewOff()`, `PetscObjectSAWsTakeAccess()`
2315681b3cSBarry Smith 
2415681b3cSBarry Smith @*/
25e04113cfSBarry Smith void  PetscStackSAWsGrantAccess(void)
26d9262e54SJed Brown {
27ec957eceSBarry Smith   if (amsmemstack) {
2816ad0300SBarry Smith     /* ignore any errors from SAWs */
299a492a5cSBarry Smith     SAWs_Unlock();
3015681b3cSBarry Smith   }
31d9262e54SJed Brown }
32d9262e54SJed Brown 
3315681b3cSBarry Smith /*@C
34586f9135SBarry Smith    PetscStackSAWsTakeAccess - Takes access of the PETSc stack frames from the SAWs publisher
3515681b3cSBarry Smith 
3615681b3cSBarry Smith    Collective on PETSC_COMM_WORLD?
3715681b3cSBarry Smith 
3815681b3cSBarry Smith    Level: developer
3915681b3cSBarry Smith 
40*792fecdfSBarry Smith    Developers Note: Cannot use PetscFunctionBegin/Return() or PetscCallSAWs() since it may be used within those routines
4115681b3cSBarry Smith 
42db781477SPatrick Sanan .seealso: `PetscObjectSetName()`, `PetscObjectSAWsViewOff()`, `PetscObjectSAWsTakeAccess()`
4315681b3cSBarry Smith 
4415681b3cSBarry Smith @*/
45e04113cfSBarry Smith void  PetscStackSAWsTakeAccess(void)
46d9262e54SJed Brown {
47ec957eceSBarry Smith   if (amsmemstack) {
4816ad0300SBarry Smith     /* ignore any errors from SAWs */
499a492a5cSBarry Smith     SAWs_Lock();
5015681b3cSBarry Smith   }
5115681b3cSBarry Smith }
5215681b3cSBarry Smith 
53e04113cfSBarry Smith PetscErrorCode PetscStackViewSAWs(void)
5415681b3cSBarry Smith {
55d45a07a7SBarry Smith   PetscMPIInt    rank;
5615681b3cSBarry Smith 
579566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_rank(PETSC_COMM_WORLD,&rank));
58d45a07a7SBarry Smith   if (rank) return 0;
5927104ee2SJacob Faibussowitsch #if PetscDefined(USE_DEBUG)
60*792fecdfSBarry Smith   PetscCallSAWs(SAWs_Register,("/PETSc/Stack/functions",petscstack.function,20,SAWs_READ,SAWs_STRING));
61*792fecdfSBarry Smith   PetscCallSAWs(SAWs_Register,("/PETSc/Stack/__current_size",&petscstack.currentsize,1,SAWs_READ,SAWs_INT));
6227104ee2SJacob Faibussowitsch #endif
632657e9d9SBarry Smith   amsmemstack = PETSC_TRUE;
6415681b3cSBarry Smith   return 0;
6515681b3cSBarry Smith }
6615681b3cSBarry Smith 
67e04113cfSBarry Smith PetscErrorCode PetscStackSAWsViewOff(void)
6815681b3cSBarry Smith {
69d9262e54SJed Brown   PetscFunctionBegin;
70d45a07a7SBarry Smith   if (!amsmemstack) PetscFunctionReturn(0);
71*792fecdfSBarry Smith   PetscCallSAWs(SAWs_Delete,("/PETSc/Stack"));
722657e9d9SBarry Smith   amsmemstack = PETSC_FALSE;
73d9262e54SJed Brown   PetscFunctionReturn(0);
74d9262e54SJed Brown }
7527104ee2SJacob Faibussowitsch #endif /* PETSC_HAVE_SAWS */
76d9262e54SJed Brown 
7727104ee2SJacob Faibussowitsch #if PetscDefined(USE_DEBUG)
7827104ee2SJacob Faibussowitsch PetscErrorCode PetscStackSetCheck(PetscBool check)
7974b43855SShri Abhyankar {
8027104ee2SJacob Faibussowitsch   petscstack.check = check;
8127104ee2SJacob Faibussowitsch   return 0;
827fdeb8b9SBarry Smith }
8315681b3cSBarry Smith 
8427104ee2SJacob Faibussowitsch PetscErrorCode PetscStackReset(void)
8515681b3cSBarry Smith {
8627104ee2SJacob Faibussowitsch   memset(&petscstack,0,sizeof(petscstack));
8774b43855SShri Abhyankar   return 0;
8874b43855SShri Abhyankar }
8974b43855SShri Abhyankar 
90586f9135SBarry Smith /*@C
91586f9135SBarry Smith    PetscStackView - Print the current (default) PETSc stack to an ASCII file
92586f9135SBarry Smith 
93586f9135SBarry Smith    Not Collective
94586f9135SBarry Smith 
95586f9135SBarry Smith    Input Parameter:
96586f9135SBarry Smith .   file - the file pointer, or `NULL` to use `PETSC_STDOUT`
97586f9135SBarry Smith 
98586f9135SBarry Smith    Level: developer
99586f9135SBarry Smith 
100586f9135SBarry Smith    Notes:
101586f9135SBarry 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
102586f9135SBarry Smith    occurred, for example, when a signal is received. It is recommended to use the debugger if extensive information is needed to
103586f9135SBarry Smith    help debug the problem.
104586f9135SBarry Smith 
105586f9135SBarry Smith    The default stack is a global variable called `petscstack`.
106586f9135SBarry Smith 
107586f9135SBarry Smith .seealso: `PetscAttachDebugger()`, `PetscStackCopy()`, `PetscStackPrint()`, `PetscStackSAWsGrantAccess()`, `PetscStackSAWsTakeAccess()`
108586f9135SBarry Smith @*/
109639ff905SBarry Smith PetscErrorCode  PetscStackView(FILE *file)
110d9262e54SJed Brown {
111639ff905SBarry Smith   if (!file) file = PETSC_STDOUT;
11227104ee2SJacob Faibussowitsch   if (petscstack.currentsize < 0) {
11327104ee2SJacob Faibussowitsch     /* < 0 is absolutely a corrupted stack, but this function is usually called in an error
11427104ee2SJacob Faibussowitsch      * handler, which are not capable of recovering from errors so best we can do is print
11527104ee2SJacob Faibussowitsch      * this warning */
11627104ee2SJacob Faibussowitsch     fprintf(file,"PetscStack is definitely corrupted with stack size %d\n",petscstack.currentsize);
11727104ee2SJacob Faibussowitsch   } else if (petscstack.currentsize == 0) {
118d9262e54SJed Brown     if (file == PETSC_STDOUT) {
1197a746cd8SPierre Jolivet       (*PetscErrorPrintf)("No error traceback is available, the problem could be in the main program. \n");
1206d07e311SBarry Smith     } else {
1217a746cd8SPierre Jolivet       fprintf(file,"No error traceback is available, the problem could be in the main program. \n");
1226d07e311SBarry Smith     }
1236d07e311SBarry Smith   } else {
124ef1023bdSBarry Smith     char *ptr;
125ef1023bdSBarry Smith 
1266d07e311SBarry Smith     if (file == PETSC_STDOUT) {
1276d07e311SBarry Smith       (*PetscErrorPrintf)("The EXACT line numbers in the error traceback are not available.\n");
1286d07e311SBarry Smith       (*PetscErrorPrintf)("instead the line number of the start of the function is given.\n");
12927104ee2SJacob Faibussowitsch       for (int i = petscstack.currentsize-1, j = 1; i >= 0; --i, ++j) {
130ef1023bdSBarry Smith         if (petscstack.file[i]) (*PetscErrorPrintf)("#%d %s() at %s:%d\n",j,petscstack.function[i],petscstack.file[i],petscstack.line[i]);
131ef1023bdSBarry Smith         else {
132ef1023bdSBarry Smith           PetscStrstr(petscstack.function[i]," ",&ptr);
133ef1023bdSBarry Smith           if (!ptr) (*PetscErrorPrintf)("#%d %s()\n",j,petscstack.function[i]);
134ef1023bdSBarry Smith           else (*PetscErrorPrintf)("#%d %s\n",j,petscstack.function[i]);
135ef1023bdSBarry Smith         }
13627104ee2SJacob Faibussowitsch       }
137d9262e54SJed Brown     } else {
1386d07e311SBarry Smith       fprintf(file,"The EXACT line numbers in the error traceback are not available.\n");
1396d07e311SBarry Smith       fprintf(file,"Instead the line number of the start of the function is given.\n");
14027104ee2SJacob Faibussowitsch       for (int i = petscstack.currentsize-1, j = 1; i >= 0; --i, ++j) {
141ef1023bdSBarry Smith         if (petscstack.file[i]) fprintf(file,"[%d] #%d %s() at %s:%d\n",PetscGlobalRank,j,petscstack.function[i],petscstack.file[i],petscstack.line[i]);
142ef1023bdSBarry Smith         else {
143ef1023bdSBarry Smith           PetscStrstr(petscstack.function[i]," ",&ptr);
144ef1023bdSBarry Smith           if (!ptr) fprintf(file,"[%d] #%d %s()\n",PetscGlobalRank,j,petscstack.function[i]);
145ef1023bdSBarry Smith           else fprintf(file,"[%d] #%d %s\n",PetscGlobalRank,j,petscstack.function[i]);
146ef1023bdSBarry Smith         }
147d9262e54SJed Brown       }
1486d07e311SBarry Smith     }
1497d5f7e0cSShri Abhyankar   }
150d9262e54SJed Brown   return 0;
151d9262e54SJed Brown }
152d9262e54SJed Brown 
153586f9135SBarry Smith /*@C
154586f9135SBarry Smith    PetscStackCopy - Copy the information from one PETSc stack to another
155586f9135SBarry Smith 
156586f9135SBarry Smith    Not Collective
157586f9135SBarry Smith 
158586f9135SBarry Smith    Input Parameter:
159586f9135SBarry Smith .   sint - the stack to be copied from
160586f9135SBarry Smith 
161586f9135SBarry Smith    Output Parameter:
162586f9135SBarry Smith .   sout - the stack to be copied to, this stack must already exist
163586f9135SBarry Smith 
164586f9135SBarry Smith    Level: developer
165586f9135SBarry Smith 
166586f9135SBarry Smith    Notes:
167586f9135SBarry 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
168586f9135SBarry Smith    occurred, for example, when a signal is received. It is recommended to use the debugger if extensive information is needed to
169586f9135SBarry Smith    help debug the problem.
170586f9135SBarry Smith 
171586f9135SBarry Smith .seealso: `PetscAttachDebugger()`, `PetscStackView()`
172586f9135SBarry Smith @*/
1737087cfbeSBarry Smith PetscErrorCode  PetscStackCopy(PetscStack *sint,PetscStack *sout)
174d9262e54SJed Brown {
17527104ee2SJacob Faibussowitsch   if (sint) {
17627104ee2SJacob Faibussowitsch     for (int i = 0; i < sint->currentsize; ++i) {
177d9262e54SJed Brown       sout->function[i]     = sint->function[i];
178d9262e54SJed Brown       sout->file[i]         = sint->file[i];
179d9262e54SJed Brown       sout->line[i]         = sint->line[i];
180a8d2bbe5SBarry Smith       sout->petscroutine[i] = sint->petscroutine[i];
181d9262e54SJed Brown     }
182d9262e54SJed Brown     sout->currentsize = sint->currentsize;
18327104ee2SJacob Faibussowitsch   } else {
18427104ee2SJacob Faibussowitsch     sout->currentsize = 0;
185d9262e54SJed Brown   }
186d9262e54SJed Brown   return 0;
187d9262e54SJed Brown }
188d9262e54SJed Brown 
189586f9135SBarry Smith /*@C
190586f9135SBarry Smith    PetscStackPrint - Prints a given PETSc stack to an ASCII file
191586f9135SBarry Smith 
192586f9135SBarry Smith    Not Collective
193586f9135SBarry Smith 
194586f9135SBarry Smith    Input Parameters:
195586f9135SBarry Smith +   sint - the PETSc stack to print
196586f9135SBarry Smith -  file - the file pointer
197586f9135SBarry Smith 
198586f9135SBarry Smith    Level: developer
199586f9135SBarry Smith 
200586f9135SBarry Smith    Notes:
201586f9135SBarry 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
202586f9135SBarry Smith    occurred, for example, when a signal is received. It is recommended to use the debugger if extensive information is needed to
203586f9135SBarry Smith    help debug the problem.
204586f9135SBarry Smith 
205586f9135SBarry Smith    The default stack is a global variable called `petscstack`.
206586f9135SBarry Smith 
207586f9135SBarry Smith    Developer Note:
208586f9135SBarry Smith    `PetscStackPrint()` and `PetscStackView()` should be merged into a single API.
209586f9135SBarry Smith 
210586f9135SBarry Smith .seealso: `PetscAttachDebugger()`, `PetscStackCopy()`, `PetscStackView()`
211586f9135SBarry Smith @*/
2127087cfbeSBarry Smith PetscErrorCode  PetscStackPrint(PetscStack *sint,FILE *fp)
213d9262e54SJed Brown {
21427104ee2SJacob Faibussowitsch   if (sint) {
21527104ee2SJacob Faibussowitsch     for (int i = sint->currentsize-2; i >= 0; --i) {
216ef1023bdSBarry Smith       if (sint->file[i]) fprintf(fp,"      [%d]  %s() at %s:%d\n",PetscGlobalRank,sint->function[i],sint->file[i],sint->line[i]);
217ef1023bdSBarry Smith       else fprintf(fp,"      [%d]  %s()\n",PetscGlobalRank,sint->function[i]);
21827104ee2SJacob Faibussowitsch     }
21927104ee2SJacob Faibussowitsch   }
220d9262e54SJed Brown   return 0;
221d9262e54SJed Brown }
22227104ee2SJacob Faibussowitsch #endif /* PetscDefined(USE_DEBUG) */
223