Actual source code: checkptr.c
petsc-3.8.3 2017-12-09
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: Level: advanced
19: @*/
21: {
24: switch (intensity) {
25: case 0:
26: case 1:
27: case 2:
28: petsc_checkpointer_intensity = intensity;
29: break;
30: default: SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Intensity %D not in 0,1,2",intensity);
31: }
32: return(0);
33: }
35: /* ---------------------------------------------------------------------------------------*/
36: #if defined(PETSC_HAVE_SETJMP_H) && defined(PETSC_HAVE_SIGINFO_T)
37: #include <signal.h>
38: #include <setjmp.h>
39: PETSC_INTERN jmp_buf PetscSegvJumpBuf;
40: PETSC_INTERN void PetscSegv_sigaction(int, siginfo_t*, void *);
42: /*@C
45: Not Collective
47: Input Parameters:
48: + ptr - the pointer
49: - dtype - the type of data the pointer is suppose to point to
51: Level: developer
53: @*/
55: {
56: struct sigaction sa,oldsa;
58: if (PETSC_RUNNING_ON_VALGRIND) return PETSC_TRUE;
59: if (!ptr) return PETSC_FALSE;
60: if (petsc_checkpointer_intensity < 1) return PETSC_TRUE;
62: /* Skip the verbose check if we are inside a hot function. */
63: if (petscstack && petscstack->hotdepth > 0 && petsc_checkpointer_intensity < 2) return PETSC_TRUE;
65: sigemptyset(&sa.sa_mask);
66: sa.sa_sigaction = PetscSegv_sigaction;
67: sa.sa_flags = SA_SIGINFO;
68: sigaction(SIGSEGV, &sa, &oldsa);
70: if (setjmp(PetscSegvJumpBuf)) {
71: /* A segv was triggered in the code below hence we return with an error code */
72: sigaction(SIGSEGV, &oldsa, NULL);/* reset old signal hanlder */
73: return PETSC_FALSE;
74: } else {
75: switch (dtype) {
76: case PETSC_INT:{
77: PETSC_UNUSED PetscInt x = (PetscInt)*(volatile PetscInt*)ptr;
78: break;
79: }
80: #if defined(PETSC_USE_COMPLEX)
81: case PETSC_SCALAR:{ /* C++ is seriously dysfunctional with volatile std::complex. */
82: PetscReal xreal = ((volatile PetscReal*)ptr)[0],ximag = ((volatile PetscReal*)ptr)[1];
83: PETSC_UNUSED volatile PetscScalar x = xreal + PETSC_i*ximag;
84: break;
85: }
86: #endif
87: case PETSC_REAL:{
88: PETSC_UNUSED PetscReal x = *(volatile PetscReal*)ptr;
89: break;
90: }
91: case PETSC_BOOL:{
92: PETSC_UNUSED PetscBool x = *(volatile PetscBool*)ptr;
93: break;
94: }
95: case PETSC_ENUM:{
96: PETSC_UNUSED PetscEnum x = *(volatile PetscEnum*)ptr;
97: break;
98: }
99: case PETSC_CHAR:{
100: PETSC_UNUSED char x = *(volatile char*)ptr;
101: break;
102: }
103: case PETSC_OBJECT:{
104: PETSC_UNUSED volatile PetscClassId classid = ((PetscObject)ptr)->classid;
105: break;
106: }
107: default:;
108: }
109: }
110: sigaction(SIGSEGV, &oldsa, NULL); /* reset old signal hanlder */
111: return PETSC_TRUE;
112: }
113: #else
115: {
116: if (!ptr) return PETSC_FALSE;
117: return PETSC_TRUE;
118: }
119: #endif