1: #include <petsc/private/petscimpl.h> 3: static PetscInt petsc_checkpointer_intensity = 1; 5: /*@ 7: confirm whether the address is valid. An intensity of 0 never uses signal handlers, 1 uses them when not in a "hot" 8: function, and intensity of 2 always uses a signal handler. 10: Not Collective 12: Input Parameter: 13: . intensity - how much to check pointers for validity 15: Options Database Key: 16: . -check_pointer_intensity - intensity (0, 1, or 2) 18: Level: advanced 21: @*/ 23: { 25: petsc_checkpointer_intensity = intensity; 26: return 0; 27: } 29: /* ---------------------------------------------------------------------------------------*/ 31: #if PetscDefined(HAVE_SETJMP_H) 32: #include <setjmp.h> 33: static jmp_buf PetscSegvJumpBuf; 34: static PetscBool PetscSegvJumpBuf_set; 36: /*@C 37: PetscSignalSegvCheckPointerOrMpi - To be called from a signal handler for SIGSEGV. 39: Not Collective 41: Notes: 43: there, otherwise returns with no effect. This function is called automatically by 44: PetscSignalHandlerDefault(). 46: Level: developer 48: .seealso: `PetscPushSignalHandler()` 49: @*/ 50: void PetscSignalSegvCheckPointerOrMpi(void) 51: { 52: if (PetscSegvJumpBuf_set) longjmp(PetscSegvJumpBuf, 1); 53: } 55: /*@C 58: Not Collective 60: Input Parameters: 61: + ptr - the pointer 62: - dtype - the type of data the pointer is suppose to point to 64: Level: developer 66: Note: 67: This is a non-standard PETSc function in that it returns the result as the return code and does not return an error code 70: @*/ 72: { 73: if (PETSC_RUNNING_ON_VALGRIND) return PETSC_TRUE; 74: if (!ptr) return PETSC_FALSE; 75: if (petsc_checkpointer_intensity < 1) return PETSC_TRUE; 77: #if PetscDefined(USE_DEBUG) 78: /* Skip the verbose check if we are inside a hot function. */ 79: if (petscstack.hotdepth > 0 && petsc_checkpointer_intensity < 2) return PETSC_TRUE; 80: #endif 82: PetscSegvJumpBuf_set = PETSC_TRUE; 84: if (setjmp(PetscSegvJumpBuf)) { 85: /* A segv was triggered in the code below hence we return with an error code */ 86: PetscSegvJumpBuf_set = PETSC_FALSE; 87: return PETSC_FALSE; 88: } else { 89: switch (dtype) { 90: case PETSC_INT: { 91: PETSC_UNUSED PetscInt x = (PetscInt) * (volatile PetscInt *)ptr; 92: break; 93: } 94: #if defined(PETSC_USE_COMPLEX) 95: case PETSC_SCALAR: { /* C++ is seriously dysfunctional with volatile std::complex. */ 96: #if defined(PETSC_USE_CXXCOMPLEX) 97: PetscReal xreal = ((volatile PetscReal *)ptr)[0], ximag = ((volatile PetscReal *)ptr)[1]; 98: PETSC_UNUSED volatile PetscScalar x = xreal + PETSC_i * ximag; 99: #else 100: PETSC_UNUSED PetscScalar x = *(volatile PetscScalar *)ptr; 101: #endif 102: break; 103: } 104: #endif 105: case PETSC_REAL: { 106: PETSC_UNUSED PetscReal x = *(volatile PetscReal *)ptr; 107: break; 108: } 109: case PETSC_BOOL: { 110: PETSC_UNUSED PetscBool x = *(volatile PetscBool *)ptr; 111: break; 112: } 113: case PETSC_ENUM: { 114: PETSC_UNUSED PetscEnum x = *(volatile PetscEnum *)ptr; 115: break; 116: } 117: case PETSC_CHAR: { 118: PETSC_UNUSED char x = *(volatile char *)ptr; 119: break; 120: } 121: case PETSC_OBJECT: { 122: PETSC_UNUSED volatile PetscClassId classid = ((PetscObject)ptr)->classid; 123: break; 124: } 125: default:; 126: } 127: } 128: PetscSegvJumpBuf_set = PETSC_FALSE; 129: return PETSC_TRUE; 130: } 131: #endif