Debugging with GDB学习记录(一)

本文详细介绍了GDB调试器的基本使用方法,包括如何启动程序、选择调试模式、离开GDB以及执行各种命令。文章还涵盖了GDB的启动参数、选择文件、模式选项和命令执行等内容,旨在帮助开发者高效地进行程序调试。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

最近使用GDB调试程序,所以阅读了《Debugging with GDB》一书,略作记录,如需仔细研究使用,建议仍阅读英文版书籍或MAN手册


调试器,比如GDB,的目的就是用于查看运行中的程序的执行流程以及环境、变量等情况。GDB主要可以工作于四种事情:
1、启动程序,并指定影响程序行为的操作
2、让程序在特定情况下停止
3、当程序停止时,检查发生情况
4、Change things in your program,从而可以矫正bug,并解决下一个bug


启动GDB
1、在命令行上键入gdb
可以为gdb命令配置参数、选项以更好的配置调试环境
2、gdb program-name
3、gdb program-name core-file
   需要一个fairly complete os,但很难有方法来获得core dumps,如果gdb无法attach或读core dumps时,GDB会给出警告
4、gdb program-name pid   
   可以调试正在运行中的进程
5、gdb --args gcc -O2 -c foo.c
   gdb可以使用--args,用于向可执行文件传递参数。本例用于调试gcc,并设置gcc命令行参数为-O2 -c foo.c
6、gdb -silent
   启动gdb时不会显示一些版本等信息
给定的参数和选项会被顺序处理,而使用-x选项后,就不同了。


选择文件
GDB在读取命令行参数时,如果没有指定如下选项,会认为第一个参数是可执行程序(与指定-se类似),第二个参数是进程ID或core dump文件,
如果以数字开头则认为是pid文件,如果某个core dump文件以数字开头,应当转义:加上‘./’前缀,例如'./12345'
1、-symbols file      -s file
   从file文件中读取符号表symbol table
2、-exec file         -e file
   指定可执行文件file
3、-se file  
   从file中读取符号表并把file作为可执行文件
4、-core file         -c file
   指定core dump文件file
5、-pid number        -p number
   将gdb attach到进程pid
6、-command file      -x file
   从file文件中执行命令
7、-eval-command command  -ex command
   执行一single GDB命令,该选项可被多次使用来调用符合命令,也可以与'-command'混合使用,如:
   gdb -ex 'target sim' -ex 'load' -x setbreakpoints -ex 'run' a.out
8、-directory directory  -d directory
   在path中增加查找源文件和脚本文件的目录
9、-r    -readnow
   立即读取每个符号文件中的全部符号表,而不是默认处理方式(增量读取)。


选择模式:
1、-nx     -n
   不要执行任何initialization file文件中的任何命令,一般情况下,GDB执行完命令选项和参数后会执行这些文件中的命令
2、-quiet -silent -q
   不要打印介绍和版权信息
3、-batch
   在批处理模式下运行,在执行完-x指定文件中的所有内容后,返回0,如果有错误发生,则返回非0
4、-batch-silent
   批处理和静默模式,所有到stdout的GDB输出都被禁止。
5、-return-child-result
   GDB返回值是被调式的子进程的返回值,以下情况例外:
   (1)、GDB非正常停止,这时的返回值,跟没有使用该选项一样;
   (2)、使用者使用明确的值离开gdb,如'quit 1'
   (3)、子进程没有运行或者不允许停止,这种情况下返回值一般会是-1;
   当GDB用于remote program loader或simulator interface时,与'-batch'或'-batch-silent'联合使用方便。
6、-nowindows  -nw
   如果GDB有GUI,则该选项让GDB仅使用命令行接口,如果没有GUI,则该选项没用。
7、-windows   -w
   如果GDB有GUI,则该选项让GDB如果可能则可以使用GUI
8、-cd directory
   将该directory作为GDB的工作目录
9、-data-directory directory
   使用该directory作为GDB的数据目录,该目录是GDB查找其辅助文件的地方
10、-fullname   -f
    GNU Emacs将GDB作为subprocess运行时,设置此选项。每次显示一个栈帧时,它命令GDB输出全部文件名以及行号。
    以两个'\032':文件名:行号:字符位置,下面跟一新行形式显示。
11、-epoch
   Epoch Emacs-GDB接口在将GDB运行为subprocess时设置该选项,让GDB修改打印程序,来允许Epoch在一个单独的窗口中显示表达式的值。
12、-annotate level
   设置GDB内部的annotation级别,这个基本决定了:GDB输出多少提示信息,如:表达式值、源文件行数等等
   Level 0:normal;   Level 1:用于GDB作为GNU Emacs子进程运行;  Level 3:是控制GDB程序所能用的最大级别; Level 2:不用
   这个annotation技术现已被GDB/MI取代
13、--args
   使得可执行文件之后的参数是作为可执行文件的输入参数使用
14、-baud bps   -b bps
    通过串口,使用GDB远程调试时,设置串口波特率
15、-l timeout
    远程调试时,设置GDB通信的超时时间(单位:秒)
16、-tty device     -t device
    指定程序标准输入和输出使用的设备
17、 -tui
    启动时激活Text User Interface接口。TUI接口管理终端上的多个文本窗口,显示:源、汇编、寄存器和GDB命令输出信息。
    也可以使用'gdbtui'程序,在从Emacs中运行GDB时不用该选项。
18、-interpreter interp
    使用解释器interp作为与控制程序或设备的接口。‘--interpreter=mi’使GDB使用GDB/MI接口
19、-write
    以读写方式打开可执行文件和core文件,功效同:GDB内的‘set write on’。
20、-statistics
    当GDB执行完任一个命令并返回输入时,打印关于time和内存使用情况的统计信息。
21、-version
    版本信息


GDB启动时做了什么?
1、设置命令解释器;
2、读取system-wide init file(如果编译GDB时使用了'--with-system-gdbinit')并执行该文件内所有命令;
3、读取用户home目录下的init文件并执行该文件内所有命令(if any);
4、处理命令行选项和操作;
5、读取并执行当前工作目录下init文件中的命令(if any),仅在当前目录并非用户home目录时执行;
6、如果命令行执行可执行文件、或进程ID或core文件,则GDB为该程序或其共享库加载auto-loaded scripts
   如果不想启动时自动加载,则执行$gdb -ex "set auto-load-scripts off" -ex "file myprogram"
   而下面这个命令则不起作用,因为auto-loading被关闭时已经晚了:$gdb -ex "set auto-load-scripts off" myprogram


7、读取-x指定的命令文件
8、读取history文件中记录的历史命令


init文件使用命令行文件相同的语法,并以相同方式处理。在用户home目录里的init文件可以设置选项影响后续命令行选项及操作的处理,
如果设置了-nx选项,则init file不会执行。


为显示gdb启动时加载的init file列表,可执行gdb --help
GDB init files are normally called '.gdbinit'。GDB的DJGPP port使用'gdb.ini'名字


离开GDB
quit [expression]      q或者Ctrl-d
如果是Ctrl-c无法从GDB中离开,它的作用仅仅是停止GDB中某个正在执行的GDB命令的停止。如果是attach process或device,可以通过
detach命令来释放之。


Shell命令
如果想在调试时执行shell命令,不必离开或挂起GDB
shell command string即可,如下所示:
(gdb) shell ls
apr-1.4.5-1.x86_64.rpm      ganglia-devel-3.2.0-1.x86_64.rpmganglia-gmond-modules-python-3.2.0-1.x86_64.rpm
apr-debuginfo-1.4.5-1.x86_64.rpm      ganglia-gmetad-3.2.0-1.x86_64.rpmlibganglia-3.2.0-1.x86_64.rpm
apr-devel-1.4.5-1.x86_64.rpm      ganglia-gmetad-python-3.2.0-1.x86_64.rpm
ganglia-debuginfo-3.2.0-1.x86_64.rpm  ganglia-gmond-3.2.0-1.x86_64.rpm
环境变量SHELL决定了要调用执行的shell


make make-args
以指定参数运行make,等同于'shell make make-args'


Logging Output
将GDB命令输出到文件,有以下命令控制GDB的logging
1、set logging on
   使能logging
2、set logging off
   禁止logging
3、set logging file file
   改变当前日志文件的名字,默认为gdb.txt
4、set logging overwrite [on | off]]
   默认情况下,GDB会append到logfile上,如果想覆盖,则可以如此设置
5、set logging redirect [on | off]
   默认情况下,GDB输出会同时输出到终端和日志文件,如果仅输出到日志文件,则设置redirect
6、show logging

   输出日志设置的当前值


GDB命令
可以用回车键重复执行部分GDB命令,可以用TAB键补齐GDB命令


命令语法
GDB命令可以使用首部部分字母缩写来表示,前提是不引起混淆,可用help command-name来查看该命令帮助
空行(直接回车)作为GDB输入意思是重复上一个命令,仅部分命令支持,例如run命令就不支持这种方式的重复,用户定义
的命令也禁止这样做:
(gdb) help step
Step program until it reaches a different source line.
Argument N means do this N times (or till program stops for another reason).
(gdb) 
Step program until it reaches a different source line.
Argument N means do this N times (or till program stops for another reason).


list和x命令在使用RET重复时,需要构建新的参数,而不是简单的重复上次的键入
#注释
Ctrl-o用于重复命令的一个复杂序列,该命令接受当前行,然后从历史记录中找到与当前行相关的另一个行,用于编辑


补齐命令
TAB键


如果想看所有的GDB命令,可以ESC?或两次TAB
更有可能使用的情况是可能在C++函数中使用的,因为C++支持重载,所以,同一函数名,需要以参数分开,可以在函数名前使用',这告诉GDB在
TAB时考虑更多的信息,例如:
(gdb) b ’bubble( M-?
bubble(double,double) bubble(int,int)
(gdb) b ’bubble(
可以使用set overload-resolution off来禁止overload resolution。也可以补齐struct结构体中的变量


获取帮助
1、(gdb) help  
显示命令分类,如下所示:
(gdb) help
List of classes of commands:


aliases -- Aliases of other commands
breakpoints -- Making program stop at certain points
data -- Examining data
files -- Specifying and examining files
internals -- Maintenance commands
obscure -- Obscure features
running -- Running the program
stack -- Examining the stack
status -- Status inquiries
.....................


2、help class
显示该类下的命令
(gdb) help status


3、help command
显示命令使用帮助


4、apropos args
遍历搜索所有的GDB命令及其文档,来查找args指定的正则表达式,这会打印出所有匹配的信息。
(gdb) apropos reload
set symbol-reloading -- Set dynamic symbol table reloading multiple times in one run
set symbol-reloading -- Set dynamic symbol table reloading multiple times in one run
show symbol-reloading -- Show dynamic symbol table reloading multiple times in one run
show symbol-reloading -- Show dynamic symbol table reloading multiple times in one run
5、complete args
列出args开头的所有可能的补齐命令
(gdb) complete i
if
ignore
info
init-if-undefined
inspect
interpreter-exec
interrupt


除了help之外,还可以用GDB命令info和show来查询程序状态或GDB状态
1、info
描述你自己程序的状态,例如info args显示传递给函数的参数,info registers显示当前使用的寄存器,info breakpoints显示断点信息,可以用help info
查看其支持的子命令
2、set
用set设置环境变量
3、show
用来描述GDB自己的状态,用set修改,如:show radix和set radix ×××
为显示所有可设置的参数及其当前值,可以用show或info set
以下是三个无法用set修改的三个show子命令:
1、show version   GDB版本
2、show copying
   info copying   版权信息
3、show warranty
   info warranty 显示GNU "NO WARRANTY"语句或warranty。

### 回答1: 《debugging with gdb》是本关于使用GDB进行调试的指南。GDB(GNU调试器)是个强大的调试工具,可以用于调试各种编程语言,如C、C++、Fortran等。 这本书详细介绍了GDB的安装和配置,并提供了许多示例来说明如何使用它来调试程序。它从基本的调试命令开始,如设置断点、单步执行、查看变量的值等。然后,它介绍了更高级的调试功能,如条件断点、观察点、跟踪函数调用等。 书中还介绍了如何使用GDB来调试多线程程序和动态库。它解释了如何设置线程断点、查看线程状态和跟踪线程的执行路径。此外,它还介绍了如何对动态链接库进行调试,包括加载和卸载库、查看库中的符号和调用库中的函数等。 此外,《debugging with gdb》还介绍了如何使用GDB进行内存调试。它涵盖了诸如检测内存泄漏、跟踪指针问题和查找内存错误等主题。通过这本书,读者可以学习如何使用GDB来诊断和解决各种程序错误和问题。 总之,《debugging with gdb》是本全面而详细的关于使用GDB进行调试的指南。无论是有经验的开发人员还是初学者,都可以从中学习到如何使用GDB来快速定位和解决程序中的错误。 ### 回答2: GDB个调试器,用于帮助开发者在程序中找出错误并进行调试。它提供了许多功能和命令,可以让开发者在程序运行过程中获取各种有用的信息。 在使用GDB进行调试之前,首先需要将程序编译成可调试的二进制文件。可以使用编译器的参数“-g”来生成包含调试信息的可执行文件。编译完成后,可以通过终端命令"gdb <可执行文件名>"启动GDB,并载入要调试的程序。 旦进入GDB调试界面,可以使用各种命令来控制程序的执行。例如,可以使用"break <函数名>"命令在特定的函数内设置断点,当程序执行到该函数时会触发断点,并暂停程序的执行。可以使用"run"命令来运行程序,当程序遇到断点时会暂停,并在终端显示相关的调试信息。 旦程序暂停在断点处,就可以使用GDB提供的许多命令来检查程序状态和寻找错误。例如,可以使用"print <变量名>"命令来打印特定变量的值,以确定其是否符合预期。还可以使用"step"命令来逐行执行程序,并跟踪程序的执行流程,以查找错误所在。 在调试过程中,还可以使用其他命令来查看函数调用栈,设置条件断点,监视特定变量的值等。通过这些命令的使用,可以逐步分析程序的执行过程,找出其中的问题,并进行修复。 在调试完成后,可以使用"quit"命令退出GDB调试界面。调试信息和步骤可以记录下来并与其他开发者共享,以便更好地协作解决问题。 总之,GDB个功能强大的调试器,它可以帮助开发者定位和修复程序中的错误。通过使用GDB,开发者可以更加高效地进行程序调试,提高开发效率。 ### 回答3: 《debugging with gdb》是本介绍使用GDB进行调试的书籍。GDB是GNU工具链中的个强大的调试工具,用于分析和修复程序中的错误。 该书详细介绍了GDB的各种功能和用法,并通过实例演示了如何利用GDB进行程序调试。它提供了许多实用技巧和建议,帮助读者快速定位和解决程序中的bug。 书中首先介绍了GDB的基本用法,包括启动程序、设置断点、执行程序、查看变量值等。接着,它详细阐述了GDB的高级功能,例如条件断点、观察点、内存调试等。 此外,书中还介绍了GDB调试多线程程序、动态链接程序和嵌入式程序的方法。针对不同的调试需求,它还介绍了GDB的执行控制、堆栈跟踪和源代码级别的调试等高级特性。 《debugging with gdb》还提供了些常见问题的解决方案,如内存泄漏、数组越界、死锁等。它还解释了些常见错误的原因和调试技巧,帮助读者更好地理解和定位程序中的问题。 通过阅读《debugging with gdb》,读者可以更好地理解和掌握GDB的使用方法,提高程序调试的效率和准确性。无论是新手还是有经验的程序员,都可以从中受益,提升自己的调试能力。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值