打印分段故障原因

这个问题在这里已经有了答案:

  • 当我的gcc C ++程序崩溃了28个答案时如何自动生成堆栈跟踪

  • 如果您想知道原因,您可以注册一个信号处理程序,如下所示:

    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);
    }
    

    然后在某个地方你需要注册它:

      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");
      }
    

    基本上你注册了一个SIGSEGV被传送时触发的信号,并且你会得到一些额外的信息,引用手册页:

       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
    

    这些映射到导致seg故障的两个基本原因 - 您访问的页面根本没有映射,或者您不允许执行您尝试访问该页面的任何操作。

    在信号处理程序触发后,它将取消注册,并替换默认操作。 这会导致无法再次执行的操作,因此可能会被正常路由捕获。 这是页面错误(获取seg错误的先兆)的正常行为,以便像请求分页一样工作。


    正如已经在这里回答的:如何在我的gcc C ++应用程序崩溃时生成堆栈跟踪

    你可以(至少在Linux / BSD的GCC中)这样做很容易:

    示例代码:

    #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 */
    }
    

    示例输出:

    # 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/86039.html

    上一篇: print the segmentation fault reason

    下一篇: dup2() not executing