print the segmentation fault reason

This question already has an answer here:

  • How to automatically generate a stacktrace when my gcc C++ program crashes 28 answers

  • If you want to know the cause you can register a signal handler, something like:

    void handler(int signum, siginfo_t *info, void *context)
    {
      struct sigaction action = {
        .sa_handler = SIG_DFL,
        .sa_sigaction = NULL,
        .sa_mask = 0,
        .sa_flags = 0,
        .sa_restorer = NULL
      };
    
      fprintf(stderr, "Fault address: %pn", info->si_addr);
      switch (info->si_code) {
      case SEGV_MAPERR:
        fprintf(stderr, "Address not mapped.n");
        break;
    
      case SEGV_ACCERR:
        fprintf(stderr, "Access to this address is not allowed.n");
        break;
    
      default:
        fprintf(stderr, "Unknown reason.n");
        break;
      }
    
      /* unregister and let the default action occur */
      sigaction(SIGSEGV, &action, NULL);
    }
    

    And then somewhere you need to register it:

      struct sigaction action = {
        .sa_handler = NULL,
        .sa_sigaction = handler,
        .sa_mask = 0,
        .sa_flags = SA_SIGINFO,
        .sa_restorer = NULL
      };
    
    
      if (sigaction(SIGSEGV, &action, NULL) < 0) {
        perror("sigaction");
      }
    

    Basically you register a signal that fires when SIGSEGV is delivered, and you get some additional info, to quote the man page:

       The following values can be placed in si_code for a SIGSEGV signal:
    
           SEGV_MAPERR    address not mapped to object
    
           SEGV_ACCERR    invalid permissions for mapped object
    

    These map to the two basic reasons for getting a seg fault -- either the page you accessed wasn't mapped at all, or you weren't allowed to perform whatever operation you attempted to that page.

    Here after the signal handler fires it unregisters itself and replaces the default action. This causes the operation that failed to be performed again so it can be caught by the normal route. This is the normal behavior of a page fault (the precursor to getting a seg fault) so that things like demand paging work.


    As already answered here: How to generate a stacktrace when my gcc C++ app crashes

    You can (in the case of GCC with Linux/BSD at least) do this fairly easy:

    Example code:

    #include <stdio.h>
    #include <execinfo.h>
    #include <signal.h>
    #include <stdlib.h>
    
    
    void handler(int sig) {
      void *array[10];
      size_t size;
    
      // get void*'s for all entries on the stack
      size = backtrace(array, 10);
    
      // print out all the frames to stderr
      fprintf(stderr, "Error: signal %d:n", sig);
      backtrace_symbols_fd(array, size, 2);
      exit(1);
    }
    
    int main(int argc, char **argv) {
      signal(SIGSEGV, handler);   // install our handler
    
      char * ptr = NULL;
      *ptr = "hello"; /* this will cause a segmentation fault */
    }
    

    Example output:

    # gcc -g -rdynamic -o test test.c
    # ./test
    Error: signal 11:
    0   test                                0x000000010e99dcfa handler + 42
    1   libsystem_c.dylib                   0x00007fff95c1194a _sigtramp + 26
    2   ???                                 0x0000000000000000 0x0 + 0
    3   libdyld.dylib                       0x00007fff8fa177e1 start + 0
    4   ???                                 0x0000000000000001 0x0 + 1
    
    链接地址: http://www.djcxy.com/p/86040.html

    上一篇: C ++显示堆栈跟踪异常

    下一篇: 打印分段故障原因