xref: /petsc/src/sys/error/checkptr.c (revision d96cc911b64c80119868f58f2ea4711e3a6b3d32)
1*d96cc911SJed Brown #include <petsc-private/petscimpl.h>
2*d96cc911SJed Brown 
3*d96cc911SJed Brown /* ---------------------------------------------------------------------------------------*/
4*d96cc911SJed Brown #if defined(PETSC_HAVE_SETJMP_H) && defined(PETSC_HAVE_SIGINFO_T)
5*d96cc911SJed Brown #include <signal.h>
6*d96cc911SJed Brown #include <setjmp.h>
7*d96cc911SJed Brown PETSC_EXTERN jmp_buf PetscSegvJumpBuf;
8*d96cc911SJed Brown PETSC_EXTERN void PetscSegv_sigaction(int, siginfo_t*, void *);
9*d96cc911SJed Brown /*@C
10*d96cc911SJed Brown      PetscCheckPointer - Returns PETSC_TRUE if a pointer points to accessible data
11*d96cc911SJed Brown 
12*d96cc911SJed Brown    Not Collective
13*d96cc911SJed Brown 
14*d96cc911SJed Brown    Input Parameters:
15*d96cc911SJed Brown +     ptr - the pointer
16*d96cc911SJed Brown -     dtype - the type of data the pointer is suppose to point to
17*d96cc911SJed Brown 
18*d96cc911SJed Brown    Level: developer
19*d96cc911SJed Brown 
20*d96cc911SJed Brown @*/
21*d96cc911SJed Brown PetscBool PetscCheckPointer(const void *ptr,PetscDataType dtype)
22*d96cc911SJed Brown {
23*d96cc911SJed Brown   struct sigaction sa,oldsa;
24*d96cc911SJed Brown 
25*d96cc911SJed Brown   if (PETSC_RUNNING_ON_VALGRIND) return PETSC_TRUE;
26*d96cc911SJed Brown   if (!ptr) return PETSC_FALSE;
27*d96cc911SJed Brown 
28*d96cc911SJed Brown   sigemptyset(&sa.sa_mask);
29*d96cc911SJed Brown   sa.sa_sigaction = PetscSegv_sigaction;
30*d96cc911SJed Brown   sa.sa_flags   = SA_SIGINFO;
31*d96cc911SJed Brown   sigaction(SIGSEGV, &sa, &oldsa);
32*d96cc911SJed Brown 
33*d96cc911SJed Brown   if (setjmp(PetscSegvJumpBuf)) {
34*d96cc911SJed Brown     /* A segv was triggered in the code below hence we return with an error code */
35*d96cc911SJed Brown     sigaction(SIGSEGV, &oldsa, NULL);/* reset old signal hanlder */
36*d96cc911SJed Brown     return PETSC_FALSE;
37*d96cc911SJed Brown   } else {
38*d96cc911SJed Brown     switch (dtype) {
39*d96cc911SJed Brown     case PETSC_INT:{
40*d96cc911SJed Brown       PETSC_UNUSED PetscInt x = (PetscInt)*(volatile PetscInt*)ptr;
41*d96cc911SJed Brown       break;
42*d96cc911SJed Brown     }
43*d96cc911SJed Brown #if defined(PETSC_USE_COMPLEX)
44*d96cc911SJed Brown     case PETSC_SCALAR:{         /* C++ is seriously dysfunctional with volatile std::complex. */
45*d96cc911SJed Brown       PetscReal xreal = ((volatile PetscReal*)ptr)[0],ximag = ((volatile PetscReal*)ptr)[1];
46*d96cc911SJed Brown       PETSC_UNUSED volatile PetscScalar x = xreal + PETSC_i*ximag;
47*d96cc911SJed Brown       break;
48*d96cc911SJed Brown     }
49*d96cc911SJed Brown #endif
50*d96cc911SJed Brown     case PETSC_REAL:{
51*d96cc911SJed Brown       PETSC_UNUSED PetscReal x = *(volatile PetscReal*)ptr;
52*d96cc911SJed Brown       break;
53*d96cc911SJed Brown     }
54*d96cc911SJed Brown     case PETSC_BOOL:{
55*d96cc911SJed Brown       PETSC_UNUSED PetscBool x = *(volatile PetscBool*)ptr;
56*d96cc911SJed Brown       break;
57*d96cc911SJed Brown     }
58*d96cc911SJed Brown     case PETSC_ENUM:{
59*d96cc911SJed Brown       PETSC_UNUSED PetscEnum x = *(volatile PetscEnum*)ptr;
60*d96cc911SJed Brown       break;
61*d96cc911SJed Brown     }
62*d96cc911SJed Brown     case PETSC_CHAR:{
63*d96cc911SJed Brown       PETSC_UNUSED char *x = *(char*volatile*)ptr;
64*d96cc911SJed Brown       break;
65*d96cc911SJed Brown     }
66*d96cc911SJed Brown     case PETSC_OBJECT:{
67*d96cc911SJed Brown       PETSC_UNUSED volatile PetscClassId classid = ((PetscObject)ptr)->classid;
68*d96cc911SJed Brown       break;
69*d96cc911SJed Brown     }
70*d96cc911SJed Brown     default:;
71*d96cc911SJed Brown     }
72*d96cc911SJed Brown   }
73*d96cc911SJed Brown   sigaction(SIGSEGV, &oldsa, NULL); /* reset old signal hanlder */
74*d96cc911SJed Brown   return PETSC_TRUE;
75*d96cc911SJed Brown }
76*d96cc911SJed Brown #else
77*d96cc911SJed Brown PetscBool PetscCheckPointer(const void *ptr,PETSC_UNUSED PetscDataType dtype)
78*d96cc911SJed Brown {
79*d96cc911SJed Brown   if (!ptr) return PETSC_FALSE;
80*d96cc911SJed Brown   return PETSC_TRUE;
81*d96cc911SJed Brown }
82*d96cc911SJed Brown #endif
83