初学者GDB调试教程

1.安装需要使用的工具

sudo apt install gdb build-essential gcc

2.编写测试程序

vi test.c

 将下面代码复制到test.c中。

int actual_calc(int a, int b){
  int c;
  c=a/b;
  return 0;
}

int calc(){
  int a;
  int b;
  a=13;
  b=0;
  actual_calc(a, b);
  return 0;
}

int main(){
  calc();
  return 0;
}

3.执行我们的脚本并配置核心转储

-ggdb 这是一个编译选项,用于在编译过程中生成调试信息

gcc -ggdb test.c -o test.out
./test.out

 显示如下结果说明程序进行了非法的浮点运算,因为上面程序设置的除数为0.

(1)编写shell脚本,对系统核心转储(core dump)相关的配置进行检查和设置。

if ! grep -qi 'kernel.core_pattern' /etc/sysctl.conf; then
  sudo sh -c 'echo "kernel.core_pattern=core.%p.%u.%s.%e.%t" >> /etc/sysctl.conf'
  sudo sysctl -p
fi
ulimit -c unlimited        # -c 专门用于设置核心转储文件的最大大小
#ulimit 命令设置的限制仅对当前 shell 会话有效

grep 是一个用于在文件中查找匹配指定模式的行的工具,在这里它的作用是检查 /etc/sysctl.conf 文件里是否存在 kernel.core_pattern 这一配置项。

-q 选项表示静默模式,即不输出匹配的内容,只返回匹配结果的状态码。

kernel.core_pattern 是内核参数,用于指定核心转储文件的命名模式

  • %p 表示产生核心转储的进程的进程 ID。
  • %u 表示产生核心转储的进程的用户 ID。
  • %s 表示导致核心转储的信号编号。
  • %e 表示产生核心转储的进程所对应的可执行文件的文件名。
  • %t 表示核心转储发生的时间戳。

sysctl 是一个用于查看和修改内核参数的工具-p 选项表示从 /etc/sysctl.conf 文件中加载内核参数配置,使刚刚添加或修改的 kernel.core_pattern 参数生效。

unlimited表示不限制核心转储文件的大小。这样设置后,当程序崩溃产生核心转储时,会生成完整的核心文件,方便后续的调试工作。

ulimit -c        #查看当前核心转储文件的大小限制,若为unlimited则设置成功

这段脚本的主要目的是确保 /etc/sysctl.conf 文件中配置了 kernel.core_pattern 参数,若未配置则添加该配置并使其生效,同时设置核心转储文件大小不受限制,以便在程序崩溃时能完整保存核心转储文件,方便后续的调试和分析。

(2)将所有用户的核心转储文件大小限制设置为无限制,并将该设置覆盖写入 /etc/security/limits.conf 文件。

sudo bash -c "cat << EOF > /etc/security/limits.conf
* soft core unlimited
* hard core unlimited
EOF

-c 选项表示让 bash 将后面引号内的字符串作为一条命令来执行cat 一般用于显示文件内容,这里结合 <<(Here 文档)使用。EOF是Here 文档的结束标记。* 代表所有用户

> 是重定向符号,它会把 cat 接收到的 Here 文档内容覆盖写入 /etc/security/limits.conf 文件。如果使用 >> 则是追加写入

你也可以将 ulimit -c unlimited 添加到你的 shell 配置文件中。这样每次登录都自动应用这个设置。(选一个即可)

gedit ~/.bashrc
source ~/.bashrc

(3)重新执行文件,会看到一个核心文件(具有指定的核心模式)。检查核心转储文件的元数据。

./test.out        #设置好核心转储文件后再运行会生成一个core
ls                #用ls找到该core
file core.4047.1000.8.test.out.1743061424  #core记得替换为自己生成的

4.使用 GDB 分析核心转储

调用了第一个选项的二进制文件,第二个选项调用了核心文件。

gdb ./test.out ./core.4047.1000.8.test.out.1743061424

我们看到核心转储是由 SIGFPE 生成的,并被告知该信号是一个 SIGFPE,算术异常。

具体错误出现在test.c文件的第 3 行,执行c = a / b;时,b的值为 0,触发了除零错误。

5.回溯

bt        

bt(backtrace):如果您使用多个线程,则可以使用该命令来获取在程序崩溃时运行的所有线程的回溯跟踪。

6.框架检查

f:frame 

p:print

f 2        #跳转到第二帧
list       #列出源代码
p a        #打印变量a的值

注意f 0中我们已经定义了变量c,但尚未为其提供初始值。因此,它实际上是未定义的(并且尚未由方程填充,因为该方程失败了),并且结果值可能是从变量分配到的某个地址空间读取的(并且该内存空间可能尚未初始化/清除)。

7.结论

好的我们现在能够调试 C 程序的核心转储,学会了GDB调试基础知识。设置好核心转储(core dump)后,下次再使用GDB进行调试只需要将准备好的c文件编译、运行,ls找到生成的core,然后gdb ./文件 ./核心文件就好了。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值