1af0996ceSBarry Smith #include <petsc/private/petscimpl.h> 205035670SJunchao Zhang 328559dc8SJed Brown static PetscInt petsc_checkpointer_intensity = 1; 428559dc8SJed Brown 528559dc8SJed Brown /*@ 628559dc8SJed Brown PetscCheckPointerSetIntensity - An intense pointer check registers a signal handler and attempts to dereference to 728559dc8SJed Brown confirm whether the address is valid. An intensity of 0 never uses signal handlers, 1 uses them when not in a "hot" 828559dc8SJed Brown function, and intensity of 2 always uses a signal handler. 928559dc8SJed Brown 1028559dc8SJed Brown Not Collective 1128559dc8SJed Brown 124165533cSJose E. Roman Input Parameter: 1328559dc8SJed Brown . intensity - how much to check pointers for validity 1428559dc8SJed Brown 15811af0c4SBarry Smith Options Database Key: 165789d1f5SJed Brown . -check_pointer_intensity - intensity (0, 1, or 2) 17c2f74817SBarry Smith 1828559dc8SJed Brown Level: advanced 1928559dc8SJed Brown 20db781477SPatrick Sanan .seealso: `PetscCheckPointer()`, `PetscFunctionBeginHot()` 2128559dc8SJed Brown @*/ 22d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscCheckPointerSetIntensity(PetscInt intensity) 23d71ae5a4SJacob Faibussowitsch { 2428559dc8SJed Brown PetscFunctionBegin; 250e6b6b59SJacob Faibussowitsch PetscCheck((intensity >= 0) && (intensity <= 2), PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Intensity %" PetscInt_FMT " not in [0,2]", intensity); 260e6b6b59SJacob Faibussowitsch petsc_checkpointer_intensity = intensity; 2728559dc8SJed Brown PetscFunctionReturn(0); 2828559dc8SJed Brown } 2928559dc8SJed Brown 30d96cc911SJed Brown /* ---------------------------------------------------------------------------------------*/ 31718fc407SJed Brown 320e6b6b59SJacob Faibussowitsch #if PetscDefined(HAVE_SETJMP_H) 33d96cc911SJed Brown #include <setjmp.h> 34f8a67e6dSJed Brown static jmp_buf PetscSegvJumpBuf; 35f8a67e6dSJed Brown static PetscBool PetscSegvJumpBuf_set; 36f8a67e6dSJed Brown 37f8a67e6dSJed Brown /*@C 380e6b6b59SJacob Faibussowitsch PetscSignalSegvCheckPointerOrMpi - To be called from a signal handler for SIGSEGV. 39f8a67e6dSJed Brown 40f8a67e6dSJed Brown Not Collective 41f8a67e6dSJed Brown 420e6b6b59SJacob Faibussowitsch Notes: 430e6b6b59SJacob Faibussowitsch If the signal was received while executing PetscCheckPointer(), this function longjmps back 440e6b6b59SJacob Faibussowitsch there, otherwise returns with no effect. This function is called automatically by 450e6b6b59SJacob Faibussowitsch PetscSignalHandlerDefault(). 460e6b6b59SJacob Faibussowitsch 47f8a67e6dSJed Brown Level: developer 48f8a67e6dSJed Brown 49db781477SPatrick Sanan .seealso: `PetscPushSignalHandler()` 50f8a67e6dSJed Brown @*/ 51d71ae5a4SJacob Faibussowitsch void PetscSignalSegvCheckPointerOrMpi(void) 52d71ae5a4SJacob Faibussowitsch { 53f8a67e6dSJed Brown if (PetscSegvJumpBuf_set) longjmp(PetscSegvJumpBuf, 1); 54f8a67e6dSJed Brown } 55d076d156SJed Brown 56d96cc911SJed Brown /*@C 57811af0c4SBarry Smith PetscCheckPointer - Returns `PETSC_TRUE` if a pointer points to accessible data 58d96cc911SJed Brown 59d96cc911SJed Brown Not Collective 60d96cc911SJed Brown 61d96cc911SJed Brown Input Parameters: 62d96cc911SJed Brown + ptr - the pointer 63d96cc911SJed Brown - dtype - the type of data the pointer is suppose to point to 64d96cc911SJed Brown 65d96cc911SJed Brown Level: developer 66d96cc911SJed Brown 67811af0c4SBarry Smith Note: 68811af0c4SBarry 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 69811af0c4SBarry Smith 70db781477SPatrick Sanan .seealso: `PetscCheckPointerSetIntensity()` 71d96cc911SJed Brown @*/ 72d71ae5a4SJacob Faibussowitsch PetscBool PetscCheckPointer(const void *ptr, PetscDataType dtype) 73d71ae5a4SJacob Faibussowitsch { 74d96cc911SJed Brown if (PETSC_RUNNING_ON_VALGRIND) return PETSC_TRUE; 75d96cc911SJed Brown if (!ptr) return PETSC_FALSE; 7628559dc8SJed Brown if (petsc_checkpointer_intensity < 1) return PETSC_TRUE; 77d96cc911SJed Brown 78*dfb7d7afSStefano Zampini #if PetscDefined(USE_DEBUG) && !PetscDefined(HAVE_THREADSAFETY) 79a2f94806SJed Brown /* Skip the verbose check if we are inside a hot function. */ 8027104ee2SJacob Faibussowitsch if (petscstack.hotdepth > 0 && petsc_checkpointer_intensity < 2) return PETSC_TRUE; 8127104ee2SJacob Faibussowitsch #endif 82a2f94806SJed Brown 83718fc407SJed Brown PetscSegvJumpBuf_set = PETSC_TRUE; 84d96cc911SJed Brown 85d96cc911SJed Brown if (setjmp(PetscSegvJumpBuf)) { 86d96cc911SJed Brown /* A segv was triggered in the code below hence we return with an error code */ 87718fc407SJed Brown PetscSegvJumpBuf_set = PETSC_FALSE; 88d96cc911SJed Brown return PETSC_FALSE; 89d96cc911SJed Brown } else { 90d96cc911SJed Brown switch (dtype) { 91d96cc911SJed Brown case PETSC_INT: { 92d96cc911SJed Brown PETSC_UNUSED PetscInt x = (PetscInt) * (volatile PetscInt *)ptr; 93d96cc911SJed Brown break; 94d96cc911SJed Brown } 95d96cc911SJed Brown #if defined(PETSC_USE_COMPLEX) 96d96cc911SJed Brown case PETSC_SCALAR: { /* C++ is seriously dysfunctional with volatile std::complex. */ 9796d2aba5SSatish Balay #if defined(PETSC_USE_CXXCOMPLEX) 98d96cc911SJed Brown PetscReal xreal = ((volatile PetscReal *)ptr)[0], ximag = ((volatile PetscReal *)ptr)[1]; 99d96cc911SJed Brown PETSC_UNUSED volatile PetscScalar x = xreal + PETSC_i * ximag; 10096d2aba5SSatish Balay #else 10196d2aba5SSatish Balay PETSC_UNUSED PetscScalar x = *(volatile PetscScalar *)ptr; 10296d2aba5SSatish Balay #endif 103d96cc911SJed Brown break; 104d96cc911SJed Brown } 105d96cc911SJed Brown #endif 106d96cc911SJed Brown case PETSC_REAL: { 107d96cc911SJed Brown PETSC_UNUSED PetscReal x = *(volatile PetscReal *)ptr; 108d96cc911SJed Brown break; 109d96cc911SJed Brown } 110d96cc911SJed Brown case PETSC_BOOL: { 111d96cc911SJed Brown PETSC_UNUSED PetscBool x = *(volatile PetscBool *)ptr; 112d96cc911SJed Brown break; 113d96cc911SJed Brown } 114d96cc911SJed Brown case PETSC_ENUM: { 115d96cc911SJed Brown PETSC_UNUSED PetscEnum x = *(volatile PetscEnum *)ptr; 116d96cc911SJed Brown break; 117d96cc911SJed Brown } 118d96cc911SJed Brown case PETSC_CHAR: { 119f4e06bcbSJed Brown PETSC_UNUSED char x = *(volatile char *)ptr; 120d96cc911SJed Brown break; 121d96cc911SJed Brown } 122d96cc911SJed Brown case PETSC_OBJECT: { 123d96cc911SJed Brown PETSC_UNUSED volatile PetscClassId classid = ((PetscObject)ptr)->classid; 124d96cc911SJed Brown break; 125d96cc911SJed Brown } 126d96cc911SJed Brown default:; 127d96cc911SJed Brown } 128d96cc911SJed Brown } 129718fc407SJed Brown PetscSegvJumpBuf_set = PETSC_FALSE; 130d96cc911SJed Brown return PETSC_TRUE; 131d96cc911SJed Brown } 13205035670SJunchao Zhang #endif 133