Linux系统调试器gdb使用

程序用GCC进行编译时要加上“-g”选项

一.调用 GDB 调试器的4 种方法

1.直接使用 gdb 指令启动 GDB 调试器:由于事先未指定要调试的具体程序,因此需启动后借助 file 或者 exec-file 命令指定

[root@bogon ~]# gdb -q
(gdb) file /tmp/demo/test

2.调试尚未执行的程序:输入GDB和要调试的可执行文件即可,如下所示。

gdb test

3.调试正在执行的程序
  a.首先使用pidof查出进程PID号

pidof test

  b.使用以下三种方法调用GDB

1) gdb attach PID
2) gdb test PID
3) gdb -p PID
注1:当调试完成后,如果想令当前程序进行执行,消除调试操作对它的影响,需手动将 GDB 调试器与程序分离,分离过程分为 2 步:
        1. 执行 detach 指令,使 GDB 调试器和程序分离;
        2. 执行 quit(或 q)指令,退出 GDB 调试。
注2:GDB 调试器成功连接到指定进程上时,程序执行会暂停

4.调试执行异常崩溃的程序
    Linux 操作系统中,当程序执行发生异常崩溃时,系统可以将发生崩溃时的内存数据、调用堆栈情况等信息自动记录下载,并存储到一个文件中,该文件通常称为 core 文件,Linux 系统所具备的这种功能又称为核心转储(core dump).
    Linux 系统默认不开启 core dump 功能,可以执行ulimit -c指令查看系统是否开启此功能,如果 core file size(core 文件大小)对应的值为 0,表示当前系统未开启 core dump 功能,可以通过执行如下指令改变 core 文件的大小:

[root@bogon demo]# ulimit -a
core file size          (blocks, -c) 0
......
[root@bogon demo]# ulimit -c unlimited      #unlimited 表示不限制 core 文件的大小。
[root@bogon demo]# ulimit -a
core file size          (blocks, -c) unlimited
......

对于 core 文件的调试,其调用 GDB 调试器的指令为:

gdb test core

对于 core 文件中记录的崩溃信息,可以使用 where、print、bt 等指令查看
gdb启动时可设置的参数

二.查看文件“l”(list)就可以查看所载入的文件

三.运行代码

run 命令除了可以启动程序的执行,还可以在任何时候重新启动程序,且加上行号即可从程序中指定行开始运行

四.传递参数的3 种方法:argv[] 字符串数组接收

1.启动 GDB,在指定目标调试程序的同时,使用 --args 选项指定需要传递给该程序的数据。

[root@bogon demo]# gdb --args test a.txt

2.GDB启动后,借助 set args 命令指定目标调试程序启动所需要的数据。

(gdb) set args a.txt

3.除此之外,还可以使用 run 或者 start 启动目标程序时,指定其所需要的数据。

(gdb) run a.txt
(gdb) start a.txt

五.断点

1.普通断点(break、tbreak、rbreak)

break的两种方法

(gdb) break location      // b location
(gdb) break ... if cond   // b .. if cond

a.第一种格式中,location 用于指定打断点的具体位置

b.第二种格式中,… 可以是表 1 中所有参数的值,用于指定打断点的具体位置;cond 为某个表达式。整体的含义为:每次程序执行到 … 位置时都计算 cond 的值,如果为 True,则程序在该位置暂停;反之,程序继续执行。

tbreak 命令可以看到是 break 命令的另一个版本,使用 tbreak 命令打的断点仅会作用 1 次,即使程序暂停之后,该断点就会自动消失。
rbreak 命令的作用对象是 C、C++ 程序中的函数,它会在指定函数的开头位置打断点。tbreak 命令的使用语法格式为:

(gdb) tbreak regex

其中 regex 为一个正则表达式,程序中函数的函数名只要满足 regex 条件,tbreak 命令就会其内部的开头位置打断点。值得一提的是,tbreak 命令打的断点和 break 命令打断点的效果是一样的,会一直存在,不会自动消失。

2.观察断点(watch、rwatch、awatch)
(gdb) watch cond       #conde 指的就是要监控的变量或表达式。所谓表达式,就是包含多个变量的式子,比如 a+b 就是一个表达式,其中 a、b 为变量。
(gdb) watch conde if cond

rwatch程序中出现读取目标变量(表达式)的值的操作,程序就会停止运行;
awatch程序中出现读取目标变量(表达式)的值或者改变值的操作,程序就会停止运行。

注:
    a. 当监控的变量(表达式)为局部变量(表达式)时,一旦局部变量(表达式)失效,则监控操作也随即失效;
    b.监控指针变量时(例如 *p),则 watch *p 和 watch p 是有区别的,前者监控的是 p 所指数据的变化情况,而后者监控的是 p 指针本身有没有改变指向;
    c.可监控数组中元素值的变化情况,对于 a[10] 这个数组,watch a 表示只要 a 数组中存储的数据发生改变,程序就会停止执行。

3.捕捉断点(catch、tcatch)

捕捉断点的作用是,监控程序中某一事件的发生,例如程序发生某种异常时、某一动态库被加载时等等,一旦目标时间发生,则程序停止执行。

(gdb) catch event
(gdb) watch event if cond

注:
    a. catch匹配过程需要借助 libstdc++ 库中的一些 SDT 探针,其需求GCC 编译器的版本最低为 4.8。但即便如此,catch 命令是否能正常发挥作用,还可能受到系统中其它因素的影响。
    b. 当 catch 命令捕获到指定的 event 事件时,程序暂停执行的位置往往位于某个系统库(例如 libstdc++)中。这种情况下,通过执行 up 命令,即可返回发生 event 事件的源代码处。
    c. catch 无法捕获以交互方式引发的异常。

tcatch 命令只监控一次,只有目标时间第一次触发时,tcath 命令才会捕获并使程序暂停,之后将失效。

info b  [n]                   查看断点设置情况。在GDB中可以设置多个断点。n 为某个断点的编号,可省略。
info watchpoints [n]  查看观察断点设置情况。在GDB中可以设置多个断点。

condition 命令的功能是:既可以为现有的普通断点、观察断点以及捕捉断点添加条件表达式,也可以对条件断点的条件表达式进行修改。语法格式如下:

(gdb) condition bnum expression         #参数 bnum 用于代指目标断点的编号;参数 expression 表示为断点添加或修改的条件表达式。
(gdb) condition bnum

以上 2 种语法格式中,第 1 种用于为 bnum 编号的断点添加或修改 expression 条件表达式;第 2 种用于删除 bnum 编号断点的条件表达式,使其变成普通的无条件断点。

ignore 命令可以使目标断点暂时失去作用

ignore bnum count   #参数 bnum 为某个断点的编号;参数 count 用于指定该断点失效的次数。

clear 命令可以删除指定位置处的所有断点

(gdb) clear location #ocation 通常为某一行代码的行号或者某个具体的函数名。当 location 参数为某个函数的函数名时,表示删除位于该函数入口处的所有断点。

delete 命令(可以缩写为 d )通常用来删除所有断点,也可以删除指定编号的各类型断点

(gdb) delete [breakpoints] [num]  #breakpoints 参数可有可无,num 参数为指定断点的编号,其可以是 delete 删除某一个断点,而非全部。

disable 命令可以禁用断点

(gdb) disable [breakpoints] [num...]    #breakpoints 参数可有可无;num... 表示可以有多个参数,每个参数都为要禁用断点的编号。如果指定 num...,disable 命令会禁用指定编号的断点;反之若不设定 num...,则 disable 会禁用当前程序中所有的断点。
enable [breakpoints] [num...]           激活用 num... 参数指定的多个断点,如果不设定 num...,表示激活所有禁用的断点
enable [breakpoints] once num…          临时激活以 num... 为编号的多个断点,但断点只能使用 1 次,之后会自动回到禁用状态
enable [breakpoints] count num...       临时激活以 num... 为编号的多个断点,断点可以使用 count 次,之后进入禁用状态
enable [breakpoints] delete num…        激活 num.. 为编号的多个断点,但断点只能使用 1 次,之后会被永久删除。

六.查看变量值:

display 命令每次程序暂停执行时都会自动打印出目标变量或表达式的值
print 命令只能查看 1 次某个变量或表达式的值,其复杂语法为:

(gdb) print [options --] [/fmt] expr

options:表示该命令所支持的选项; fmt:指定输出变量或表达式值时所采用的格式;expr:指定要查看的变量或表达式。

注意,options 参数和 /fmt 或者 expr 之间,必须用--( 2 个 - 字符)分隔。

当 print 命令不指定任何 options 参数时,print 和 /fmt 之间不用添加空格
除了表达式本身外,GDB 调试器还支持使用@和::运算符

(gdb) p array[0]@2
(gdb) p 'main.c'::num
(gdb) p main::num

七.单步运行

n(next)在“n”后面加上行号即可从程序停止处运行指定行数 (不进入子函数)
s(step) 在“n”后面加上行号即可从程序停止处运行指定行数 (进入子函数)
u(until)快速运行完当前的循环体,并运行至循环体外停止。注意,until只有当执行至循环体尾部(最后一行代码)时,until 命令才会发生此作用,否则作用同next。

八.程序继续运行:c(continue)

九.退出GDB:q(quit)

十.调试运行环境相关命令

临时(退出 GDB 调试后会失效)修改 PATH 环境变量,此时就可以借助 path 指令。

## (gdb) path /temp/demo

finish 命令会执行函数到正常退出
return<返回值>命令是立即结束执行当前函数并返回
jump 命令的功能是直接跳到指定行继续执行程序

十一.堆栈相关命令

十二.多线程调试

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

RobotWoods

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值