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