src/grid/fpe.h

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    
    // Catching floating-point-exceptions (and other signals)
    
    @include <signal.h>
    @include <unistd.h>
    
    static int gdb()
    {
      if (last_point.level >= 0) {
        debug (last_point);
        fputc ('\n', stderr);
        fflush (stderr);
      }
      char command[80];
      sprintf (command, "exec xterm -e 'gdb -p %d' & xterm -e 'gnuplot plot -'",
    	   getpid());
      return system (command);
    }
    
    static void caught_abort (int sig)
    {
      fprintf (stderr, "Caught signal %d (Aborted)\n", sig);
      gdb();
    }
    
    static void caught_fpe (int sig)
    {
      fprintf (stderr, "Caught signal %d (Floating Point Exception)\n", sig);
      gdb();
      exit (1);
    }
    
    static void caught_segfault (int sig)
    {
      fprintf (stderr, "Caught signal %d (Segmentation Fault)\n", sig);
      gdb();
      exit (2);
    }
    
    void catch_fpe (void)
    {
      struct sigaction act;
      act.sa_handler = caught_fpe;
      sigemptyset (&act.sa_mask);
      act.sa_flags = 0;
      last_point.level = -1;
      sigaction (8, &act, NULL); // FPE
      act.sa_handler = caught_segfault;
      sigaction (11, &act, NULL); // Segfault
      act.sa_handler = caught_abort;
      act.sa_flags = SA_RESETHAND;
      sigaction (6, &act, NULL); // Abort
    }