Linux下gdb调试方法

GDB(GNU Debugger)是Linux环境下一款强大的命令行调试工具,由GNU项目提供,用于帮助开发者诊断和修复程序中的错误。它支持多种编程语言,包括C、C++、Fortran、Pascal以及其他使用GNU编译器集合(GCC)编译的语言。GDB提供了丰富的功能,如设置断点、单步执行代码、查看和修改变量值、查看调用堆栈、分析内存、执行程序直到特定条件满足等,这些都是软件开发和调试过程中不可或缺的工具。

如何使用GDB进行调试程序:

准备程序
  1. 编译程序时加入调试信息:使用gccg++编译时,需要添加-g选项,以便在可执行文件中包含调试信息。例如:

    gcc -g my_program.c -o my_program
    
启动GDB
  1. 启动GDB:在命令行中输入gdb后跟你的程序名来启动GDB并加载程序。

    gdb my_program
    
基本命令
  1. 运行程序:在GDB提示符下,输入runr来运行程序。

    (gdb) run
    
  2. 设置断点:可以使用break命令(简写为b)在特定的函数名或代码行设置断点。

    (gdb) break main        # 在main函数开始处设置断点
    (gdb) break 42         # 在第42行设置断点
    
  3. 单步执行:使用step(简写为s)命令逐行执行代码,进入函数内部;使用next(简写为n)命令跳过函数内部,直接执行到下一行。

    (gdb) step
    (gdb) next
    
  4. 查看变量值:使用print(简写为p)命令查看变量或表达式的值。

    (gdb) print variable_name
    
  5. 继续执行至下一个断点:当程序在某个断点暂停时,使用continue(简写为c)命令继续执行,直到遇到下一个断点。

    (gdb) continue
    
  6. 查看调用堆栈:使用backtrace(简写为bt)查看当前的函数调用堆栈。

    (gdb) backtrace
    
  7. 退出GDB:输入quit(简写为q)退出GDB。

    (gdb) quit
    
进阶使用
  • 条件断点:可以在设置断点时指定条件,例如,break if condition会在condition为真的时候才触发断点。
  • 查看内存和寄存器:使用x命令查看内存内容,info registers查看CPU寄存器状态。
  • 修改变量值:使用set variable variable_name = value命令修改变量值。
  • 脚本和自动化:GDB支持编写脚本来自动化调试任务,可以使用source命令执行脚本文件。

GDB是一个功能丰富且高度可配置的工具,熟练掌握它对于提高程序调试效率至关重要。由于它是一个命令行工具,初学者可能需要一段时间来熟悉各种命令,但一旦掌握,会发现它在复杂调试场景中的强大和灵活性。

编译Debug版本程序

若要调试程序,编译程序的时候必须带上-g调试选项,让程序附带debug信息

$gcc -g xxx.c -o a.out
$g++ -g xxx.cpp -o a.out

启动调试程序

GDB启动参数简写解释
-quiet-q不打印GDB的介绍信息和版权信息
-symbols=-s指定被调试程序的符号表文件
-exec=-e指定被调试程序的名称
-se=读取符号表的文件和可执行文件
-core=-c使用文件作为一个coredump文件来测试
-directory=-d指定被调试程序的源文件搜索路径。默认搜索路径是环境变量PATH
-cd=指定工作目录,默认为当前目录
–args若被调试程序后面携带参数,需要加上–args

这里以调试a.out程序为例子(a.out 为附带debug信息的可执行程序)

启动调试程序

$gdb a.out

当不需要查看gdb版本信息时,可以使用-q参数取消打印gdb版本信息

$gdb -q a.out

当要调试的程序带有参数时,需要使用–args选项启动可执行程序,并且在可执行程序后边加上参数

$gdb --args a.out 100 200

常用调试命令

调试过程控制

命令简写解释
(gdb) runr运行程序,会自动在第一个断点处暂停执行
(gdb) start运行程序,单步执行,停在第一执行语句
(gdb) nextn单步调试,直接执行不会进入函数,类似于Step Over
(gdb) steps单步调试,若遇到函数会进入内部,类似于Step Into
(gdb) finishfi单步调试,执行完函数并跳出函数,类似于Step Out
(gdb) until <line_number>u使程序运行至第line_number行处暂停,类似于Run To Cursor
(gdb) continuec继续运行,直至遇到断点或者程序结束
(gdb) quitq终止调试

调试断点设置

调试断点命令简写解释
(gdb) info break [n]info b [n]显示当前程序的断点,其中n为可选的断点编号
(gdb) break <line_number>b <line_number>添加断点,line_number为源代码的行号
(gdb) clear <line_number>删除断点,line_number为源代码的行号
(gdb) delete 删除断点,n为断点的编号
(gdb) delete breakpoints删除所有断点
(gdb) enable 启用断点,n为断点的编号
(gdb) disable 暂停断点,n为断点的编号

调试源码查看

查看源码命令简写解释
(gdb) listl列出程序源码,默认每次显示10行
(gdb) list <line_number>列出程序源码,以line_number行为中心显示前后10行代码
(gdb) list <func_name>将显示“func_name”函数的源代码

运行时信息查看

打印信息简写解释
(gdb) print <表达式>p输出表达式的值,“表达式”可以是任何数字、变量、函数调用等
(gdb) display <表达式>显示表达式的值,单步调试时每次执行都会输出显示
(gdb) watch <表达式>设置监视点,当表达式的值发生变化会强行终止正在被调试的程序
(gdb) whatis <表达式>查看表达式的类型定义
(gdb) backtracebt显示当前调用堆栈

多线程调试方法

命令解释
(gdb) info threads查看当前进程的所有线程运行情况
(gdb) thread 切换到具体id编号的线程上去
(gdb) thread apply 让一个或者多个线程执行GDB命令CMD
(gdb) thread apply all 让所有被调试线程执行GDB命令CMD
以下是多线程中断点的设置方法
(gdb) break <line_number> thread 在某个文件的line_number行添加断点,只作用于ID指定的线程
(gdb) break <line_number> thread all在某个文件的line_number行添加断点,作用于所有的线程

分割窗口设置

分割窗口解释
(gdb) layout src显示源代码窗口
(gdb) layout asm显示反汇编窗口
(gdb) layout regs显示源代码/反汇编和CPU寄存器窗口
(gdb) layout split显示源代码和反汇编窗口
Ctrl + L刷新窗口显示

Linux下常用的调试场景

在Linux下执行可执行程序时经常会打印Segmentation fault(段错误),当遇到这种情况时,我们可以通过查看程序执行时的堆栈信息定位程序出错的大体位置信息,以方便我们查找问题。

例如执行a.out 时,出现这种情况

$a.out 100 200
Segmentation fault

使用如下命令启动调试程序

$gdb -q --args a.out 100 200		#启动调试程序
(gdb)r		#run 运行程序

...			#这里会打印程序执行异常

(gdb)bt		#backtrace 打印程序堆栈信息

···			#此时会打印程序的调用堆栈,通过查看堆栈可以得知在调用那个函数时发生崩溃你

(gdb)q		#退出调试程序
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

DS小龙哥

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

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

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

打赏作者

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

抵扣说明:

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

余额充值