目录
背景
步骤
1.安装gdb
2.对core_file限制进行设置
3.修改core_file生成位置
4.修改CMakeLists.txt
5.将二进制文件和core一块放进gdb
6.其他注意事项
写项目中,由于保护做得不够,可能发生coredump,即段错误的情况,这时手动定位会比较麻烦,因为一个项目,可能函数不断嵌套,无论是打断点,还是cout指定位置输出,都会消耗不少时间,那么,能不能,找到什么办法,直接知道程序崩在哪一行呢?(不是崩在main里哪一行,而是函数不可往下分的那一行)
sudo apt install gdb
查看core_file限制
$ ulimit -c
$ 0
如上所示,如果你得到的结果是0,就修改一下
ulimit -c unlimited
此时,当程序崩溃时,就能生成core_file文件了
core file生成的地方是在/proc/sys/kernel/core_pattern文件定义的
改动方式如下:
echo "yourPath/core-%e-%p" > /proc/sys/kernel/core_pattern
# 举例
echo "/home/user/code/coredump/core-%e-%p" > /proc/sys/kernel/core_pattern
然而,有时,你的权限会不够
zsh: permission denied: /proc/sys/kernel/core_pattern
可以采用如下方式提高重定向符权限
sudo sh -c "echo "yourPath/core-%e-%p" > /proc/sys/kernel/core_pattern"
还需要说明的一点是,core-%e-%p只是一个自定义的命名方式,%字符的含义如下
%%: 相当于%
%p: 相当于
%u: 相当于
%g: 相当于
%s: 相当于导致dump的信号的数字
%t: 相当于dump的时间
%h: 相当于hostname
%e: 相当于执行文件的名称
可以按照自己的习惯去命名
在CMakeLists.txt里添加编译选项
add_definitions("-g")
cmake 3.12版本之后,还可以用add_compile_definitions来写,这个暂时没研究
如果你没用cmake,而是直接g++,那么g++ -g就可以了
现我有二进制文件MAIN,对应的core_file core-MAIN-5988 ,于是
gdb MAIN ../core_dump/core-MAIN-5988
然后,就报具体的错误行了(不在main.cc哦)
$ gdb MAIN ../core_dump/core-MAIN-5988
GNU gdb (Ubuntu 12.0.90-0ubuntu1) 12.0.90
Copyright (C) 2022 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying" and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
.
Find the GDB manual and other documentation resources online at:
.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from MAIN...
[New LWP 5988]
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
Core was generated by `./MAIN'.
Program terminated with signal SIGSEGV, Segmentation fault.
#0 0x0000558b2b50b1f5 in Test::fun_err (this=)
at /home/ain/Documents/code/include/test.h:24
--Type for more, q to quit, c to continue without paging
倒数第二行就告诉了你,错误在test.h的第24行,这时你按照最后一行的提示输入c,这一行的内容就会显示出来
Core was generated by `./MAIN'.
Program terminated with signal SIGSEGV, Segmentation fault.
#0 0x0000558b2b50b1f5 in Test::fun_err (this=)
at /home/ain/Documents/code/include/test.h:24
--Type for more, q to quit, c to continue without paging--c
24 std::cout << p->first << std::endl;
至此,我们就定位到了具体出错在哪一行了
ulimit -c和echo指令写入自定义路径,前者只在当前shell有效,后者由于写入了系统文件,因此持续有效
因此如果退出当前shell,core_file大小会重新变成0。其实这样也好,不随便产生coredump文件,给你一个手动控制开关的权力,但如果你想一直持续开启的话,可以将ulimt -c unlimited直接写入相应的shellrc中(如~/.bashrc ~/.zshrc)
希望能帮到大家!