1af0996ceSBarry Smith #include <petsc/private/petscimpl.h> 205035670SJunchao Zhang 328559dc8SJed Brown static PetscInt petsc_checkpointer_intensity = 1; 428559dc8SJed Brown 528559dc8SJed Brown /*@ 610450e9eSJacob Faibussowitsch PetscCheckPointerSetIntensity - Set the intensity of debug pointer checks 728559dc8SJed Brown 828559dc8SJed Brown Not Collective 928559dc8SJed Brown 104165533cSJose E. Roman Input Parameter: 1128559dc8SJed Brown . intensity - how much to check pointers for validity 1228559dc8SJed Brown 13811af0c4SBarry Smith Options Database Key: 145789d1f5SJed Brown . -check_pointer_intensity - intensity (0, 1, or 2) 15c2f74817SBarry Smith 1628559dc8SJed Brown Level: advanced 1728559dc8SJed Brown 1810450e9eSJacob Faibussowitsch Notes: 1910450e9eSJacob Faibussowitsch An intense pointer check registers a signal handler and attempts to dereference to confirm 2010450e9eSJacob Faibussowitsch whether the address is valid. An intensity of 0 never uses signal handlers, 1 uses them when 2110450e9eSJacob Faibussowitsch not in a "hot" function, and intensity of 2 always uses a signal handler. 2210450e9eSJacob Faibussowitsch 23db781477SPatrick Sanan .seealso: `PetscCheckPointer()`, `PetscFunctionBeginHot()` 2428559dc8SJed Brown @*/ 25d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscCheckPointerSetIntensity(PetscInt intensity) 26d71ae5a4SJacob Faibussowitsch { 2728559dc8SJed Brown PetscFunctionBegin; 280e6b6b59SJacob Faibussowitsch PetscCheck((intensity >= 0) && (intensity <= 2), PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Intensity %" PetscInt_FMT " not in [0,2]", intensity); 290e6b6b59SJacob Faibussowitsch petsc_checkpointer_intensity = intensity; 303ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3128559dc8SJed Brown } 3228559dc8SJed Brown 33d96cc911SJed Brown /* ---------------------------------------------------------------------------------------*/ 34718fc407SJed Brown 350e6b6b59SJacob Faibussowitsch #if PetscDefined(HAVE_SETJMP_H) 36d96cc911SJed Brown #include <setjmp.h> 37f8a67e6dSJed Brown static jmp_buf PetscSegvJumpBuf; 38f8a67e6dSJed Brown static PetscBool PetscSegvJumpBuf_set; 39f8a67e6dSJed Brown 40f8a67e6dSJed Brown /*@C 410e6b6b59SJacob Faibussowitsch PetscSignalSegvCheckPointerOrMpi - To be called from a signal handler for SIGSEGV. 42f8a67e6dSJed Brown 43f8a67e6dSJed Brown Not Collective 44f8a67e6dSJed Brown 450e6b6b59SJacob Faibussowitsch Notes: 460e6b6b59SJacob Faibussowitsch If the signal was received while executing PetscCheckPointer(), this function longjmps back 470e6b6b59SJacob Faibussowitsch there, otherwise returns with no effect. This function is called automatically by 480e6b6b59SJacob Faibussowitsch PetscSignalHandlerDefault(). 490e6b6b59SJacob Faibussowitsch 50f8a67e6dSJed Brown Level: developer 51f8a67e6dSJed Brown 52db781477SPatrick Sanan .seealso: `PetscPushSignalHandler()` 53f8a67e6dSJed Brown @*/ 54d71ae5a4SJacob Faibussowitsch void PetscSignalSegvCheckPointerOrMpi(void) 55d71ae5a4SJacob Faibussowitsch { 56f8a67e6dSJed Brown if (PetscSegvJumpBuf_set) longjmp(PetscSegvJumpBuf, 1); 57f8a67e6dSJed Brown } 58d076d156SJed Brown 59d96cc911SJed Brown /*@C 60811af0c4SBarry Smith PetscCheckPointer - Returns `PETSC_TRUE` if a pointer points to accessible data 61d96cc911SJed Brown 62d96cc911SJed Brown Not Collective 63d96cc911SJed Brown 64d96cc911SJed Brown Input Parameters: 65d96cc911SJed Brown + ptr - the pointer 66d96cc911SJed Brown - dtype - the type of data the pointer is suppose to point to 67d96cc911SJed Brown 68d96cc911SJed Brown Level: developer 69d96cc911SJed Brown 70811af0c4SBarry Smith Note: 71811af0c4SBarry Smith This is a non-standard PETSc function in that it returns the result as the return code and does not return an error code 72811af0c4SBarry Smith 73db781477SPatrick Sanan .seealso: `PetscCheckPointerSetIntensity()` 74d96cc911SJed Brown @*/ 75d71ae5a4SJacob Faibussowitsch PetscBool PetscCheckPointer(const void *ptr, PetscDataType dtype) 76d71ae5a4SJacob Faibussowitsch { 77d96cc911SJed Brown if (PETSC_RUNNING_ON_VALGRIND) return PETSC_TRUE; 78d96cc911SJed Brown if (!ptr) return PETSC_FALSE; 7928559dc8SJed Brown if (petsc_checkpointer_intensity < 1) return PETSC_TRUE; 80d96cc911SJed Brown 81dfb7d7afSStefano Zampini #if PetscDefined(USE_DEBUG) && !PetscDefined(HAVE_THREADSAFETY) 82a2f94806SJed Brown /* Skip the verbose check if we are inside a hot function. */ 8327104ee2SJacob Faibussowitsch if (petscstack.hotdepth > 0 && petsc_checkpointer_intensity < 2) return PETSC_TRUE; 8427104ee2SJacob Faibussowitsch #endif 85a2f94806SJed Brown 86718fc407SJed Brown PetscSegvJumpBuf_set = PETSC_TRUE; 87d96cc911SJed Brown 88d96cc911SJed Brown if (setjmp(PetscSegvJumpBuf)) { 89d96cc911SJed Brown /* A segv was triggered in the code below hence we return with an error code */ 90718fc407SJed Brown PetscSegvJumpBuf_set = PETSC_FALSE; 91d96cc911SJed Brown return PETSC_FALSE; 92d96cc911SJed Brown } else { 93d96cc911SJed Brown switch (dtype) { 94d96cc911SJed Brown case PETSC_INT: { 95*7a2f837dSToby Isaac PETSC_UNUSED PetscInt x = *(volatile PetscInt *)ptr; 96d96cc911SJed Brown break; 97d96cc911SJed Brown } 98d96cc911SJed Brown #if defined(PETSC_USE_COMPLEX) 99d96cc911SJed Brown case PETSC_SCALAR: { /* C++ is seriously dysfunctional with volatile std::complex. */ 10096d2aba5SSatish Balay #if defined(PETSC_USE_CXXCOMPLEX) 101d96cc911SJed Brown PetscReal xreal = ((volatile PetscReal *)ptr)[0], ximag = ((volatile PetscReal *)ptr)[1]; 102d96cc911SJed Brown PETSC_UNUSED volatile PetscScalar x = xreal + PETSC_i * ximag; 10396d2aba5SSatish Balay #else 10496d2aba5SSatish Balay PETSC_UNUSED PetscScalar x = *(volatile PetscScalar *)ptr; 10596d2aba5SSatish Balay #endif 106d96cc911SJed Brown break; 107d96cc911SJed Brown } 108d96cc911SJed Brown #endif 109d96cc911SJed Brown case PETSC_REAL: { 110d96cc911SJed Brown PETSC_UNUSED PetscReal x = *(volatile PetscReal *)ptr; 111d96cc911SJed Brown break; 112d96cc911SJed Brown } 113d96cc911SJed Brown case PETSC_BOOL: { 114d96cc911SJed Brown PETSC_UNUSED PetscBool x = *(volatile PetscBool *)ptr; 115d96cc911SJed Brown break; 116d96cc911SJed Brown } 117d96cc911SJed Brown case PETSC_ENUM: { 118d96cc911SJed Brown PETSC_UNUSED PetscEnum x = *(volatile PetscEnum *)ptr; 119d96cc911SJed Brown break; 120d96cc911SJed Brown } 121d96cc911SJed Brown case PETSC_CHAR: { 122f4e06bcbSJed Brown PETSC_UNUSED char x = *(volatile char *)ptr; 123d96cc911SJed Brown break; 124d96cc911SJed Brown } 125d96cc911SJed Brown case PETSC_OBJECT: { 126d96cc911SJed Brown PETSC_UNUSED volatile PetscClassId classid = ((PetscObject)ptr)->classid; 127d96cc911SJed Brown break; 128d96cc911SJed Brown } 129d96cc911SJed Brown default:; 130d96cc911SJed Brown } 131d96cc911SJed Brown } 132718fc407SJed Brown PetscSegvJumpBuf_set = PETSC_FALSE; 133d96cc911SJed Brown return PETSC_TRUE; 134d96cc911SJed Brown } 13505035670SJunchao Zhang #endif 136