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