Data hosted with ♥ by Pastebin.com - Download Raw - See Original
  1. // Compile with gcc -Wall -pedantic-errors -std=gnu99 foo.c
  2. //
  3. #include <stdio.h>
  4. #include <setjmp.h>
  5. #include <signal.h>
  6.  
  7. // Pointer to functions like void f(void)
  8. //
  9. typedef void (*Func)(void);
  10.  
  11. // Store where to go when SIGSEGV caught
  12. //
  13. static sigjmp_buf jumpTarget;
  14.  
  15. // Called when SIGSEGV caught
  16. //
  17. static void sigHandler(int sig) {
  18.   siglongjmp(jumpTarget, sig);
  19. }
  20.  
  21. // Execute the supplied function, return 0 for success and 1 for SIGSEGV
  22. //
  23. int catchCrash(Func f) {
  24.   struct sigaction oldAction;
  25.   struct sigaction newAction;
  26.  
  27.   // Remember the old SIGSEGV handler and set a new handler
  28.   newAction.sa_flags = 0;
  29.   newAction.sa_handler = sigHandler;
  30.   sigemptyset(&newAction.sa_mask);
  31.   sigaction(SIGSEGV, &newAction, &oldAction);
  32.  
  33.   // Crashing code ends up inside this block
  34.   if ( __extension__ sigsetjmp(jumpTarget, 1) != 0 ) {
  35.     return 1; // crash detected
  36.   }
  37.  
  38.   // Execute the function: maybe crash, maybe not
  39.   f();
  40.  
  41.   // Restore the old handler
  42.   sigaction(SIGSEGV, &oldAction, NULL);
  43.   return 0;
  44. }
  45.  
  46. // Innocuous function
  47. //
  48. void sayHello(void) {
  49.   printf("Hello World\n");
  50. }
  51.  
  52. // Attempt to write to address zero
  53. //
  54. void writeZero(void) {
  55.   int *p = NULL;
  56.   *p = 42;
  57. }
  58.  
  59. // Attempt to read from address zero
  60. //
  61. void readZero(void) {
  62.   int *p = NULL;
  63.   printf("Read: %d\n", *p);
  64. }
  65.  
  66. // Attempt to execute code at address zero
  67. //
  68. void jmpZero(void) {
  69.   Func f = NULL;
  70.   f();
  71. }
  72.  
  73. int main(void) {
  74.   printf("catchCrash(sayHello) returned %d\n", catchCrash(sayHello));
  75.   printf("catchCrash(writeZero) returned %d\n", catchCrash(writeZero));
  76.   printf("catchCrash(readZero) returned %d\n", catchCrash(readZero));
  77.   printf("catchCrash(jmpZero) returned %d\n", catchCrash(jmpZero));
  78.   return 0;
  79. }