欢迎光临散文网 会员登陆 & 注册

Linux幽灵般的coredump之如何定位出错位置

2023-08-08 23:25 作者:这个橙子好辣  | 我要投稿

视觉slam,最近修改了原工程里的数据更新部分,由主线程改到子线程中,改完后自认为逻辑没有问题,每次访问共享数据也上了数据互斥锁。

但是却出现了一个偶发性bug,有时候运行几次都不会出现,有时候轨迹跑到一半就会出现coredump,每次引起coredump的原因也不尽相同如,ibus error, Segmentation fault (core dumped), corrupted double-linked list Aborted (core dumped) 伴随的就是程序的立刻中断,而不带一丝的错误位置信息。

只能网上搜索,给出的方法是查看coredump文件。具体步骤如下

1.查看当前系统是否已开启core文件记录

    为0测代表没有开启,需要输入 ulimit -c unlimited,表示core文件大小无限制。

2.我们需要设置core文件生成的位置

3.加上可调式参数gcc main.c -o main -g,对于cmake文件需要设置Debug模式或者release但是O0优化(默认的优化)

4.再次执行文件,直到出现coredump,此时进入core文件生成的目录,下面应该就有了core文件生成。执行gdb ./main core_main.xxx.xxxxxxxx,查看core文件,此时应该能看到具体出错位置了,如果没有的话输入bt或者where即可。

当然我的问题没这么简单,当我输入bt后,依旧没有出错的具体位置或者函数,只有下面一些信息:

Backtrace stopped: previous frame identical to this frame (corrupt stack?) 或者 double free之类的

位置信息也只有 0xb.......... in ?? () 的地址信息,而看不见具体的出错位置或者函数。

后来知道了需要将编译优化参数去掉 O0、O1、O2、O3、Os中,只能用原始的O0,不进行优化。但是当我设置O0后,原来的slam帧数就从100fps+变成了0.1-1fps左右。这样的速度太慢,很难触发coredump,跑了十几分钟,没有耐性了,并且可能改为O0不优化后,根本触发不了错误了。我的错误大概率是由线程间的不安全访问导致的。但我访问公共资源时都加了互斥锁,相比原来的代码,我也找不出逻辑错误。

总之,这样使用O3优化,虽然能触发了coredump,但是看不了具体错误位置。O0能从core文件看到具体错误位置,但又触发不了coredump。直接自相矛盾了。

最后只能妥协,采用wait/notify机制,线程等待和唤醒,唤醒后再更新数据,这样虽然更新数据还是在子线程运行,试了多次后,没有触发过coredump。缺点就是只有插入了新关键帧,才会更新数据,pan-golin的可视化交互才可以被相应,只有此时才能拖动鼠标进行交互,所以会卡卡的。而slam结束后,由于没有新关键帧了,一直处于wait状态,所以pangolin也无法相应鼠标交互。相比coredump,这点交互牺牲确实无伤大雅了。

所以,我还是没能找到之前coredump的原因(无法理解的偶发性错误),但还是把查看core文件的方法写下来吧,免得以后又忘了,再查资料又要花很多时间。

Linux幽灵般的coredump之如何定位出错位置的评论 (共 条)

分享到微博请遵守国家法律