关于
使用gcc
或g++
编译程序时加上-g
参数即可将调试信息加入生成的目标文件,否则使用gdb调试时函数名、变量名都只能显示内存地址。直接运行gdb
即可进入gdb,然后输入file a.out
即可开始调试a.out,当然也可以直接gdb a.out
进入a.out
的调试状态。可以使用在命令行状态下使用gdb -help
来查看帮助,当然也可以用man。在gdb调试状态下使用help可心获得更强大的帮助,类似vim中的帮助,gdb调试状态下使用help step
即可查看单步调试相关的帮助。gdb状态下使用quit
退出gdb。进入GDB时可以使用可选参数-tui
进入GDB的文本用户界面,该界面可以分屏显示源代码及断点所在行,比使用list查看代码方便很多,而且支持使用上下键来滚动显示代码,此时的命令行历史切换需要使用ctrl+n和ctrl+p。当然有一些支持GDB调试的图形软件ddd和code::block。
GDB基本用法
$gdb app -tui
:进入调试状态
选择一种方式进入gdb,例如$gdb app -tui
或者$gdb -tui
和(gdb)file app
,当然也可以执行程序之后再启动gdb,然后使用指定pid的方式 调试,此处$
和(gdb)
分别表示bash上的命令行前导符和gdb运行时的前导符(gdb)break main
或(gdb)b N
:添加断点
在main函数所在行添加断点,当然可以使用(gdb)b 20
在第20行添加断点。(gdb)run args-list
:运行调试程序
运行程序,run后面可以跟想要传递给所有调试的程序的参数列表。当然可以(gdb)r
,即没有输入参数直接运行到断点处(gdb)list n1,n2
:显示被调试程序源代码
显示n1到n2行之间的程序源码。或者(gdb)l
显示当前行和其后10行的代码(gdb)next N
或者(gdb)step N
:单步执行
next将单步执行,一次运行N行,当然省略N则表示一次一行,如果当前行是一个函数,next会直接一次运行完该函数,然后继续进入下一行。而step则是单步进入执行,一次执行一行,遇到函数也会进入函数内部执行,遇到对象转到相应类的构造函数。当然这两个命令可以省略为n和s,也可以直接回车表示执行一次的命令。(gdb)finish
或(gdb)until
:跳出当前函数或循环体
finish执行完当前函数后返回到调用它的函数,并给出函数返回值。例如使用step时,想跳出当前函数即可以使用finish。until在循环开始处使用会直接执行完整个循环体。(gdb)print var
或(gdb)print var=5
:显示变量var的值,或将变量var的值修改为5
print后面可以是变量名也可以是函数名,还可以是历史记录,当然可以省略为p,可以显示var的状态信息,并且存放在历史记录中。历史记录以$
开头,形如$7
,使用(gdb)p $7
,即可以显示$7
中的内容。(gdb)info breakpoints
和(gdb)delete N
:显示所以断点和删除断点号为N的断点
可以省略为(gdb)i b
和(gdb)d N
(gdb)watch var
和(gdb)info watch
:监视变量var的值和查看当前所有监视信息
当变量var的值变化时显示var的值并暂停程序执行,后面一个命令可以省略为i watch
,显示的信息也会跟i b
一样带有一个序号,可以使用d N
来删除监视对象(gdb)continue
和kill
:继续运行程序到下一个断点处和停止本次调试
以下是GDB详细用法:
GDB重要提示
- 首先编译时必须带上参数
-g
,如g++ a.cpp -o a -g -std=c++11
,这样才能在可执行程序中生成调试信息,以供GDB使用 - 不能使用编译优化参数,例如
-O
或者-O2
,由于这些优化参数为了提高性能会重新安排程序执行操作,导致调试信息与源码不匹配 - GDB内部可以使用
! command
或shell command
来执行shell命令 - GDB内部可以使用
TAB
键进行自动补全,例如info bre
+TAB会自动输入命令info breakpoints
- GDB内部可以使用很多缩写,只要缩写的匹配是唯一的,例如
info bre
+回车,相当于执行了info breakpoints
+回车 - GDB内部使用
ctrl+c
可以在当前位置处暂停执行正在执行的程序,例如当循环很大或者死循环时又不想退出调试时
GDB传递命令行参数
gdb test
进入调试之后
可以使用以下两种方法输入命令行参数:
run <命令行参数>
set args
<命令行参数>`
GDB所有可用的命令行参数
调试可执行程序
1 | gdb <name-of-excutable> |
调试带有core文件的可执行程序
1 | gdb -e <name-of-excutable> -c <name-of-core-file> |
调试进程
1 | gdb <name-of-excutable> --pid=<process-id> # 或者 gdb <name-of-excutable> -p [pid] |
可以使用ps -auxw
来列出当前正在运行的进程,或者直接pgrep <进程名>
调试多线程info threads
显示当前可调试的所有线程,每个线程会有一个GDB为其分配的ID,后面操作线程的时候会用到这个ID。 前面有*的是当前调试的线程。
thread ID
切换当前调试的线程为指定ID的线程。
break thread_test.c:123 thread all
在所有线程中相应的行上设置断点
thread apply ID1 ID2 command
让一个或者多个线程执行GDB命令command。
thread apply all command
让所有被调试线程执行GDB命令command。
set scheduler-locking off|on|step
估计是实际使用过多线程调试的人都可以发现,在使用step或者continue命令调试当前被调试线程的时候,
其他线程也是同时执行的,怎么只让被调试程序执行呢?通过这个命令就可以实现这个需求。off 不锁定任何线程,也就是所有线程都执行,这是默认值。 on 只有当前被调试程序会执行。 step 在单步的时候,除了next过一个函数的情况(熟悉情况的人可能知道,这其实是一个设置断点然后continue的行为)以外,只有当前线程会执行。
调试多进程
使用gdb调试多进程时,如果想要在进程间进行切换,那么就需要在fork调用前设置: set detach-on-fork off
,然后使用 info inferiors
来查看进程信息,得到的信息可以看到最前面有一个进程编号,使用 inferior num
来进行进程切换。
那么为什么要使用 set detache-on-fork off
呢?它的意思是在调用fork后相关进程的运行行为是怎么样的,是detache on/off
也就是说分离出去独立运行,不受gdb控制还是不分离,被阻塞住。
这里还涉及到一个设置 set follow-fork-mode [parents/child]
,就是fork之后,gdb的控制落在谁身上,如果是父进程,那么分离的就是子进程,反之亦然。如果detache-on-fork
被off了,那么未受控的那个进程就会被阻塞住,进程状态为T,即处于调试状态。
GDB可选的命令行参数: (version 6. 老版本使用一个短划线 "-")
-
Option Description --help
-hList command line arguments --exec=file-name
-e file-nameIdentify executable associated with core file. --core=name-of-core-file
-c name-of-core-fileSpecify core file. --command=command-file
-x command-fileFile listing GDB commands to perform. Good for automating set-up. --directory=directory
-d directoryAdd directory to the path to search for source files. --cd=directory Run GDB using specified directory as the current working directory. --nx
-nDo not execute commands from ~/.gdbinit initialization file. Default is to look at this file and execute the list of commands. --batch -x command-file Run in batch (not interactive) mode. Execute commands from file. Requires -x option. --symbols=file-name
-s file-nameRead symbol table from file file. --se=file-name Use FILE as symbol file and executable file. --write Enable writing into executable and core files. --quiet
-qDo not print the introductory and copyright messages. --tty=device Specify device for running program's standard input and output. --tui Use a terminal user interface. Console curses based GUI interface for GDB. Generates a source and debug console area. --pid=process-id
-p process-idSpecify process ID number to attach to. --version Print version information and then exit.
GDB常用调试命令
GDB运行时在GDB内部使用的命令
帮助和查看信息命令
Command | Description |
---|---|
help | List gdb command topics. |
help topic-classes | List gdb command within class. |
help command | Command description. eg help show to list the show commands |
apropos search-word | Search for commands and command topics containing search-word. |
info args i args |
List program command line arguments |
info breakpoints | List breakpoints |
info break | List breakpoint numbers. |
info break breakpoint-number | List info about specific breakpoint. |
info watchpoints | List breakpoints |
info registers | List registers in use |
info threads | List threads in use |
info set | List set-able option |
断点和监视命令
Break and Watch | |
---|---|
break funtion-name break line-number break ClassName::functionName |
Suspend program at specified function of line number. |
break +offset break -offset |
Set a breakpoint specified number of lines forward or back from the position at which execution stopped. |
break filename:function | Don't specify path, just the file name and function name. |
break filename:line-number | Don't specify path, just the file name and line number. break Directory/Path/filename.cpp:62 |
break *address | Suspend processing at an instruction address. Used when you do not have source. |
break line-number if condition | Where condition is an expression. i.e. x > 5 Suspend when boolean expression is true. |
break line thread thread-number | Break in thread at specified line number. Use info threads to display thread numbers. |
tbreak | Temporary break. Break once only. Break is then removed. See "break" above for options. |
watch condition | Suspend processing when condition is met. i.e. x > 5 |
clear clear function clear line-number |
Delete breakpoints as identified by command option. Delete all breakpoints in function Delete breakpoints at a given line |
delete d |
Delete all breakpoints, watchpoints, or catchpoints. |
delete breakpoint-number delete range |
Delete the breakpoints, watchpoints, or catchpoints of the breakpoint ranges specified as arguments. |
disable breakpoint-number-or-range enable breakpoint-number-or-range |
Does not delete breakpoints. Just enables/disables them. Example: Show breakpoints: info break Disable: disable 2-9 |
enable breakpoint-number once | Enables once |
continue c |
Continue executing until next break point/watchpoint. |
continue number | Continue but ignore current breakpoint number times. Usefull for breakpoints within a loop. |
finish | Continue to end of function. |
单步执行相关命令
Line Execution | |
---|---|
step s step number-of-steps-to-perform |
Step to next line of code. Will step into a function. |
next n next number |
Execute next line of code. Will not enter functions. |
until until line-number |
Continue processing until you reach a specified line number. Also: function name, address, filename:function or filename:line-number. |
info signals info handle handle SIGNAL-NAME option |
Perform the following option when signal recieved: nostop, stop, print, noprint, pass/noignore or nopass/ignore |
where | Shows current line number and which function you are in. |
查看堆栈信息命令
Stack | |
---|---|
backtrace bt bt inner-function-nesting-depth bt -outer-function-nesting-depth |
Show trace of where you are currently. Which functions you are in. Prints stack backtrace. |
backtrace full | Print values of local variables. |
frame frame number f number |
Show current stack frame (function where you are stopped) Select frame number. (can also user up/down to navigate frames) |
up down up number down number |
Move up a single frame (element in the call stack) Move down a single frame Move up/down the specified number of frames in the stack. |
info frame | List address, language, address of arguments/local variables and which registers were saved in frame. |
info args info locals info catch |
Info arguments of selected frame, local variables and exception handlers. |
查看源代码相关信息命令
Source Code | |
---|---|
list l list line-number list function list - list start#,end# list filename:function |
List source code. |
set listsize count show listsize |
Number of lines listed when list command given. |
directory directory-name dir directory-name show directories |
Add specified directory to front of source code path. |
directory | Clear sourcepath when nothing specified. |
查看机器代码相关命令
Machine Language | |
---|---|
info line info line number |
Displays the start and end position in object code for the current line in source. Display position in object code for a specified line in source. |
disassemble 0xstart 0xend | Displays machine code for positions in object code specified (can use start and end hex memory values given by the info line command. |
stepi si nexti ni |
step/next assembly/processor instruction. |
x 0xaddress x/nfu 0xaddress |
Examine the contents of memory. Examine the contents of memory and specify formatting.
|
测试变量信息的相关命令
Examine Variables | |
---|---|
print variable-name p variable-name p file-name::variable-name p 'file-name'::variable-name |
Print value stored in variable. |
p *array-variable@length | Print first # values of array specified by length. Good for pointers to dynamicaly allocated memory. |
p/x variable | Print as integer variable in hex. |
p/d variable | Print variable as a signed integer. |
p/u variable | Print variable as a un-signed integer. |
p/o variable | Print variable as a octal. |
p/t variable x/b address x/b &variable |
Print as integer value in binary. (1 byte/8bits) |
p/c variable | Print integer as character. |
p/f variable | Print variable as floating point number. |
p/a variable | Print as a hex address. |
x/w address x/4b &variable |
Print binary representation of 4 bytes (1 32 bit word) of memory pointed to by address. |
ptype variable ptype data-type |
Prints type definition of the variable or declared variable type. Helpful for viewing class or struct definitions while debugging. |
测试GDB模式的命令
GDB Modes | |
---|---|
set gdb-option value | Set a GDB option |
set logging on set logging off show logging set logging file log-file |
Turn on/off logging. Default name of file is gdb.txt |
set print array on set print array off show print array |
Default is off. Convient readable format for arrays turned on/off. |
set print array-indexes on set print array-indexes off show print array-indexes |
Default off. Print index of array elements. |
set print pretty on set print pretty off show print pretty |
Format printing of C structures. |
set print union on set print union off show print union |
Default is on. Print C unions. |
set print demangle on set print demangle off show print demangle |
Default on. Controls printing of C++ names. |
启动和停止的相关命令
Start and Stop | |
---|---|
run r run command-line-arguments run < infile > outfile |
Start program execution from the beginning of the program. The command break main will get you started. Also allows basic I/O redirection. |
continue c |
Continue execution to next break point. |
kill | Stop program execution. |
quit q |
Exit GDB debugger. |
参考
主要参考资料: