gdb调试用命令与一般调试方法


示例代码

 1 #include 
 2 using namespace std;
 3 
 4 void Print()
 5 {
 6     cout<<"helloworld"<<endl;
 7 }
 8  
 9 class TestDebug
10 {
11 public:
12     TestDebug()
13     {
14         cout<<"TestDebug"<<endl;
15         int temp=0;
16         ti = 0;
17         while(1)//调试自动变量
18         {
19             if(++temp==10)
20                 break;
21         }
22         ti = temp;
23     }
24 
25     void disPlayTi()
26     {
27         cout<<"ti:"<endl;
28     }
29 
30 private:
31     int ti;
32 };
33 
34 
35 int main() {
36  
37     Print();
38     TestDebug tg;
39     tg.disPlayTi();
40     return 0;
41 }

 

使用gdb调试程序的前提是在编译程序时使用gcc -g的选项,这样才能在程序中生成调试相关的信息。下面我们就使用上面的示例代码来调试程序。

 

生成可调试程序

keqin@ubuntu:~/Test$ gcc -g hello.cpp -o hello -lstdc++

 

 

 

启动调试——gdb + 程序名

keqin@ubuntu:~/Test$ gdb hello 

#有时程序运行需要外设参数也就是main(int argc,char **argv)中的参数,可以使用 gdb --args +程序名 argv1 argv2 

启动成功后,对应如下输出,"(gdb)"开头标志着进入了可调式模式。

GNU gdb (Ubuntu 7.11.1-0ubuntu1~16.04) 7.11.1
Copyright (C) 2016 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later //gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
//www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
//www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from hello...done.
(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
support -- Support facilities
tracepoints -- Tracing of program execution without stopping the program
user-defined -- User-defined commands

Type "help" followed by a class name for a list of commands in that class.
Type "help all" for the list of all commands.
Type "help" followed by command name for full documentation.
Type "apropos word" to search for commands related to "word".
Command name abbreviations are allowed if unambiguous.

输入help + command可以获取到某个命令的详细帮助信息,如输入help break来查看如何添加断点。其输出类似于Linux的man帮助

gdb) help break
Set breakpoint at specified location.
break [PROBE_MODIFIER] [LOCATION] [thread THREADNUM] [if CONDITION]
PROBE_MODIFIER shall be present if the command is to be placed in a
probe point.  Accepted values are `-probe' (for a generic, automatically
guessed probe type), `-probe-stap' (for a SystemTap probe) or 
`-probe-dtrace' (for a DTrace probe).
LOCATION may be a linespec, address, or explicit location as described
below.

With no LOCATION, uses current execution address of the selected
stack frame.  This is useful for breaking on return to a stack frame.

THREADNUM is the number from "info threads".
CONDITION is a boolean expression.
;
Linespecs are colon-separated lists of location parameters, such as
source filename, function name, label name, and line number.
Example: To specify the start of a label named "the_top" in the
function "fact" in the file "factorial.c", use
"factorial.c:fact:the_top".

Address locations begin with "*" and specify an exact address in the
program.  Example: To specify the fourth byte past the start function
"main", use "*main + 4".

---Type  to continue, or q  to quit---

 例如:

 

添加断点:

下面列举一些打断点的方式

break + 函数名

(gdb) break Print() 
Breakpoint 1 at 0x40090a: file hello.cpp, line 6.

break +文件名:函数名

 (gdb) break hello.cpp:Print()
 Note: breakpoint 1 also set at pc 0x40090a.
 Breakpoint 2 at 0x40090a: file hello.cpp, line 6.

 

break 文件名:行号

(gdb) break hello.cpp:39
Breakpoint 6 at 0x400951: file hello.cpp, line 39.

 

 

调试类中的成员函数

(gdb) break TestDebug #按Tab键补全
TestDebug               TestDebug::TestDebug()  TestDebug::disPlayTi()  
(gdb) break TestDebug::TestDebug() 
Breakpoint 3 at 0x4009d8: file hello.cpp, line 14.

 

执行调试(run)

(gdb) run
Starting program: /home/guilin/Test/hello 

Breakpoint 1, Print () at hello.cpp:6
6           cout<<"helloworld"<

 

继续运行到下个断点(continue)

(gdb) continue
Continuing.
helloworld

Breakpoint 3, TestDebug::TestDebug (this=0x7fffffffe1d0) at hello.cpp:14
14              cout<<"TestDebug"<

//如果感觉断点不够,调试过程可以继续添加加断点。

 

 

打印变量值(print)

出于调试需要,有时候我们需要查看某个变量的值。

(gdb) print temp
$1 = 0

 

监视某个变量(watch)——调试过程中,变量数据发生变化会自动停下来。

(gdb) break 14      #先打断点
Breakpoint 20 at 0x4009d8: file hello.cpp, line 14.
(gdb) run       #运行程序
Starting program: /home/guilin/Test/hello 
helloworld

Breakpoint 20, TestDebug::TestDebug (this=0x7fffffffe1a0) at hello.cpp:14
14              cout<<"TestDebug"<<endl;
(gdb) watch temp   #调试成中添加监控变量
Hardware watchpoint 21: temp
(gdb) continue     #继续执行
Continuing.
TestDebug

Hardware watchpoint 21: temp

Old value = 0     #变量旧值
New value = 1     #变量新值 
0x0000000000400a09 in TestDebug::TestDebug (this=0x7fffffffe1a0) at hello.cpp:19
19                  if(++temp==10)

 

 

 

添加条件断点:

我们有时需程序自动运行到某个临界条件而在此条件满足之前不去调试它,这时可以使用条件断点。

gdb)break hello.cpp:39 if temp>8 #当TestDebug::TestDebug 中temp>8时才中止运行 
Note: breakpoint 3 also set at pc 0x4009d8. Breakpoint 32 at 0x4009d8: file hello.cpp, line 19.

 

单步调试(next)——一般对应IDE中的F10

(gdb) next  
helloworld
38          TestDebug tg;
(gdb) next
TestDebug
39          tg.disPlayTi();

 

单步进入(step)——一般对应IDE中的F11

Breakpoint 9, main () at hello.cpp:37
37          Print();
(gdb) step  #调试时会进入到函数内部
Print () at hello.cpp:6
6           cout<<"helloworld"<<endl;
(gdb) 

 

 

执行到下个断点(continue)——一般对应IDE中F5

(gdb) continue 
Continuing.
TestDebug

Breakpoint 31, TestDebug::TestDebug (this=0x7fffffffe1d0) at hello.cpp:16
16              ti = 0;    
(gdb) print temp
$2 = 0

 

修改变量值(set var 变量名=value)

有时候有些有异常处理的分支无法进入,或者我们想提前到达某个临界条件。可以去直接修改变量的值以达到目的。

(gdb) run
Starting program: /home/guilin/Test/hello 
helloworld

Breakpoint 20, TestDebug::TestDebug (this=0x7fffffffe1a0) at hello.cpp:14
14              cout<<"TestDebug"<<endl;
(gdb) watch temp
Hardware watchpoint 22: temp
(gdb) c
Continuing.
TestDebug

Hardware watchpoint 22: temp

Old value = 0
New value = 1
0x0000000000400a09 in TestDebug::TestDebug (this=0x7fffffffe1a0) at hello.cpp:19
19                  if(++temp==10)
(gdb) set var temp=9
(gdb) c
Continuing.

Hardware watchpoint 22: temp

Old value = 9
New value = 10
0x0000000000400a09 in TestDebug::TestDebug (this=0x7fffffffe1a0) at hello.cpp:19
19                  if(++temp==10)

 

查看堆栈调用(backtrace)

(gdb) backtrace  #简写为bt
#0  main () at hello.cpp:39

 

清除断点:

clear 

用法与break类似,如何创建,如何删除。

delete

delete(删除所有断点)

(gdb) delete
Delete all breakpoints? (y or n)