[实践OK]php的coredump怎么看?段错误等造成死机问题的分析, apache的coredump文件及其它像swoole这样的出现崩溃查找问题在哪行的原理。

jackxiang 2014-11-14 16:58 | |
设置一下吐核,按Swoole官方的Wiki教程,设置一下吐核,From: https://wiki.swoole.com/wiki/page/10.html :
一、开启CoreDump:
ulimit -c   #查看
#ulimit -c unlimited
使用gdb来查看core dump信息。core文件一般在当前目录,如果操作系统做了处理,将core dump文件放置到其他目录,请替换为相应的路径


二、设置内核参数将吐的核放到指定目录下指定格式存放:
kernel.core_pattern = /data/core_files/core-%e-%p-%t
通过ulimit -c命令查看当前coredump文件的限制
ulimit -c
打开core dump
ulimit -c unlimited

三、调试:
#gdb /usr/bin/httpd core.123
gdb /usr/local/nginx/sbin/nginx core.456

四、在GDB里使用bt命令调试等:
在gdb下输入bt查看调用栈信息

(gdb)bt
Program terminated with signal 11, Segmentation fault.
#0  0x00007f1cdbe205e0 in swServer_onTimer (reactor=<value optimized out>, event=...)  
    at /usr/local/php/swoole-swoole-1.5.9b/src/network/Server.c:92
92                              serv->onTimer(serv, timer_node->interval);
Missing separate debuginfos, use: debuginfo-install php-cli-5.3.3-22.el6.x86_64
在gdb中使用f指令查看代码段

(gdb)f 1
(gdb)f 0

五、像这种退出不是段错误,没有Coredump的:
==> /data/logs/nginx/error.log <==

2017/08/16 11:56:52 [notice] 41234#0: signal 17 (SIGCHLD) received
2017/08/16 11:56:52 [notice] 41234#0: worker process 41237 exited with code 2
2017/08/16 11:56:52 [alert] 41234#0: worker process 41237 exited with fatal code 2 and cannot be respawned
2017/08/16 11:56:52 [notice] 41234#0: signal 29 (SIGIO) received
2017/08/16 11:56:52 [emerg] 41236#0: load ip map file error: /usr/local/nginx/conf/ip.map

2017/08/16 11:56:52 [notice] 41234#0: signal 17 (SIGCHLD) received
2017/08/16 11:56:52 [notice] 41234#0: worker process 41236 exited with code 2
2017/08/16 11:56:52 [alert] 41234#0: worker process 41236 exited with fatal code 2 and cannot be respawned
原因是:一个文件不存在,故意移动了下:
mv /usr/local/nginx/conf/ip.map /usr/local/nginx/conf/ip.map.bak
===================================================================================
使用gdb来查看core dump信息。core文件一般在当前目录,如果操作系统做了处理,将core dump文件放置到其他目录,请替换为相应的路径
gdb php core
gdb php /tmp/core.4596
在gdb下输入bt查看调用栈信息
(gdb)bt
Program terminated with signal 11, Segmentation fault.
#0  0x00007f1cdbe205e0 in swServer_onTimer (reactor=<value optimized out>, event=...)  
    at /usr/local/php/swoole-swoole-1.5.9b/src/network/Server.c:92
92                              serv->onTimer(serv, timer_node->interval);
Missing separate debuginfos, use: debuginfo-install php-cli-5.3.3-22.el6.x86_64
在gdb中使用f指令查看代码段
(gdb)f 1
(gdb)f 0


对gdb下f命令的实践,能显示哪一行出了问题:
(gdb) bt
#0  0x00007ffff7b01980 in __read_nocancel () at ../sysdeps/unix/syscall-template.S:81
#1  0x00007ffff7a924a0 in _IO_new_file_underflow (fp=0x7ffff7dd5640 <_IO_2_1_stdin_>) at fileops.c:612
#2  0x00007ffff7a9342e in __GI__IO_default_uflow (fp=0x7ffff7dd5640 <_IO_2_1_stdin_>) at genops.c:436
#3  0x00007ffff7a753b3 in _IO_vfscanf_internal (s=<optimized out>, format=<optimized out>, argptr=argptr@entry=0x7fffffffe368, errp=errp@entry=0x0) at vfscanf.c:600
#4  0x00007ffff7a83a19 in __isoc99_scanf (format=<optimized out>) at isoc99_scanf.c:37
#5  0x00000000004006d4 in creat () at nodedemo.c:24
#6  0x000000000040075b in main () at nodedemo.c:46
(gdb) f 5
#5  0x00000000004006d4 in creat () at nodedemo.c:24
24          }
(gdb) f 2
#2  0x00007ffff7a9342e in __GI__IO_default_uflow (fp=0x7ffff7dd5640 <_IO_2_1_stdin_>) at genops.c:436
436       int ch = _IO_UNDERFLOW (fp);


如果为0,需要修改/etc/security/limits.conf,进行limit设置。
开启core-dump后,一旦程序发生异常,会将进程导出到文件。对于调查程序问题有很大的帮助
来自:http://wiki.swoole.com/wiki/page/10.html http://wiki.swoole.com/wiki/page/11.html
—————————————————————————————————————————————

记录一下。
1. ulimit -S -c unlimited
2. 在apache主配置文件中增加一行:CoreDumpDirectory /var/apache_coredump #目录随意
3. chown修改/var/apache_coredump的权限为apache子进程可写

注意:不要开启太久,core文件太多。占用太多磁盘空间
调试
gdb /usr/bin/httpd core.123
apache的coredump

来自:http://5iwww.blog.51cto.com/856039/761077

在实际工作当中,通过会出现某个应用造成死机问题。如何解决该问题。
方法一:最简单办法,看打印,通过反复调试,看是哪条语句造成造成了死机。这种方法效率低,而且有时不准确,比如一个系统中有多个进程,但A进程跑的B断点是,出现段错误,系统发出11号信号,造成B,C等进程接到11号信号反初始化而推出。实际当中可能不一定是A进程原因,因为此时B,C等进程也在并发执行,甚至A,B,c 三个进程都在访问某一共享资源(如共享内存等)。

方法二:让内核通过OOPS打出堆栈信息,PC指针和链接指针,进行pc指针分析或者堆栈回溯
                内核默认是不支持OOPS打印,需要内核配置开关打开。通常内为了了优化性能,调试开关都不会打开,需要我们根据实际需要打开某些调试开关。
OOPS打出来可以看到:pc指针,LR链接库指针,CPU各个寄存器信息,堆栈信息。

简单情况:
从OOPS知道PC指针,如果该进程是没有调用库,可以直接将该进程反汇编 objdump -D -S  xxx进程名>124.txt
再从123.txt找到该PC指针位置对于的C代码行,即可定位。
对于情况还可以使用addr2line  PC指针  -e  xxxx进程名 -f定位到某个C代码行
复杂情况:
如果一个进程包含很多库,甚至要调用底层驱动,定位起来就更加麻烦。
首先看pc指针地址确认是在死在内核态和用户态。还是KO模块,不同处理器架构不一样,可以看内核地址映射表  system.map
比如在MIPS系统中
用户程序地址空间:    0x00000000~0x7FFFFFFF;
内核地址空间:           System.map文件中的_stext ~_etext,大概是0x80000000~0x80300000;
可加载模块地址空间:0xC0000000~0xC0800000
如果在用户空间:
首先通过cat /proc./pid/maps
查看 pc=xxxx 指针所在库,比如pc指针所在库为xxx.so ,而xx.so的地址访问为aaa~bbb
那么pc指针再 xxx.so库中偏移地址为xxx-aaa=ccc
对xxx.so  进行反汇编,objdump -D -S >345.txt
查找到ccc行就能找到对应行。
注意该进程以及改进程所在的库编译是必需加-g ,也不能strip,否则反汇编出来没有C代码的映射行
如果是在内核空间,可以通过堆栈回溯法进程回溯。该方法需要熟悉汇编,其次需要耐心,这里不详述。
堆栈回溯法出来OOPS
  通过反汇编,然后堆栈回溯,找到出问题的函数,该方法需要熟悉汇编,其次需要耐心,这里不详述。

方法三:coredump分析法
对于死机问题,某些情况下OOPS打印出来的信息不足以分析。coreDump给了个详细的方法。
首先在内核当中打开coredup  开关,死机后就会产生一个core问题,事后可以通过 gdb调试方法来分析定位死机的位置。

摘自:http://blog.csdn.net/fengliang191/article/details/36894103

作者:jackxiang@向东博客 专注WEB应用 构架之美 --- 构架之美,在于尽态极妍 | 应用之美,在于药到病除
地址:https://jackxiang.com/post/7627/
版权所有。转载时必须以链接形式注明作者和原始出处及本声明!


最后编辑: jackxiang 编辑于2017-8-16 12:01
评论列表
发表评论

昵称

网址

电邮

打开HTML 打开UBB 打开表情 隐藏 记住我 [登入] [注册]