1 #include <petsc-private/petscimpl.h> 2 3 static PetscInt petsc_checkpointer_intensity = 1; 4 5 #undef __FUNCT__ 6 #define __FUNCT__ "PetscCheckPointerSetIntensity" 7 /*@ 8 PetscCheckPointerSetIntensity - An intense pointer check registers a signal handler and attempts to dereference to 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. 11 12 Not Collective 13 14 Input Arguments: 15 . intensity - how much to check pointers for validity 16 17 Level: advanced 18 19 .seealso: PetscCheckPointer(), PetscFunctionBeginHot 20 @*/ 21 PetscErrorCode PetscCheckPointerSetIntensity(PetscInt intensity) 22 { 23 24 PetscFunctionBegin; 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 PetscFunctionReturn(0); 34 } 35 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 *); 42 43 /*@C 44 PetscCheckPointer - Returns PETSC_TRUE if a pointer points to accessible data 45 46 Not Collective 47 48 Input Parameters: 49 + ptr - the pointer 50 - dtype - the type of data the pointer is suppose to point to 51 52 Level: developer 53 54 @*/ 55 PetscBool PetscCheckPointer(const void *ptr,PetscDataType dtype) 56 { 57 struct sigaction sa,oldsa; 58 PetscStack *stackp; 59 60 if (PETSC_RUNNING_ON_VALGRIND) return PETSC_TRUE; 61 if (!ptr) return PETSC_FALSE; 62 if (petsc_checkpointer_intensity < 1) return PETSC_TRUE; 63 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; 67 68 sigemptyset(&sa.sa_mask); 69 sa.sa_sigaction = PetscSegv_sigaction; 70 sa.sa_flags = SA_SIGINFO; 71 sigaction(SIGSEGV, &sa, &oldsa); 72 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 = *(char*volatile*)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 117 PetscBool PetscCheckPointer(const void *ptr,PETSC_UNUSED PetscDataType dtype) 118 { 119 if (!ptr) return PETSC_FALSE; 120 return PETSC_TRUE; 121 } 122 #endif 123