Linux下进程崩溃时定位源代码位置

来源:互联网 发布:上海威纳 数据 编辑:程序博客网 时间:2024/06/18 08:25


原文链接:http://blog.chinaunix.net/uid-26611383-id-3453351.html


前几天领导安排一个小项目,大意是解决这样一个问题:

在Linux系统下,进程可能由于各种原因崩溃,此时我们要找到出问题的源代码在某一个文件的具体行号,这样调试起来就会方便,高效很多,可能是公司项目要用到,想想挺有意思的,加上自己本身是个Linux狂热者,最终花了两三天解决了这个问题,当然我的领导我们称之为专家指点了我很多,废话少说,下面是解决问题的思路和步骤以及自己的一些想法  

解决该问题的大体思路是这样的:在Linux下,进程崩溃时内核(也就是我们所谓的操作系统)会向进程发送信号,比如我们程序运行崩溃时经常会看到segmentation falt这样的信息,这是进程非法操作内存,内核会向进程发送SIGENV信号,那么我们凭什么可以找到进程崩溃的原因对应的源代码的位置呢,我们知道,每个进程都有自己的堆栈,当某个进程崩溃时,堆栈里保存了一些关键信息,通过这些信息我们可以定位到出错的源代码位置,那么我们怎么来获得进程崩溃时堆栈的信息呢,请记住,Linux是当今世界上最为强大的操作系统(不管你信不信,反正我是信了,^_^),在Linux系统里有个backtrace这些个函数可以获得当前堆栈信息,好了,到这里问题已经解决了一半,backtrace信息中的有一个地址包含了出错代码在文件中的偏移量

需要注意的是编译时一定要加上 -g和-rdynamic参数

如果我们使用的是静态库或者出错的代码不在动态库中,那么我们可以直接用命令"addr2line -e 可执行文件名 偏移地址"打印出出错的代码行,下面是具体步骤
在测试程序的29行非法操作了内存

我们把addr2line命令放在程序里面做了,在代码中也可以看得到,下面这幅图片是程序的输出,可以看到
打印出源代码出错的行数为29

如果crash在一个动态库so里面,比较麻烦一点,此时addr2line不能直接给出代码行。因为我们都知道,so里面的地址在可执行文件装载的时候,是可以被 reallocate的。所以,如果只有一个so的地址,要找出对应代码行的话,送给 addr2line的参数地址就是一个偏移地址,这里的偏移地址就是backtrace中的地址减去动态库加载的时候的基地址,这个基地址我们可以通过/proc/pid/maps这个文件找到,pid是当前进程号,下面是具体步骤,跟之前的步骤类似,只不过我们为了测试,将func函数编译进了一个动态库里面
这里我们只给出测试文件,具体怎么实现动态库,这个很容易,不在此多提,下面是测试程序的一部分

我们在/proc/pid/maps文件中找出出错动态库加载的基地址,用backtrace中的地址与基地址相减得到偏移地址就可以了,下面是程序输出
可以看到,我们用hello.c做的动态库,定位到代码出错在hello.c的第五行



下面是定位动态库错误的源代码:
 test.zip  



0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 塑料和金属断了怎么办 孕妇吃了沙拉酱怎么办 孕妇淀粉吃多了怎么办 怀孕初期吃了杏怎么办 如果睡觉吃梨了怎么办 怀孕6个月有点贫血怎么办 怀孕八个多月有点贫血怎么办 生完小孩身体虚怎么办 孩子咳嗽厉害怎么办吃什么药 新生儿三天不拉大便怎么办 胃吃的变大了怎么办 小孩长高长的慢怎么办 小孩长高长得慢怎么办 小孩吃东西不吸收营养怎么办 婴儿长得太快怎么办 2个月婴儿长太快怎么办 孩子脚长得太快怎么办 4个月宝宝缺钙怎么办 2个月宝宝不长肉怎么办 小孩子长得不高怎么办 宝宝误吃蜂蜜了怎么办 有人拿着吃完的东西退货怎么办 婴儿个子长的慢怎么办 儿童长得太快怎么办 宝宝个子长太快怎么办 孩子九个月奶水不够怎么办 小孩起热痱子痒怎么办 媳妇生完小孩奶水出不来怎么办 生完孩子下奶疼怎么办 生完小孩没奶水怎么办 孩子半个月奶水越来越少怎么办 半个月后奶水越来越少怎么办 坐月子半个月奶水越来越少怎么办 孩子七个月奶水越来越少怎么办 生完孩子奶水越来越少怎么办 生完孩子回奶了怎么办 产妇3天没奶水怎么办 产后7天了奶水少怎么办 刚生完小孩没有奶水怎么办 突然就没奶水了怎么办 生完小孩没有奶水怎么办