127104ee2SJacob Faibussowitsch #include <petsc/private/petscimpl.h> /*I "petscsys.h" I*/ 2d9262e54SJed Brown 3dfb7d7afSStefano Zampini #if defined(PETSC_USE_DEBUG) && !defined(PETSC_HAVE_THREADSAFETY) 427104ee2SJacob Faibussowitsch PetscStack petscstack; 527104ee2SJacob Faibussowitsch #endif 615681b3cSBarry Smith 7e04113cfSBarry Smith #if defined(PETSC_HAVE_SAWS) 8e04113cfSBarry Smith #include <petscviewersaws.h> 915681b3cSBarry Smith 102657e9d9SBarry Smith static PetscBool amsmemstack = PETSC_FALSE; 1115681b3cSBarry Smith 125d83a8b1SBarry Smith /*@ 13e04113cfSBarry Smith PetscStackSAWsGrantAccess - Grants access of the PETSc stack frames to the SAWs publisher 1415681b3cSBarry Smith 15811af0c4SBarry Smith Collective on `PETSC_COMM_WORLD`? 1615681b3cSBarry Smith 1715681b3cSBarry Smith Level: developer 1815681b3cSBarry Smith 1910450e9eSJacob Faibussowitsch Developer Notes: 2054c05997SPierre Jolivet Cannot use `PetscFunctionBegin`/`PetscFunctionReturn()` or `PetscCallSAWs()` since it may be 2110450e9eSJacob Faibussowitsch used within those routines 2215681b3cSBarry Smith 23db781477SPatrick Sanan .seealso: `PetscObjectSetName()`, `PetscObjectSAWsViewOff()`, `PetscObjectSAWsTakeAccess()` 2415681b3cSBarry Smith @*/ 25d71ae5a4SJacob Faibussowitsch void PetscStackSAWsGrantAccess(void) 26d71ae5a4SJacob Faibussowitsch { 27ec957eceSBarry Smith if (amsmemstack) { 2816ad0300SBarry Smith /* ignore any errors from SAWs */ 29dd460d27SBarry Smith (void)SAWs_Unlock(); 3015681b3cSBarry Smith } 31d9262e54SJed Brown } 32d9262e54SJed Brown 335d83a8b1SBarry Smith /*@ 34586f9135SBarry Smith PetscStackSAWsTakeAccess - Takes access of the PETSc stack frames from the SAWs publisher 3515681b3cSBarry Smith 36811af0c4SBarry Smith Collective on `PETSC_COMM_WORLD`? 3715681b3cSBarry Smith 3815681b3cSBarry Smith Level: developer 3915681b3cSBarry Smith 4010450e9eSJacob Faibussowitsch Developer Notes: 4110450e9eSJacob Faibussowitsch Cannot use `PetscFunctionBegin`/`PetscFunctionReturn()` or `PetscCallSAWs()` since it may be 4210450e9eSJacob Faibussowitsch used within those routines 4315681b3cSBarry Smith 4410450e9eSJacob Faibussowitsch .seealso: `PetscObjectSetName()`, `PetscObjectSAWsViewOff()`, `PetscObjectSAWsGrantAccess()` 4515681b3cSBarry Smith @*/ 46d71ae5a4SJacob Faibussowitsch void PetscStackSAWsTakeAccess(void) 47d71ae5a4SJacob Faibussowitsch { 48ec957eceSBarry Smith if (amsmemstack) { 4916ad0300SBarry Smith /* ignore any errors from SAWs */ 50dd460d27SBarry Smith (void)SAWs_Lock(); 5115681b3cSBarry Smith } 5215681b3cSBarry Smith } 5315681b3cSBarry Smith 54d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscStackViewSAWs(void) 55d71ae5a4SJacob Faibussowitsch { 56d45a07a7SBarry Smith PetscMPIInt rank; 5715681b3cSBarry Smith 589566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(PETSC_COMM_WORLD, &rank)); 593ba16761SJacob Faibussowitsch if (rank) return PETSC_SUCCESS; 6027104ee2SJacob Faibussowitsch #if PetscDefined(USE_DEBUG) 61792fecdfSBarry Smith PetscCallSAWs(SAWs_Register, ("/PETSc/Stack/functions", petscstack.function, 20, SAWs_READ, SAWs_STRING)); 62792fecdfSBarry Smith PetscCallSAWs(SAWs_Register, ("/PETSc/Stack/__current_size", &petscstack.currentsize, 1, SAWs_READ, SAWs_INT)); 6327104ee2SJacob Faibussowitsch #endif 642657e9d9SBarry Smith amsmemstack = PETSC_TRUE; 653ba16761SJacob Faibussowitsch return PETSC_SUCCESS; 6615681b3cSBarry Smith } 6715681b3cSBarry Smith 68d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscStackSAWsViewOff(void) 69d71ae5a4SJacob Faibussowitsch { 70d9262e54SJed Brown PetscFunctionBegin; 713ba16761SJacob Faibussowitsch if (!amsmemstack) PetscFunctionReturn(PETSC_SUCCESS); 72792fecdfSBarry Smith PetscCallSAWs(SAWs_Delete, ("/PETSc/Stack")); 732657e9d9SBarry Smith amsmemstack = PETSC_FALSE; 743ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 75d9262e54SJed Brown } 7627104ee2SJacob Faibussowitsch #endif /* PETSC_HAVE_SAWS */ 77d9262e54SJed Brown 78dfb7d7afSStefano Zampini #if PetscDefined(USE_DEBUG) && !PetscDefined(HAVE_THREADSAFETY) 79d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscStackSetCheck(PetscBool check) 80d71ae5a4SJacob Faibussowitsch { 8127104ee2SJacob Faibussowitsch petscstack.check = check; 823ba16761SJacob Faibussowitsch return PETSC_SUCCESS; 837fdeb8b9SBarry Smith } 8415681b3cSBarry Smith 85d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscStackReset(void) 86d71ae5a4SJacob Faibussowitsch { 8727104ee2SJacob Faibussowitsch memset(&petscstack, 0, sizeof(petscstack)); 883ba16761SJacob Faibussowitsch return PETSC_SUCCESS; 8974b43855SShri Abhyankar } 9074b43855SShri Abhyankar 9125073096SBarry Smith // PetscClangLinter pragma disable: -fdoc-sowing-chars 9210450e9eSJacob Faibussowitsch /* 93586f9135SBarry Smith PetscStackView - Print the current (default) PETSc stack to an ASCII file 94586f9135SBarry Smith 95586f9135SBarry Smith Not Collective 96586f9135SBarry Smith 97586f9135SBarry Smith Input Parameter: 98*67a21fd9SBarry Smith . file - the file pointer, or `NULL` to use `PETSC_STDERR` 99586f9135SBarry Smith 100586f9135SBarry Smith Level: developer 101586f9135SBarry Smith 102586f9135SBarry Smith Notes: 10310450e9eSJacob Faibussowitsch In debug mode PETSc maintains a stack of the current function calls that can be used to help 10410450e9eSJacob Faibussowitsch to quickly see where a problem has occurred, for example, when a signal is received. It is 10510450e9eSJacob Faibussowitsch recommended to use the debugger if extensive information is needed to help debug the problem. 106586f9135SBarry Smith 107*67a21fd9SBarry Smith If `file` is `PETSC_STDERR` (or `NULL`) then `PetscErrorPrintf()` is used to print the stack, otherwise `fprintf()` is used. 108*67a21fd9SBarry Smith 109*67a21fd9SBarry Smith Developer Note: 110586f9135SBarry Smith The default stack is a global variable called `petscstack`. 111586f9135SBarry Smith 112586f9135SBarry Smith .seealso: `PetscAttachDebugger()`, `PetscStackCopy()`, `PetscStackPrint()`, `PetscStackSAWsGrantAccess()`, `PetscStackSAWsTakeAccess()` 11310450e9eSJacob Faibussowitsch */ 114d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscStackView(FILE *file) 115d71ae5a4SJacob Faibussowitsch { 116*67a21fd9SBarry Smith if (!file) file = PETSC_STDERR; 11727104ee2SJacob Faibussowitsch if (petscstack.currentsize < 0) { 11827104ee2SJacob Faibussowitsch /* < 0 is absolutely a corrupted stack, but this function is usually called in an error 11927104ee2SJacob Faibussowitsch * handler, which are not capable of recovering from errors so best we can do is print 12027104ee2SJacob Faibussowitsch * this warning */ 12127104ee2SJacob Faibussowitsch fprintf(file, "PetscStack is definitely corrupted with stack size %d\n", petscstack.currentsize); 12227104ee2SJacob Faibussowitsch } else if (petscstack.currentsize == 0) { 123*67a21fd9SBarry Smith if (file == PETSC_STDERR) { 1243ba16761SJacob Faibussowitsch PetscCall((*PetscErrorPrintf)("No error traceback is available, the problem could be in the main program. \n")); 1256d07e311SBarry Smith } else { 1267a746cd8SPierre Jolivet fprintf(file, "No error traceback is available, the problem could be in the main program. \n"); 1276d07e311SBarry Smith } 1286d07e311SBarry Smith } else { 129bbcf679cSJacob Faibussowitsch char *ptr = NULL; 130ef1023bdSBarry Smith 131*67a21fd9SBarry Smith if (file == PETSC_STDERR) { 1329c9354e5SBarry Smith PetscCall((*PetscErrorPrintf)("The line numbers in the error traceback may not be exact.\n")); 13327104ee2SJacob Faibussowitsch for (int i = petscstack.currentsize - 1, j = 1; i >= 0; --i, ++j) { 1343ba16761SJacob Faibussowitsch if (petscstack.file[i]) PetscCall((*PetscErrorPrintf)("#%d %s() at %s:%d\n", j, petscstack.function[i], PetscCIFilename(petscstack.file[i]), PetscCILinenumber(petscstack.line[i]))); 135ef1023bdSBarry Smith else { 1363ba16761SJacob Faibussowitsch PetscCall(PetscStrstr(petscstack.function[i], " ", &ptr)); 1373ba16761SJacob Faibussowitsch if (!ptr) PetscCall((*PetscErrorPrintf)("#%d %s()\n", j, petscstack.function[i])); 1383ba16761SJacob Faibussowitsch else PetscCall((*PetscErrorPrintf)("#%d %s\n", j, petscstack.function[i])); 139ef1023bdSBarry Smith } 14027104ee2SJacob Faibussowitsch } 141d9262e54SJed Brown } else { 142660278c0SBarry Smith fprintf(file, "The line numbers in the error traceback are not always exact.\n"); 14327104ee2SJacob Faibussowitsch for (int i = petscstack.currentsize - 1, j = 1; i >= 0; --i, ++j) { 144660278c0SBarry 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])); 145ef1023bdSBarry Smith else { 1463ba16761SJacob Faibussowitsch PetscCall(PetscStrstr(petscstack.function[i], " ", &ptr)); 147ef1023bdSBarry Smith if (!ptr) fprintf(file, "[%d] #%d %s()\n", PetscGlobalRank, j, petscstack.function[i]); 148ef1023bdSBarry Smith else fprintf(file, "[%d] #%d %s\n", PetscGlobalRank, j, petscstack.function[i]); 149ef1023bdSBarry Smith } 150d9262e54SJed Brown } 1516d07e311SBarry Smith } 1527d5f7e0cSShri Abhyankar } 1533ba16761SJacob Faibussowitsch return PETSC_SUCCESS; 154d9262e54SJed Brown } 155d9262e54SJed Brown 15610450e9eSJacob Faibussowitsch /* 157586f9135SBarry Smith PetscStackCopy - Copy the information from one PETSc stack to another 158586f9135SBarry Smith 159586f9135SBarry Smith Not Collective 160586f9135SBarry Smith 161586f9135SBarry Smith Input Parameter: 162586f9135SBarry Smith . sint - the stack to be copied from 163586f9135SBarry Smith 164586f9135SBarry Smith Output Parameter: 165586f9135SBarry Smith . sout - the stack to be copied to, this stack must already exist 166586f9135SBarry Smith 167586f9135SBarry Smith Level: developer 168586f9135SBarry Smith 169811af0c4SBarry Smith Note: 17010450e9eSJacob Faibussowitsch In debug mode PETSc maintains a stack of the current function calls that can be used to help 17110450e9eSJacob Faibussowitsch to quickly see where a problem has occurred, for example, when a signal is received. It is 17210450e9eSJacob Faibussowitsch recommended to use the debugger if extensive information is needed to help debug the problem. 173586f9135SBarry Smith 174586f9135SBarry Smith .seealso: `PetscAttachDebugger()`, `PetscStackView()` 17510450e9eSJacob Faibussowitsch */ 176d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscStackCopy(PetscStack *sint, PetscStack *sout) 177d71ae5a4SJacob Faibussowitsch { 17827104ee2SJacob Faibussowitsch if (sint) { 17927104ee2SJacob Faibussowitsch for (int i = 0; i < sint->currentsize; ++i) { 180d9262e54SJed Brown sout->function[i] = sint->function[i]; 181d9262e54SJed Brown sout->file[i] = sint->file[i]; 182d9262e54SJed Brown sout->line[i] = sint->line[i]; 183a8d2bbe5SBarry Smith sout->petscroutine[i] = sint->petscroutine[i]; 184d9262e54SJed Brown } 185d9262e54SJed Brown sout->currentsize = sint->currentsize; 18627104ee2SJacob Faibussowitsch } else { 18727104ee2SJacob Faibussowitsch sout->currentsize = 0; 188d9262e54SJed Brown } 1893ba16761SJacob Faibussowitsch return PETSC_SUCCESS; 190d9262e54SJed Brown } 191d9262e54SJed Brown 19225073096SBarry Smith // PetscClangLinter pragma disable: -fdoc-sowing-chars 19310450e9eSJacob Faibussowitsch /* 194586f9135SBarry Smith PetscStackPrint - Prints a given PETSc stack to an ASCII file 195586f9135SBarry Smith 196586f9135SBarry Smith Not Collective 197586f9135SBarry Smith 198586f9135SBarry Smith Input Parameters: 199586f9135SBarry Smith + sint - the PETSc stack to print 20025073096SBarry Smith - fp - the file pointer 201586f9135SBarry Smith 202586f9135SBarry Smith Level: developer 203586f9135SBarry Smith 204586f9135SBarry Smith Notes: 20510450e9eSJacob Faibussowitsch In debug mode PETSc maintains a stack of the current function calls that can be used to help 20610450e9eSJacob Faibussowitsch to quickly see where a problem has occurred, for example, when a signal is received. It is 20710450e9eSJacob Faibussowitsch recommended to use the debugger if extensive information is needed to help debug the problem. 208586f9135SBarry Smith 209586f9135SBarry Smith The default stack is a global variable called `petscstack`. 210586f9135SBarry Smith 211586f9135SBarry Smith Developer Note: 212586f9135SBarry Smith `PetscStackPrint()` and `PetscStackView()` should be merged into a single API. 213586f9135SBarry Smith 214586f9135SBarry Smith .seealso: `PetscAttachDebugger()`, `PetscStackCopy()`, `PetscStackView()` 21510450e9eSJacob Faibussowitsch */ 216d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscStackPrint(PetscStack *sint, FILE *fp) 217d71ae5a4SJacob Faibussowitsch { 21827104ee2SJacob Faibussowitsch if (sint) { 2199c9354e5SBarry Smith for (int i = sint->currentsize; i >= 0; --i) { 220660278c0SBarry 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])); 221ef1023bdSBarry Smith else fprintf(fp, " [%d] %s()\n", PetscGlobalRank, sint->function[i]); 22227104ee2SJacob Faibussowitsch } 22327104ee2SJacob Faibussowitsch } 2243ba16761SJacob Faibussowitsch return PETSC_SUCCESS; 225d9262e54SJed Brown } 22627104ee2SJacob Faibussowitsch #endif /* PetscDefined(USE_DEBUG) */ 227