gdb的使用

本文详细介绍GDB调试器的使用方法,包括设置断点、单步执行、查看变量和寄存器值等功能。通过实例演示如何定位和修复程序错误,如段错误。同时,介绍了GDB的布局和窗口管理命令,帮助开发者更高效地进行调试。

gdb使用

gdb 是功能强大的调试程序,可完成如下的调试任务:

  • 设置断点
  • 监视程序变量的值
  • 程序的单步(step in/step over)执行
  • 显示/修改变量的值
  • 显示/修改寄存器
  • 查看程序的堆栈情况
  • 远程调试
  • 调试线程

在可以使用 gdb 调试程序之前,必须使用 -g 或 –ggdb编译选项编译源文件。运行 gdb 调试程序时通常使用如下的命令:

gdb progname

在 gdb 提示符处键入help,将列出命令的分类,主要的分类有:

  • aliases:命令别名
  • breakpoints:断点定义;
  • data:数据查看;
  • files:指定并查看文件;
  • internals:维护命令;
  • running:程序执行;
  • stack:调用栈查看;
  • status:状态查看;
  • tracepoints:跟踪程序执行。

键入 help 后跟命令的分类名,可获得该类命令的详细清单。gdb的常用命令如下表所示。

表 gdb 的常用命令

break FILENAME:NUM在特定源文件特定行上设置断点
clear FILENAME:NUM删除设置在特定源文件特定行上的断点
run运行调试程序
step单步执行调试程序,不会直接执行函数
next单步执行调试程序,会直接执行函数
backtrace显示所有的调用栈帧。该命令可用来显示函数的调用顺序
where continue继续执行正在调试的程序
display EXPR每次程序停止后显示表达式的值,表达式由程序定义的变量组成
file FILENAME装载指定的可执行文件进行调试
help CMDNAME显示指定调试命令的帮助信息
info break显示当前断点列表,包括到达断点处的次数等
info files显示被调试文件的详细信息
info func显示被调试程序的所有函数名称
info prog显示被调试程序的执行状态
info local显示被调试程序当前函数中的局部变量信息
info var显示被调试程序的所有全局和静态变量名称
kill终止正在被调试的程序
list显示被调试程序的源代码
quit退出 gdb

gdb调试实例

下面以一个有错误的例子程序来介绍gdb的使用:

/*bugging.c*/
#include <stdio.h>
#include <stdlib.h>

static char buff [256];
static char* string;
int main ()
{
    printf ("Please input a string: ");
    gets (string);
    printf ("\nYour string is: %s\n", string);
}

这个程序是接受用户的输入,然后将用户的输入打印出来。该程序使用了一个未经过初始化的字符串地址 string,因此,编译并运行之后,将出现 "Segment Fault"错误:

$ gcc -o bugging -g  bugging.c
$ ./bugging
Please input a string: asdf
Segmentation fault (core dumped)

为了查找该程序中出现的问题,我们利用 gdb,并按如下的步骤进行:

[1] 运行 “gdb bugging” ,加载 bugging 可执行文件;

$gdb bugging 

[2] 执行装入的 bugging 命令;

(gdb) run

[3] 使用 where 命令查看程序出错的地方;

(gdb) where

[4] 利用 list 命令查看调用 gets 函数附近的代码;

(gdb) list

[5] 在 gdb 中,我们在第 11 行处设置断点,看看是否是在第11行出错;

(gdb) break 11

[6] 程序重新运行到第 11 行处停止,这时程序正常,然后执行单步命令next;

(gdb) next

[7] 程序确实出错,能够导致 gets 函数出错的因素就是变量 string。重新执行测试程,用 print 命令查看 string 的值;

(gdb) run
(gdb) print string
(gdb) $1=0x0

[8] 问题在于string指向的是一个无效指针,修改程序,在10行和11行之间增加一条语句 “string=buff; ”,重新编译程序,然后继续运行,将看到正确的程序运行结果。

用gdb查看源代码可以用list命令,但是这个不够灵活。可以使用"layout src"命令,或者按Ctrl-X再按A,就会出现一个窗口可以查看源代码。也可以用使用-tui参数,这样进入gdb里面后就能直接打开代码查看窗口。其他代码窗口相关命令:

info win显示窗口的大小
layout next切换到下一个布局模式
layout prev切换到上一个布局模式
layout src只显示源代码
layout asm只显示汇编代码
layout split显示源代码和汇编代码
layout regs增加寄存器内容显示
focus cmd/src/asm/regs/next/prev切换当前窗口
refresh刷新所有窗口
tui reg next显示下一组寄存器
tui reg system显示系统寄存器
update更新源代码窗口和当前执行点
winheight name +/- line调整name窗口的高度
tabset nchar设置tab为nchar个字符
### GDB调试工具的使用指南 #### 启用GDB并设置调试环境 为了启用GDB调试器,需要先编译带有调试信息的程序。可以通过`gcc`命令添加`-g`选项来生成调试信息[^2]。例如: ```bash gcc -g program.c -o program ``` 随后可以启动GDB调试器,并加载目标程序: ```bash gdb ./program ``` 如果需要向被调试程序传递参数,则可以在运行时通过`run`命令指定这些参数[^1]: ```bash (gdb) run arg1 arg2 ``` #### 使用GDB命令进行调试 在GDB环境中,有多种命令可以帮助开发者查看程序的状态、控制执行流以及分析错误。 ##### 查看源码和状态信息 使用`list`命令可以查看当前文件中的源代码片段[^4]: ```bash (gdb) list ``` 此命令会显示当前上下文附近的代码行数,默认为10行。 ##### 断点管理 断点用于暂停程序以便进一步检查其行为。创建断点的方法如下: ```bash (gdb) break main ``` 这将在函数`main`入口处设置一个断点。还可以通过行号设置断点: ```bash (gdb) break filename.c:line_number ``` 删除特定编号的断点可通过以下方式实现: ```bash (gdb) delete breakpoint_number ``` ##### 单步执行 单步执行允许逐条语句跟踪程序逻辑。以下是常用的单步执行命令: - `step`: 进入子函数继续调试。 - `next`:进入子函数而跳过它。 - `continue`: 继续执行直到遇到下一个断点。 ##### 变量监控与表达式求值 利用`print`命令能够打印变量或表达式的值: ```bash (gdb) print variable_name ``` 对于复杂的数据结构或者指针内容,可能还需要借助格式化输出功能[^2]: ```bash (gdb) print/x address_value # 显示十六进制地址 ``` #### 分析Core Dump文件 当应用程序异常终止时可能会生成core dump文件。要使用GDB对此类文件进行分析,需按照下面的方式操作[^3]: ```bash gdb executable_file core_dump_file ``` 之后即可像正常调试一样探索崩溃时刻的信息,比如回溯调用链(`bt`)、检视寄存器状态等。 --- ### 常见GDB命令总结表 | 功能 | 对应命令 | |---------------------|------------------------------| | 开始调试 | gdb target_program | | 执行程序 | (gdb) run | | 列出源代码 | (gdb) list | | 设置断点 | (gdb) break function_or_line| | 删除断点 | (gdb) delete breakpoint_num | | 步骤前进(不进入函数)| (gdb) next | | 步骤前进(进入函数内部)|(gdb) step | | 继续执行到下一断点 | (gdb) continue | | 打印变量 | (gdb) print varname | ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值