Actual source code: checkptr.c
petsc-3.12.5 2020-03-29
1: #include <petsc/private/petscimpl.h>
2: #include <petscvalgrind.h>
4: static PetscInt petsc_checkpointer_intensity = 1;
6: /*@
8: confirm whether the address is valid. An intensity of 0 never uses signal handlers, 1 uses them when not in a "hot"
9: function, and intensity of 2 always uses a signal handler.
11: Not Collective
13: Input Arguments:
14: . intensity - how much to check pointers for validity
16: Options Database:
17: . -check_pointer_intensity - intensity (0, 1, or 2)
19: Level: advanced
22: @*/
24: {
27: switch (intensity) {
28: case 0:
29: case 1:
30: case 2:
31: petsc_checkpointer_intensity = intensity;
32: break;
33: default: SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Intensity %D not in 0,1,2",intensity);
34: }
35: return(0);
36: }
38: /* ---------------------------------------------------------------------------------------*/
40: #if defined(PETSC_HAVE_SETJMP_H)
41: #include <setjmp.h>
42: static jmp_buf PetscSegvJumpBuf;
43: static PetscBool PetscSegvJumpBuf_set;
45: /*@C
46: PetscSignalSegvCheckPointer - To be called from a signal handler for SIGSEGV. If the signal was received while
48: called automatically by PetscSignalHandlerDefault().
50: Not Collective
52: Level: developer
54: .seealso: PetscPushSignalHandler()
55: @*/
56: void PetscSignalSegvCheckPointer() {
57: if (PetscSegvJumpBuf_set) longjmp(PetscSegvJumpBuf,1);
58: }
60: /*@C
63: Not Collective
65: Input Parameters:
66: + ptr - the pointer
67: - dtype - the type of data the pointer is suppose to point to
69: Level: developer
72: @*/
74: {
76: if (PETSC_RUNNING_ON_VALGRIND) return PETSC_TRUE;
77: if (!ptr) return PETSC_FALSE;
78: if (petsc_checkpointer_intensity < 1) return PETSC_TRUE;
80: /* Skip the verbose check if we are inside a hot function. */
81: if (petscstack && petscstack->hotdepth > 0 && petsc_checkpointer_intensity < 2) return PETSC_TRUE;
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: #else
133: void PetscSignalSegvCheckPointer() {
134: return;
135: }
138: {
139: if (!ptr) return PETSC_FALSE;
140: return PETSC_TRUE;
141: }
142: #endif