coredump来调试崩溃进程

来源:互联网 发布:spring切面编程 注解 编辑:程序博客网 时间:2024/05/20 14:24

在平常开发中,经常碰到进程异常崩溃退出的情况,这时候最便捷的方法就是生成core文件,然后通过gdb在查看程序崩溃时的调用栈,一般很快就能定位出问题。 linux系统中程序异常崩溃时默认是不会自动生成core文件的,这时候我们一般需要使用以下命令将core文件生成开关打开,然后再在终端手动拉起进程,当进程再次崩溃时就会生成core文件。

# 将coresize从默认的0改成无限制ulimit -c unlimited# 因为我们的rootfs是只读的,所以需要将core文件生成路径从默认的当前路径改为/var/coreecho /var/core >/proc/sys/kernel/core_pattern

但是ulimit命令是有作用范围的,事实上ulimit限制的是当前shell进程以及其派生的子进程,所以通过ulimit修改coresize只是针对在当前shell下启动的子进程,而不能影响其他shell下启动的进程。而pc进程是一个精灵进程,由它启动的进程都是属于其他shell了,所以通过pc进程启动的子进程是无法生成core文件的。


那么怎么才能让指定的进程崩溃时生成core文件呢?

带着这个疑问,我查看了busybox中的ash的源码,发现ash中实现的ulimit命令最终是通过调用setrlimit函数来实现对coresize参数的设置。增加一个enableCoreDump函数用于开启coredump的功能,对于想要生成core文件的程序,只需要在启动时调用enableCoreDump(1),即可在程序崩溃时生成core文件。

int enableCoreDump(int iFlag){    int iRes = RLIMIT_CORE;    struct rlimit stRlim;    /* 允许生成core文件 */    stRlim.rlim_cur = stRlim.rlim_max = iFlag ? RLIM_INFINITY : 0;    if (0 != setrlimit(iRes, &stRlim))    {        printf("Error: setrlimit failed, %s\n", strerror(errno));        return TBS_FAILED;    }    else    {        /* 设置core文件生成的路径 */        system("echo /var/core > /proc/sys/kernel/core_pattern");        printf("Set coredump file size to %lu, path = /var/core\n", stRlim.rlim_cur);        return TBS_SUCCESS;    }    return TBS_FAILED;}

生成core文件之后,怎么使用gdb对其调试呢?

首先需要在板子上通过tftp命令将/var/core上传到编译服务器上,然后使用交叉编译器的gdb打开带调试信息的程序,再指定core文件为上传上来的core文件路径,使用bt命令即可看到程序崩溃时的调用栈,剩下的就可以自由发挥了。

  • 当logic崩溃时:
  • 板上操作命令:
cd /vartftp -pr core 192.168.1.100
  • 编译服务器操作命令
cd /root/coredump# 使用gdb打开logic/opt/toolchains/rsdk-1.3.6-4181-EB-2.6.30-0.9.30/bin/rsdk-linux-gdb build/apps/logic/logic# 设置库文件的加载路径(gdb) set solib-absolute-prefix build/romfs/rootfs# 设置core文件路径(gdb) core-file build/romfs/core# 查看调用栈(gdb) bt

4 小结

注意:

  1. 当你尝试了上面的方法之后还是无法生成core文件的话,可能是内核的CONFIG_ELF_CORE编译开关没打开,请将之打开。
  2. 当你生成的core文件用gdb打开时却看不到调用栈信息时,可能是你的rootfs中的库文件被sstrip过了,请修改根目录的Makefile将sstrip目标去掉
0 0
原创粉丝点击