现在的位置: 首页 > 综合 > 正文

Debugging with GDB学习记录(一)

2013年03月21日 ⁄ 综合 ⁄ 共 6231字 ⁄ 字号 评论关闭

最近使用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。

抱歉!评论已关闭.