什么条件触发转存
这个转存发生在应用程序收到致命的signal,在处理这个signal的时候会执行应用程序的转存,并在之后退出执行。有一点必须注意,如果用户给这些致命signal安装了自定义的handler,转存是不会发生的。OK,那么这里总结出两点:
1,致命signal会出发转存发生,这些signal包括如下内容。
点击(此处)折叠或打开
-
398 #define SIG_KERNEL_COREDUMP_MASK(\
-
399 rt_sigmask(SIGQUIT)|rt_sigmask(SIGILL)|\
-
400 rt_sigmask(SIGTRAP)|rt_sigmask(SIGABRT)|\
-
401 rt_sigmask(SIGFPE)|rt_sigmask(SIGSEGV)|\
-
402 rt_sigmask(SIGBUS)|rt_sigmask(SIGSYS)|\
-
403 rt_sigmask(SIGXCPU)|rt_sigmask(SIGXFSZ)|\
- 404 SIGEMT_MASK
点击(此处)折叠或打开
-
2264if(ka->sa.sa_handler!=SIG_DFL){
-
2265/*Run the handler.*/
-
2266 ksig->ka=*ka;
-
2267
-
2268if(ka->sa.sa_flags&SA_ONESHOT)
-
2269 ka->sa.sa_handler=SIG_DFL;
-
2270
-
2271 break;/*will return non-zero"signr"value*/
- 2272}
触发coredump执行的分支
点击(此处)折叠或打开
-
2335if(sig_kernel_coredump(signr)){
-
2336if(print_fatal_signals)
-
2337 print_fatal_signal(ksig->info.si_signo);
-
2338 proc_coredump_connector(current);
-
2339/*
-
2340*Ifit was abletodump core,this kills all
-
2341*other threadsinthe groupandsynchronizes with
-
2342*their demise.Ifwe lost the race with another
-
2343*thread getting here,itsetgroup_exit_code
-
2344*firstandour do_group_exitcallbelow will use
-
2345*that valueandignore the one we pass it.
-
2346*/
-
2347 do_coredump(&ksig->info);
- 2348}
-
将致命signal打印到控制台的Tips
如果你开启如下proc目录下的option,将开启打印致命signal到控制台的功能。
/proc/sys/kernel/print-fatal-signals
coredump主要步骤
其实将这个应用程序都写入到磁盘的过程肯定是非常负责的。这里我不会扣没一个细节,有一些原理性的细节可能推到后面的部分再详细学习和分析。但是,这里我们需要了解如下几个关于coredump的关键处理流程。
1, coredump之间,首先要检查线程组中所有线程是不是已经都进入到了休眠状态。我们要coredump必须保证我们在拷贝这个进程的内存空间的时候进程中的某些线程还在运行并改写内存空间。
2, 对于直接将进程内存转存到文件的情况,没有什么特别之处,就是打开一个文件,并开始写入。
3,对于制定了用户空间脚本,进行一些压缩操作的情况,这里会启动一个用户态进程,并在kernel和用户态进程之间建立一个管道,
kernel=========读出===========用户态进程(压缩)-----------写入-------->文件
对于第一步处理,kernel想进程组中所有的线程发送kill signal信号,然后等待所有进程都不处在运行状态。
对于第二步,处理相对简单,只是之后如果有兴趣还可深入研究一下coredump文件的格式到底是什么样子的。
第三步,相对比较复杂,比较巧妙的地方就是在kernel中建立了一条管道,kernel处理signal部分将coredump写入管道,而新建的进程中管道的另外一端被设置到了标准输入上面。
对于压缩进程转存的方法
我们可以兴建一个shell执行文件
#!/bin/sh
exec gzip - > /root/$1.core.$2.gz
然后在/proc/sys/kernel/core_pattern 中写入
|/usr/sbin/core_helper %e %p