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