Actual source code: checkptr.c
1: #include <petsc/private/petscimpl.h>
3: static PetscInt petsc_checkpointer_intensity = 1;
5: /*@
6: PetscCheckPointerSetIntensity - An intense pointer check registers a signal handler and attempts to dereference to
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
20: .seealso: `PetscCheckPointer()`, `PetscFunctionBeginHot()`
21: @*/
22: PetscErrorCode PetscCheckPointerSetIntensity(PetscInt intensity)
23: {
24: PetscFunctionBegin;
25: PetscCheck((intensity >= 0) && (intensity <= 2), PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Intensity %" PetscInt_FMT " not in [0,2]", intensity);
26: petsc_checkpointer_intensity = intensity;
27: PetscFunctionReturn(PETSC_SUCCESS);
28: }
30: /* ---------------------------------------------------------------------------------------*/
32: #if PetscDefined(HAVE_SETJMP_H)
33: #include <setjmp.h>
34: static jmp_buf PetscSegvJumpBuf;
35: static PetscBool PetscSegvJumpBuf_set;
37: /*@C
38: PetscSignalSegvCheckPointerOrMpi - To be called from a signal handler for SIGSEGV.
40: Not Collective
42: Notes:
43: If the signal was received while executing PetscCheckPointer(), this function longjmps back
44: there, otherwise returns with no effect. This function is called automatically by
45: PetscSignalHandlerDefault().
47: Level: developer
49: .seealso: `PetscPushSignalHandler()`
50: @*/
51: void PetscSignalSegvCheckPointerOrMpi(void)
52: {
53: if (PetscSegvJumpBuf_set) longjmp(PetscSegvJumpBuf, 1);
54: }
56: /*@C
57: PetscCheckPointer - Returns `PETSC_TRUE` if a pointer points to accessible data
59: Not Collective
61: Input Parameters:
62: + ptr - the pointer
63: - dtype - the type of data the pointer is suppose to point to
65: Level: developer
67: Note:
68: 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: .seealso: `PetscCheckPointerSetIntensity()`
71: @*/
72: PetscBool PetscCheckPointer(const void *ptr, PetscDataType dtype)
73: {
74: if (PETSC_RUNNING_ON_VALGRIND) return PETSC_TRUE;
75: if (!ptr) return PETSC_FALSE;
76: if (petsc_checkpointer_intensity < 1) return PETSC_TRUE;
78: #if PetscDefined(USE_DEBUG) && !PetscDefined(HAVE_THREADSAFETY)
79: /* Skip the verbose check if we are inside a hot function. */
80: if (petscstack.hotdepth > 0 && petsc_checkpointer_intensity < 2) return PETSC_TRUE;
81: #endif
83: PetscSegvJumpBuf_set = PETSC_TRUE;
85: if (setjmp(PetscSegvJumpBuf)) {
86: /* A segv was triggered in the code below hence we return with an error code */
87: PetscSegvJumpBuf_set = PETSC_FALSE;
88: return PETSC_FALSE;
89: } else {
90: switch (dtype) {
91: case PETSC_INT: {
92: PETSC_UNUSED PetscInt x = (PetscInt) * (volatile PetscInt *)ptr;
93: break;
94: }
95: #if defined(PETSC_USE_COMPLEX)
96: case PETSC_SCALAR: { /* C++ is seriously dysfunctional with volatile std::complex. */
97: #if defined(PETSC_USE_CXXCOMPLEX)
98: PetscReal xreal = ((volatile PetscReal *)ptr)[0], ximag = ((volatile PetscReal *)ptr)[1];
99: PETSC_UNUSED volatile PetscScalar x = xreal + PETSC_i * ximag;
100: #else
101: PETSC_UNUSED PetscScalar x = *(volatile PetscScalar *)ptr;
102: #endif
103: break;
104: }
105: #endif
106: case PETSC_REAL: {
107: PETSC_UNUSED PetscReal x = *(volatile PetscReal *)ptr;
108: break;
109: }
110: case PETSC_BOOL: {
111: PETSC_UNUSED PetscBool x = *(volatile PetscBool *)ptr;
112: break;
113: }
114: case PETSC_ENUM: {
115: PETSC_UNUSED PetscEnum x = *(volatile PetscEnum *)ptr;
116: break;
117: }
118: case PETSC_CHAR: {
119: PETSC_UNUSED char x = *(volatile char *)ptr;
120: break;
121: }
122: case PETSC_OBJECT: {
123: PETSC_UNUSED volatile PetscClassId classid = ((PetscObject)ptr)->classid;
124: break;
125: }
126: default:;
127: }
128: }
129: PetscSegvJumpBuf_set = PETSC_FALSE;
130: return PETSC_TRUE;
131: }
132: #endif