Linux下使用coredump调试软件bug:使用篇

应用程序在运行过程中由于各种异常或者bug导致退出,在满足一定条件下产生一个core文件。

通常core文件包含了程序运行时内存、寄存器状态、堆栈指针、内存管理信息以及函数调用堆栈信息。

core就是程序当前工作转改存储生成的一个文件,通过工具分析这个文件,可以定位到程序异常退出的时候对应的堆栈调用等信息,找出问题点并解决。

coredump

如果需要使用需要通过ulimit进行设置,可以通过ulimit -c查看当前系统是否支持coredump。如果为0,则表示coredump被关闭。

通过ulimit -c unlimited可以打开coredump。

coredump文件默认存储位置与可执行文件在同一目录下,文件名为core。

可以通过/proc/sys/kernel/core_pattern进行设置。

1
2
3
4
5
6
7
%p  出Core进程的PID
%u 出Core进程的UID
%s 造成Core的signal号
%t 出Core的时间,从1970-01-0100:00:00开始的秒数
%e 出Core进程对应的可执行文件名
%g 所dump进程的实际组ID
%h 程序所属的host

首先进入root用户,然后通过

1
echo "/tmp/coredump-%e-%p-%u-%g-%s-%t-%h" > /proc/sys/kernel/core_pattern

调整生成的coredump文件的名称和位置,默认位置是:/usr/lib/systemd/文件夹下。

但是这些操作只对当前用户当前状态有效,我们想要永久有效。

永久设置

首先在/etc/profile中添加:

1
2
sysctl -p -q -e
ulimit -c unlimited

系统启动时会自动执行这个文件,第一行表示执行sysctl,第二行表示设置core无内存大小限制。

其次在/etc文件夹下添加sysctl.conf文件(如果没有的话),并添加:

1
2
kernel.core_pattern = /tmp/coredump_%e_%p_%t
kernel.core_uses_pid = 0

这样的话系统启动时会自动设置coredump相关设置。

如果需要立刻生效的话,需要执行:

1
sysctl -p

测试

我们来简单测试一下:

1
2
3
4
5
6
7
8
9
10
11
#include <iostream>

using namespace std;

int main()
{
int a,b;
cin>>a>>b;
cout<<a/b<<endl;
return 0;
}

如果输入的b为0,那么一定会出错。

执行如下:

1
2
3
$ ./coredump                       
1 0
[1] 34490 floating point exception (core dumped) ./coredump

执行出错,会在/tmp文件夹下生产coredump文件。(之所以设在/tmp文件夹下,系统关闭时会清空/tmp文件夹,这样的话就不会占用太多空间)

我们到软件可执行程序所在文件夹下,执行:

1
gdb app_path -c coredump_path

此示例输出为:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
$ gdb ./coredump -c /tmp/coredump_coredump_34490_1592660854                 
GNU gdb (GDB) 9.2
Copyright (C) 2020 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later &lt;http://gnu.org/licenses/gpl.html&gt;
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-pc-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
&lt;http://www.gnu.org/software/gdb/bugs/&gt;.
Find the GDB manual and other documentation resources online at:
&lt;http://www.gnu.org/software/gdb/documentation/&gt;.

For help, type "help".
Type "apropos word" to search for commands related to "word"...
Registered pretty printers for UE4 classes
Reading symbols from ./coredump...
[New LWP 34490]

warning: Unexpected size of section `.reg-xstate/34490' in core file.
Core was generated by `./coredump'.
Program terminated with signal SIGFPE, Arithmetic exception.

warning: Unexpected size of section `.reg-xstate/34490' in core file.
#0 0x0000559991fbd1cf in main () at ../coredump/main.cpp:9
9 cout<<a/b<<endl;

此程序的coredump直接显示了程序在哪出错,打扰了因为程序比较简单,如果程序比较复杂,可以输入bt查看库调用关系。我的是

1
2
3
(gdb) bt
#0 0x0000559991fbd1cf in main () at ../coredump/main.cpp:9
(gdb)

因为程序比较简单,没有调用说明动态链接库,直接输出错误的位置了。

下一篇:原理篇