GDB调试器用法

简介:

wiki页:http://code.google.com/p/ldd6410/wiki/GDBDebug

gdb调试器用法

不管是调试Linux内核空间的驱动还是调试用户空间的应用程序,掌握gdb的用法都是必须。而且,调试内核和调试应用程序时使用的gdb命令是完全相同的,下面以代码清单22.2的应用程序为例演示gdb调试器的用法。
1  int add(int a, int b)
2  {
3    return a + b;
4  }
5  
6  main()
7  {
8    int sum[10] =
9    {
10     0, 0, 0, 0, 0, 0, 0, 0, 0, 0    
11   }  ;
12   int i;
13  
14   int array1[10] =
15   {
16     48, 56, 77, 33, 33, 11, 226, 544, 78, 90
17   };
18   int array2[10] =
19   {
20     85, 99, 66, 0x199, 393, 11, 1, 2, 3, 4
21   };
22
23   for (i = 0; i < 10; i++)
24   {
25     sum[i] = add(array1[i], array2[i]);
26   }
27 }
[root@localhost driver_study]# gdb gdb_example
GNU gdb
Red Hat Linux (5.3post-0.20021129.18rh)
Copyright 2003 Free Software Foundation, Inc.
GDB
is free software, covered by the GNU General Public License, and you are
welcome to change it
and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB.  Type "show warranty" for details.
This GDB was configured as "i386-redhat-linux-gnu"...
(gdb)

1、list命令

(gdb) list 15
10        
11        int array1[10] =
12        {
13          48, 56, 77, 33, 33, 11, 226, 544, 78, 90
14        };
15        int array2[10] =
16        {
17          85, 99, 66, 0x199, 393, 11, 1, 2, 3, 4
18        };
19
list <function> ,显示函数名为function的函数的源程序,如:
(gdb) list main
2       {
3         return a + b;
4       }
5
6       main()
7       {
8         int sum[10];
9         int i;
10        
11        int array1[10] =
list,显示当前行后面的源程序。 list - ,显示当前行前面的源程序。
(gdb) break add
Breakpoint 1 at 0x80482f7: file gdb_example.c, line 3.
(gdb) run  
Starting program: /driver_study/gdb_example

Breakpoint 1, add (a=48, b=85) at gdb_example.c:3
warning
: Source file is more recent than executable.

3         return a + b;
(gdb) next
4       }
(gdb) next
main
() at gdb_example.c:23
23        for (i = 0; i < 10; i++)
(gdb) next
25          sum[i] = add(array1[i], array2[i]);
(gdb) print sum
$1
= {133, 0, 0, 0, 0, 0, 0, 0, 0, 0}

2、run命令

set args 可指定运行时参数,如:set args 10 20 30 40 50;show args 命令可以查看设置好的运行参数。 path <dir> 可设定程序的运行路径;how paths可查看程序的运行路径;set environment varname [=value]用于设置环境变量,如set env USER=baohua;show environment [varname]则用于查看环境变量。 cd <dir> 相当于shell的cd命令;pwd 显示当前所在的目录。 info terminal 用于显示程序用到的终端的模式;gdb中也可以使用重定向控制程序输出,如run > outfile;tty命令可以指定输入输出的终端设备,如:tty /dev/ttyS1。

3、break命令

在进入指定函数时停住,C++中可以使用class::function或function(type, type)格式来指定函数名。 在指定行号停住。 在当前行号的前面或后面的offset行停住,offiset为自然数。 在源文件filename的linenum行处停住。 在源文件filename的function函数的入口处停住。 在程序运行的内存地址处停住。 break命令没有参数时,表示在下一条指令处停住。 “...”可以是上述的break <linenum>、break +offset / break –offset中的参数,condition表示条件,在条件成立时停住。比如在循环体中,可以设置break if i=100,表示当i为100时停住程序。 查看断点时,可使用info命令,如info breakpoints [n]、info break [n](n表示断点号)。

4、单步命令

(gdb) break 25
Breakpoint 1 at 0x8048362: file gdb_example.c, line 25.
(gdb) run
Starting program: /driver_study/gdb_example

Breakpoint 1, main () at gdb_example.c:25
25          sum[i] = add(array1[i], array2[i]);
(gdb) step
add
(a=48, b=85) at gdb_example.c:3
3         return a + b;
单步跟踪,如果有函数调用,它不会进入该函数。同样地,next后面不加count表示一条条地执行,加表示执行后面的count条指令,然后再停住。 set step-mode on用于打开step-mode模式,这样,在进行单步跟踪时,程序不会因为没有debug信息而不停住,这个参数的设置可便于查看机器码。set step-mod off用于关闭step-mode模式。 运行程序,直到当前函数完成返回,并打印函数返回时的堆栈地址和返回值及参数值等信息。 一直在循环体内执行单步,退不出来是一件令人烦恼的事情,until命令可以运行程序直到退出循环体。 stepi和nexti用于单步跟踪一条机器指令,一条程序代码有可能由数条机器指令完成,stepi和nexti可以单步执行机器指令。 另外,运行“display/i $pc”命令后,单步跟踪会在打出程序代码的同时打出机器指令,即汇编代码。

5、continue命令

continue [ignore-count]
c
[ignore-count]
fg
[ignore-count]
(gdb) continue
Continuing.
Hardware watchpoint 3: i

Old value = 2
New value = 3
0x0804838d in main () at gdb_example.c:23
23        for (i = 0; i < 10; i++)
(gdb) continue
Continuing.

Breakpoint 1, main () at gdb_example.c:25
25          sum[i] = add(array1[i], array2[i]);
(gdb) continue
Continuing.
Hardware watchpoint 3: i

Old value = 3
New value = 4
0x0804838d in main () at gdb_example.c:23
23        for (i = 0; i < 10; i++)

6、print命令

 print <expr>
 
print /<f> <expr>
<expr>是表达式,是被调试的程序中的表达式,<f>是输出的格式,比如,如果要把表达式按16进制的格式输出,那么就是/x。在表达式中,有几种GDB所支持的操作符,它们可以用在任何一种语言中,“@”是一个和数组有关的操作符,“::”指定一个在文件或是函数中的变量,“{<type>} <addr>”表示一个指向内存地址<addr>的类型为type的一个对象。
(gdb) print sum
$2
= {133, 155, 0, 0, 0, 0, 0, 0, 0, 0}
(gdb) next

Breakpoint 1, main () at gdb_example.c:25
25          sum[i] = add(array1[i], array2[i]);
(gdb) next
23        for (i = 0; i < 10; i++)
(gdb) print sum
$3
= {133, 155, 143, 0, 0, 0, 0, 0, 0, 0}
int *array = (int *) malloc (len * sizeof (int));
p *array@len
我们可用display命令设置一些自动显示的变量,当程序停住时,或是单步跟踪时,这些变量会自动显示。 如果要修改变量,如x的值,可使用如下命令:
print x=4

7、watch命令

(gdb) watch i
Hardware watchpoint 3: i
(gdb) next
23        for (i = 0; i < 10; i++)
(gdb) next
Hardware watchpoint 3: i

Old value = 0
New value = 1
0x0804838d in main () at gdb_example.c:23
23        for (i = 0; i < 10; i++)
(gdb) next

Breakpoint 1, main () at gdb_example.c:25
25          sum[i] = add(array1[i], array2[i]);
(gdb) next
23        for (i = 0; i < 10; i++)
(gdb) next
Hardware watchpoint 3: i

Old value = 1
New value = 2
0x0804838d in main () at gdb_example.c:23
23        for (i = 0; i < 10; i++)

8、examine命令

x/<n/f/u> <addr> 
<addr>表示一个内存地址。“x/”后 的n、f、u都是可选的参数,n 是一个正整数,表示显示内存的长度,也就是说从当前地址向后显示几个地址的内容;f 表示显示的格式,如果地址所指的是字符串,那么格式可以是s,如果地址是指令地址,那么格式可以是i;u 表示从当前地址往后请求的字节数,如果不指定的话,GDB默认是4字节。u参数可以被一些字符代替:b表示单字节,h表示双字节,w表示四字节,g表示八 字节。当我们指定了字节长度后,GDB会从指定的内存地址开始,读写指定字节,并把其当作一个值取出来。n、f、u这3个参数可以一起使用,例如命令“x/3uh 0x54320”表示从内存地址0x54320开始以双字节为1个单位(h)、16进制方式(u)显示3个单位(3)的内存。

9、jump命令

一般来说,被调试程序会按照程序代码的运行顺序依次执行,但是GDB也提供了乱序执行的功能,也就是说,GDB可以修改程序的执行顺序,从而让程序随意跳跃。这个功能可以由GDB的jump命令: jump <linespec> 来指定下一条语句的运行点。<linespec>可以是文件的行号,可以是file:line格式,也可以是+num这种偏移量格式,表示下一条运行语句从哪里开始。 jump <address> 这里的<address>是代码行的内存地址。 注意,jump命令不会改变当前的程序栈中的内容,所以,如果使用jump从一个函数跳转到另一个函数,当跳转到的函数运行完返回,进行出栈操作时必然会发生错误,这可能导致意想不到的结果,所以最好只用jump在同一个函数中进行跳转。

10、signal命令

11、return命令

return
return <expression>

12、call命令

13、info命令

info命令可以在调试时用来查看寄存器、断点、观察点和信号等信息。要查看寄存器的值,可以使用如下命令: info registers (查看除了浮点寄存器以外的寄存器) info all-registers (查看所有寄存器,包括浮点寄存器) info registers <regname ...> (查看所指定的寄存器) 要查看断点信息,可以使用如下命令: info break 列出当前所设置的所有观察点,使用如下命令: info watchpoints 查看有哪些信号正在被GDB检测,使用如下命令: info signals info handle 也可以使用info line命令来查看源代码在内存中的地址。info line后面可以跟行号、函数名、文件名:行号、文件名:函数名等多种形式,例如下面的命令会打印出所指定的源码在运行时的内存地址:
info line tst.c:func

14、disassemble

(gdb) disassemble func
Dump of assembler code for function func:
0x8048450 <func>:       push   %ebp
0x8048451 <func+1>:     mov    %esp,%ebp
0x8048453 <func+3>:     sub    $0x18,%esp
0x8048456 <func+6>:     movl   $0x0,0xfffffffc(%ebp)
...

End of assembler dump.



本文转自 21cnbao 51CTO博客,原文链接:http://blog.51cto.com/21cnbao/223565,如需转载请自行联系原作者





相关实践学习
阿里云图数据库GDB入门与应用
图数据库(Graph Database,简称GDB)是一种支持Property Graph图模型、用于处理高度连接数据查询与存储的实时、可靠的在线数据库服务。它支持Apache TinkerPop Gremlin查询语言,可以帮您快速构建基于高度连接的数据集的应用程序。GDB非常适合社交网络、欺诈检测、推荐引擎、实时图谱、网络/IT运营这类高度互连数据集的场景。 GDB由阿里云自主研发,具备如下优势: 标准图查询语言:支持属性图,高度兼容Gremlin图查询语言。 高度优化的自研引擎:高度优化的自研图计算层和存储层,云盘多副本保障数据超高可靠,支持ACID事务。 服务高可用:支持高可用实例,节点故障迅速转移,保障业务连续性。 易运维:提供备份恢复、自动升级、监控告警、故障切换等丰富的运维功能,大幅降低运维成本。 产品主页:https://www.aliyun.com/product/gdb
相关文章
|
2月前
|
NoSQL Linux 程序员
Linux:gdb调试器的解析+使用(超详细版)
Linux:gdb调试器的解析+使用(超详细版)
75 1
|
8天前
|
NoSQL IDE Linux
Linux的学习之路:8、Linux调试器-gdb使用
Linux的学习之路:8、Linux调试器-gdb使用
19 0
|
NoSQL Linux 编译器
【Linux】——调试器-gdb的使用
【Linux】——调试器-gdb的使用
|
3月前
|
NoSQL Linux C语言
【Linux】Linux调试器-gdb使用
【Linux】Linux调试器-gdb使用
【Linux】Linux调试器-gdb使用
|
3月前
|
NoSQL Linux 编译器
【Linux工具篇】调试器gdb
【Linux工具篇】调试器gdb
24 0
|
4月前
|
NoSQL 编译器 Linux
Linux——编译器gcc/g++、调试器gdb以及自动化构建工具makefile&&make详解
Linux——编译器gcc/g++、调试器gdb以及自动化构建工具makefile&&make详解
|
4月前
|
NoSQL Linux C语言
调试器gdb
调试器gdb
48 0
|
5月前
|
监控 NoSQL Linux
3.6、linux调试器:gdb
3.6、linux调试器:gdb
35 0
|
5月前
|
NoSQL IDE Linux
《Linux从练气到飞升》No.09 Linux调试器-gdb使用
《Linux从练气到飞升》No.09 Linux调试器-gdb使用
37 0
《Linux从练气到飞升》No.09 Linux调试器-gdb使用
|
5月前
|
NoSQL Linux C语言
Linux调试器:gdb的使用
Linux调试器:gdb的使用