Actual source code: checkptr.c
petsc-3.6.4 2016-04-12
1: #include <petsc/private/petscimpl.h>
2: #include <petscvalgrind.h>
4: static PetscInt petsc_checkpointer_intensity = 1;
8: /*@
10: confirm whether the address is valid. An intensity of 0 never uses signal handlers, 1 uses them when not in a "hot"
11: function, and intensity of 2 always uses a signal handler.
13: Not Collective
15: Input Arguments:
16: . intensity - how much to check pointers for validity
18: Level: advanced
21: @*/
23: {
26: switch (intensity) {
27: case 0:
28: case 1:
29: case 2:
30: petsc_checkpointer_intensity = intensity;
31: break;
32: default: SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Intensity %D not in 0,1,2",intensity);
33: }
34: return(0);
35: }
37: /* ---------------------------------------------------------------------------------------*/
38: #if defined(PETSC_HAVE_SETJMP_H) && defined(PETSC_HAVE_SIGINFO_T)
39: #include <signal.h>
40: #include <setjmp.h>
41: PETSC_INTERN jmp_buf PetscSegvJumpBuf;
42: PETSC_INTERN void PetscSegv_sigaction(int, siginfo_t*, void *);
44: /*@C
47: Not Collective
49: Input Parameters:
50: + ptr - the pointer
51: - dtype - the type of data the pointer is suppose to point to
53: Level: developer
55: @*/
57: {
58: struct sigaction sa,oldsa;
60: if (PETSC_RUNNING_ON_VALGRIND) return PETSC_TRUE;
61: if (!ptr) return PETSC_FALSE;
62: if (petsc_checkpointer_intensity < 1) return PETSC_TRUE;
64: /* Skip the verbose check if we are inside a hot function. */
65: if (petscstack && petscstack->hotdepth > 0 && petsc_checkpointer_intensity < 2) return PETSC_TRUE;
67: sigemptyset(&sa.sa_mask);
68: sa.sa_sigaction = PetscSegv_sigaction;
69: sa.sa_flags = SA_SIGINFO;
70: sigaction(SIGSEGV, &sa, &oldsa);
72: if (setjmp(PetscSegvJumpBuf)) {
73: /* A segv was triggered in the code below hence we return with an error code */
74: sigaction(SIGSEGV, &oldsa, NULL);/* reset old signal hanlder */
75: return PETSC_FALSE;
76: } else {
77: switch (dtype) {
78: case PETSC_INT:{
79: PETSC_UNUSED PetscInt x = (PetscInt)*(volatile PetscInt*)ptr;
80: break;
81: }
82: #if defined(PETSC_USE_COMPLEX)
83: case PETSC_SCALAR:{ /* C++ is seriously dysfunctional with volatile std::complex. */
84: PetscReal xreal = ((volatile PetscReal*)ptr)[0],ximag = ((volatile PetscReal*)ptr)[1];
85: PETSC_UNUSED volatile PetscScalar x = xreal + PETSC_i*ximag;
86: break;
87: }
88: #endif
89: case PETSC_REAL:{
90: PETSC_UNUSED PetscReal x = *(volatile PetscReal*)ptr;
91: break;
92: }
93: case PETSC_BOOL:{
94: PETSC_UNUSED PetscBool x = *(volatile PetscBool*)ptr;
95: break;
96: }
97: case PETSC_ENUM:{
98: PETSC_UNUSED PetscEnum x = *(volatile PetscEnum*)ptr;
99: break;
100: }
101: case PETSC_CHAR:{
102: PETSC_UNUSED char x = *(volatile char*)ptr;
103: break;
104: }
105: case PETSC_OBJECT:{
106: PETSC_UNUSED volatile PetscClassId classid = ((PetscObject)ptr)->classid;
107: break;
108: }
109: default:;
110: }
111: }
112: sigaction(SIGSEGV, &oldsa, NULL); /* reset old signal hanlder */
113: return PETSC_TRUE;
114: }
115: #else
117: {
118: if (!ptr) return PETSC_FALSE;
119: return PETSC_TRUE;
120: }
121: #endif