C语言我用 Linux

使用gdb调试与ulimit命令遇到的坑

2019-01-12  本文已影响407人  以前干嘛去了

所谓的坑,可能来源于理论没充分学习(或者全貌需要过一遍),急于动手;可能来源于实践不到位,验证不充分,自己埋下炸弹

一、问题

今天在挂机测试中,一个重要的通信进程出现segmentfault错误退出,需然挂机时打开了该进程的Debug开关,有打印运行时的日志,但是该问题出现时,只有常规日志,没有留下可用的问题分析日志。通过常规日志,大概能够判断是某个操作引起,但是该操作背后还有操作,无法进行有效定位。

之前在开发过程中,有想过此类问题会发生,当时的想法是通过gdb定位进程异常,使用该方式想到要做三个事情:

1,在编译进程的时候增加-g选项,gcc的-g选项在编译阶段加入,在生成的汇编代码文件中将增加调试信息便于gdb进行调试,在Makefile中可以这样添加:

CFLAGS += -g

2,增加gdb进程到目标测试机的文件系统,这是一个移植过程,我使用的版本是:GNU gdb (GDB) 7.5

3,增加ulimit命令,我的想法是这也是一个移植过程,于是去网上找ulimit的源码包,但是基本无有效的源码包,心中疑惑,当时因一些原因我就放弃了,没有做这一步,想着后面出了问题再来,先做其他事情,没想到你所担心的往往发生概率很大。

二、思路

所谓欠的债总是要还的,今天便是来还债的。怎么来Debug这个Segmentfault大概是这个步骤:

1,复现问题

2,复现问题后需要保留可分析的信息,能想到比较有效的就是core dump文件,然后通过gdb调试定位,要产生core dump文件,需要有ulimit命令的支持,所以需要集成ulimit命令

3,使用gdb调试core dump文件进行定位

三、坑一

现在开始还ulimit的债,思路没变,去找ulimit的源码包,各种找未果,其中又产生两个想法:

1,我要使用的是ulimit -c unlimited命令,我大概知道这个命令是设置系统环境变量的,那我要知道他是设置什么环境变量的大概一个过程,我自己也可以把这个命令写出来,于是朝这个方向找了一番,未果

2,想到busybox里应该有这个命令,去busybox里找源码,未果,但这是转折发生,偶然用busybox ulimit进行搜索,得到下面的文章(感谢):

在busybox里使用ulimit命令

重点是:ulimit是shell的内置命令,泪奔......

话说我在目标机上还敲过ulimit,来试试这个命令有没有,当时脑抽了吗?现在已经无法还原当时记忆。好吧,ulimit已经具备,于是觉得之前东风(复现)了。

使用命令,使系统在进程异常退出时能够产生core dump文件:

ulimit -c unlimited

顺便学习了一下(感谢):linux下产生core文件以及不产生core文件的条件

复现问题过程比较顺利,在/tmp目录下产生了core dump文件(写该文章时使用了一个测试进程的core dump文件来讲这个事情,没使用问题产生的业务进程):

test_core_dump.16281.11.1547275509.core

系统上core dump文件存放的目录及文件的命名方式可以自定义,具体参考(感谢):linux下的core文件路径及文件名设置

四、坑二

至此,觉得马上就可以定位出问题了,光明就在眼前:

图1

什么,??是什么鬼,gdb命令用错啦?

图2

这样也不行,我的编译选项-g没加上吗?检查下,没问题,尝试在开发主机上试一试:

图3

我中饭都不想吃了,继续尝试,终见曙光:

图4

通过对比,可以推断:

1,代码不是问题

2,编译不是问题

3,gdb <应用程序> <core dump文件>可以有效定位:行数,代码

4,难道是gdb的问题?

想到之前调试内核异常时,使用的是编译工具链的gdb而不是编译到目标主机上的gdb,于是尝试将目标主机上的core dump文件通过tftp传到开发主机:

tftp -pl /tmp/test_core_dump.16281.11.1547275509.core 192.168.1.230

192.168.1.230:开发主机ip

然后在开发主机使用编译工具链下的gdb命令:

图5

五、总结

至此,问题得到定位和解决,通过这次问题得到以下的总结:

1,ulimit是shell的内置命令

2,需使用和工具链同级的gdb对coredump文件进行调试,同级的意思是应用程序使用哪个工具编译出来的,那就使用该工具包中的gdb,例如交叉gcc编译的,使用该交叉编译工具链中的gdb,不要使用自己移植到目标板上的gdb

3,gdb调试命令推荐:gdb <应用程序> <core dump文件>

六、遗留问题

遗留待深入学习的问题:

1,ulimit原理(他做了什么,我不用他也可以手动或用程序替代之)

2,编译进目标主机的gdb为啥不能定位行数、符号,是因为版本问题(开发主机7.6,目标主机7.5),还是本来就因该由开发主机工具链中的gdb进行调试,联想到gdbserver,是否目标主机和gdb和开发主机的gdbserver配合也可以解决问题?

3,gdb <应用程序> <core dump文件>和gdb -c <core dump文件>效果为啥不一样(真是无知,我在快写完的时候找了篇文章讲了两个使用gdb调试coredump的方法(感谢):Linux下gdb调试生成core文件并调试core文件),我测试了一遍,使用这种方法同样可以完成问题定位:

图6

至此,才算是有了解决了定位开发板上进程挂掉的工具与方法,完成了当初想法的实施。后面将找时间完成遗留问题的学习与论证。

上一篇 下一篇

猜你喜欢

热点阅读