Actual source code: checkptr.c
petsc-3.5.4 2015-05-23
1: #include <petsc-private/petscimpl.h>
3: static PetscInt petsc_checkpointer_intensity = 1;
7: /*@
9: confirm whether the address is valid. An intensity of 0 never uses signal handlers, 1 uses them when not in a "hot"
10: function, and intensity of 2 always uses a signal handler.
12: Not Collective
14: Input Arguments:
15: . intensity - how much to check pointers for validity
17: Level: advanced
20: @*/
22: {
25: switch (intensity) {
26: case 0:
27: case 1:
28: case 2:
29: petsc_checkpointer_intensity = intensity;
30: break;
31: default: SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Intensity %D not in 0,1,2",intensity);
32: }
33: return(0);
34: }
36: /* ---------------------------------------------------------------------------------------*/
37: #if defined(PETSC_HAVE_SETJMP_H) && defined(PETSC_HAVE_SIGINFO_T)
38: #include <signal.h>
39: #include <setjmp.h>
40: PETSC_INTERN jmp_buf PetscSegvJumpBuf;
41: PETSC_INTERN void PetscSegv_sigaction(int, siginfo_t*, void *);
43: /*@C
46: Not Collective
48: Input Parameters:
49: + ptr - the pointer
50: - dtype - the type of data the pointer is suppose to point to
52: Level: developer
54: @*/
56: {
57: struct sigaction sa,oldsa;
58: PetscStack *stackp;
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: stackp = (PetscStack*)PetscThreadLocalGetValue(petscstack);
66: if (stackp && stackp->hotdepth > 0 && petsc_checkpointer_intensity < 2) return PETSC_TRUE;
68: sigemptyset(&sa.sa_mask);
69: sa.sa_sigaction = PetscSegv_sigaction;
70: sa.sa_flags = SA_SIGINFO;
71: sigaction(SIGSEGV, &sa, &oldsa);
73: if (setjmp(PetscSegvJumpBuf)) {
74: /* A segv was triggered in the code below hence we return with an error code */
75: sigaction(SIGSEGV, &oldsa, NULL);/* reset old signal hanlder */
76: return PETSC_FALSE;
77: } else {
78: switch (dtype) {
79: case PETSC_INT:{
80: PETSC_UNUSED PetscInt x = (PetscInt)*(volatile PetscInt*)ptr;
81: break;
82: }
83: #if defined(PETSC_USE_COMPLEX)
84: case PETSC_SCALAR:{ /* C++ is seriously dysfunctional with volatile std::complex. */
85: PetscReal xreal = ((volatile PetscReal*)ptr)[0],ximag = ((volatile PetscReal*)ptr)[1];
86: PETSC_UNUSED volatile PetscScalar x = xreal + PETSC_i*ximag;
87: break;
88: }
89: #endif
90: case PETSC_REAL:{
91: PETSC_UNUSED PetscReal x = *(volatile PetscReal*)ptr;
92: break;
93: }
94: case PETSC_BOOL:{
95: PETSC_UNUSED PetscBool x = *(volatile PetscBool*)ptr;
96: break;
97: }
98: case PETSC_ENUM:{
99: PETSC_UNUSED PetscEnum x = *(volatile PetscEnum*)ptr;
100: break;
101: }
102: case PETSC_CHAR:{
103: PETSC_UNUSED char x = *(volatile char*)ptr;
104: break;
105: }
106: case PETSC_OBJECT:{
107: PETSC_UNUSED volatile PetscClassId classid = ((PetscObject)ptr)->classid;
108: break;
109: }
110: default:;
111: }
112: }
113: sigaction(SIGSEGV, &oldsa, NULL); /* reset old signal hanlder */
114: return PETSC_TRUE;
115: }
116: #else
118: {
119: if (!ptr) return PETSC_FALSE;
120: return PETSC_TRUE;
121: }
122: #endif