当前位置:   article > 正文

Linux signal捕获_使用signal获取死机

使用signal获取死机

signal的原理这里不打算多讲,这里主要讲一下应用

man 7 signal,可以看到一些关于signal的介绍:

每个信号都对应着一个action,默认的有:Term, Ign,core,Stop,Cont,  文档上明确的写着是以进程为修改单位的,所有的线程的action都相同:

The signal disposition is a per-process attribute: in a multithreaded application, the disposition of a particular signal is the same for all threads.

信号对应的action被执行了才称之为这个signal被delivered,signal已经发出了,但是没有执行action,称之为signal被pending了,每个线程都可以单独设置mask,来block一些信号,当有对应的signal到来时,这些信号就被pending了,直到再次设置mask在unblock这些signal, pending的signal才会被执行。

signal和默认的action直接的对应关系为:

core就是产生core dump(需要kernel打开coredump选项支持,ulimit -c unlimited不限制core文件大小,core文件的路径可读写),因此可以看出并不是所有的死机都会产生core文件,测试coredump是否生效可以使用下面命令:

kill  -s 11   pid

linux有时会出现应用莫名奇妙的死机,死机毫无规律可循,这时就可以考虑捕获信号,如果了解过kernel的原理就会知道死机都是由信号引起的。

捕获信号的本质就是改变action,action其实就是一个函数指针,改变这个函数指针以指向自定义的函数,sigaction(2) or signal(2)都可以进行捕获,但是signal(2)缺乏移植性。

注意这些signal_handler()是在用户空间执行的,内核采用了Trampoline机制,感兴趣的可以查阅相关资料了解一下。

下面给出一个捕获的例子: 

  1. #if DEBUG_SEGV_HANDLER
  2.           struct sigaction sa;
  3.           memset(&sa, 0, sizeof(sa));
  4.           sa.sa_sigaction = handle_sigsegv;
  5.           sa.sa_flags = SA_SIGINFO;
  6.           sigaction(SIGSEGV, &sa, NULL);
  7.           sigaction(SIGILL, &sa, NULL);
  8.           sigaction(SIGFPE, &sa, NULL);
  9.           sigaction(SIGBUS, &sa, NULL);
  10. #endif
  11.   #if DEBUG_SEGV_HANDLER
  12.   static
  13.   void handle_sigsegv(int sig, siginfo_t *info, void *ucontext)
  14.   {
  15.       long ip;
  16.       ucontext_t *uc;
  17.   
  18.       uc = ucontext;
  19.       ip = uc->uc_mcontext.gregs[REG_EIP];
  20.       fdprintf(2, "signal:%d address:0x%lx ip:0x%lx\n",
  21.               sig,
  22.               /* this is void*, but using %p would print "(null)"
  23.                * even for ptrs which are not exactly 0, but, say, 0x123:
  24.                */
  25.               (long)info->si_addr,
  26.               ip);
  27.       {
  28.           /* glibc extension */
  29.           void *array[50];
  30.           int size;
  31.           size = backtrace(array, 50);
  32.           backtrace_symbols_fd(array, size, 2);
  33.       }
  34.       for (;;) sleep(9999);
  35.   }
  36.   #endif

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/从前慢现在也慢/article/detail/785320
推荐阅读
相关标签
  

闽ICP备14008679号