当前位置: 代码迷 >> 综合 >> (Linux) C++ segment default错误 GDB调试
  详细解决方案

(Linux) C++ segment default错误 GDB调试

热度:81   发布时间:2023-11-27 02:32:57.0

问题现象

程序以前都运行的好好的,但是最近更新了一个新的安装包安装到现场之后,出现频繁的不定时重启现象,有时候几分钟就重启,有时候几个小时出现重启。
界面上显示 segment default段错误,double free or corruption (fasttop): 0x00007fffd06c9b50,看报错的信息可能是有的地方多次释放同一块内存。查看代码,没有之类的问题,通过查看程序的运行日志文件也没有发现明显的报错。

问题排查

因为通过查看报错信息并不能直接查看问题出现的具体原因或者具体是哪行代码出现了问题,而且项目的程序代码非常庞大,直接通过gdb调试运行程序不可能。但是在Linux下segmentdefault错误可以生成core文件,可以通过产生的core文件排查。core文件的产生具体可以参考其他文章。

1. core文件

(1)ulimit -a #查看系统core文件的大小限制,core file size为0表示没有打开core dump设置。需要先打开;

(2)ulimit -c 0 #不产生core文件
ulimit -c 100 #设置core文件最大为100k
ulimit -c unlimited #不限制core文件的大小

(3)执行2的语句之后记得执行 ulimit -a 查看是否设置成功,设置成功的话在程序出现段错误的时候就可以产生core文件了。

(4)还可以设置产生的core文件文件名,具体的操作参考其他文章。

(5)注意:要想生成有效的core文件,运行的程序需要是debug版本的!!!

2. core文件调试

1 运行可执行程序,出现segment default错误的时候会生成core文件;

2 gdb 可执行程序路径 生成的对应的core文件路径;

gdb example core.11632

example是生成的可执行程序(debug版本);
core.11632是程序报错是生成的对应的core文件;
两个文件不在同一目录下的时候记得加上文件的路径;

3 使用 bt 命令查看coredump时的堆栈
这个命令可以查看到出现coredump时的代码,但是在有可能还不能明确报错的原因,尤其在多线程的情况下;
我的显示问题是出现在一个Getmemory()从内存读取数据时出现了错误,通过检查代码,这个函数的代码本身没有问题。

4 多线程下查看所有线程 info threads

5 多线程情况下查看所有线程的运行情况 thread apply all bt
通过这个命令,我看到了有多个线程在执行Getmemory()、Setmemory()这两个函数,而这两个函数的主要通能就是设置将数据保存到一个内存map中,或是从中读取数据。

问题解决

通过最后查看 thread apply all bt 看到多个线程同时在操作内存map,在我的代码中Getmemory()、Setmemory()这两个函数是在同一个类中,类的设计模式是单例模式,有一个全局变量为map,这两个函数主要就是对这个全局变量map操作。多个线程在执行这两个函数,说明有多个线程在同时操作全局map,但是我没有加锁!!!就导致出现segment default 、double free的报错。

总结

1 Linux下大型程序报错找不到问题原因时,可以通过debug版本的程序生成core文件排查错误,方便排查。

2 无论使用什么设计模式,在多线程的情况下,为了确保安全,一定要记得加锁!!!

3 多线程调试要记得查看一下所有线程的运行情况,有助于排错。

4 double free or corruption的原因不一定就是因为多次释放指针,具体还是需要看调试信息。

--------如有侵权,联系删除!

  相关解决方案