gdb的命令 _VMware, Unix及操作系统讨论区_Weblogic技术|Tuxedo技术|中间件技术|Oracle论坛|JAVA论坛|Linux/Unix技术|hadoop论坛_联动北方技术论坛  
网站首页 | 关于我们 | 服务中心 | 经验交流 | 公司荣誉 | 成功案例 | 合作伙伴 | 联系我们 |
联动北方-国内领先的云技术服务提供商
»  游客             当前位置:  论坛首页 »  自由讨论区 »  VMware, Unix及操作系统讨论区 »
总帖数
9
每页帖数
101/1页1
返回列表
0
发起投票  发起投票 发新帖子
查看: 5600 | 回复: 8   主题: gdb的命令         上一篇   下一篇 
jun.zhang
注册用户
等级:上士
经验:278
发帖:76
精华:0
注册:2011-12-27
状态:离线
发送短消息息给jun.zhang 加好友    发送短消息息给jun.zhang 发消息
发表于: IP:您无权察看 2016-3-28 18:13:22 | [全部帖] [楼主帖] 楼主

   GDB的命令很多,本文不会全部介绍,仅会介绍一些最常用的。在介绍之前,先介绍GDB中的一个非常有用的功能:补齐功能。它就如同Linux下 SHELL中的命令补齐一样。当你输入一个命令的前几个字符,然后输入TAB键,如果没有其它命令的前几个字符与此相同,SHELL将补齐此命令。如果有其它命令的前几个字符与此相同,你会听到一声警告声,再输入TAB键,SHELL将所有前几个字符与此相同的命令全部列出。而GDB中的补齐功能不仅能补齐GDB命令,而且能补齐参数。

   本文将先介绍常用的命令,然后结合一个具体的例子来演示如何实际使用这些命令。下面的所有命令除了第一条启动GDB命令是在SHELL下输入的,其余都是GDB内的命令。大部分GDB内的命令都可以仅输入前几个字符,只要不与其它指令冲突。如quit可以简写为q,因为以q打头的命令只有quit。 List可以简写为l,等等。

1. 启动GDB

   你可以输入GDB来启动GDB程序。 GDB程序有许多参数,在此没有必要详细介绍,但一个最为常用的还是要介绍的:如果你已经编译好一个程序,我们假设文件名为hello,你想用GDB调试它,可以输入gdb hello来启动GDB并载入你的程序。如果你仅仅启动了GDB,你必须在启动后,在GDB中再载入你的程序。

2. 载入程序 === file

   在GDB内,载入程序很简单,使用file命令。如file hello。当然,程序的路径名要正确。

退出GDB === quit

在GDB的命令方式下,输入quit,你就可以退出GDB。你也可以输入'C-d'来退出GDB。

3. 运行程序 === run

   当你在GDB中已将要调试的程序载入后,你可以用run命令来执行。如果你的程序需要参数,你可以在run指令后接着输入参数,就象你在SHELL下执行一个需要参数的命令一样。

4. 查看程序信息 === info

   info指令用来查看程序的信息,当你用help info查看帮助的话,info指令的参数足足占了两个屏幕,它的参数非常多,但大部分不常用。我用info指令最多的是用它来查看断点信息。

4.1 查看断点信息

   info br

   br是断点break的缩写,记得GDB的补齐功能吧。用这条指令,你可以得到你所设置的所有断点的详细信息。包括断点号,类型,状态,内存地址,断点在源程序中的位置等。

4.2 查看当前源程序

   info source

4.3 查看堆栈信息

   info stack

用这条指令你可以看清楚程序的调用层次关系。

4.4 查看当前的参数

   info args

5. 列出源一段源程序 === list

5.1 列出某个函数

   list FUNCTION

5.2 以当前源文件的某行为中间显示一段源程序

   list LINENUM

5.3 接着前一次继续显示

   list

5.4 显示前一次之前的源程序

   list -

5.5 显示另一个文件的一段程序

   list FILENAME:FUNCTION 或 list FILENAME:LINENUM

6. 设置断点 === break

   现在我们将要介绍的也许是最常用和最重要的命令:设置断点。无论何时,只要你的程序已被载入,并且当前没有正在运行,你就能设置,修改,删除断点。设置断点的命令是break。有许多种设置断点的方法。如下:

6.1 在函数入口设置断点

   break FUNCTION

6.2 在当前源文件的某一行上设置断点

   break LINENUM

6.3 在另一个源文件的某一行上设置断点

   break FILENAME:LINENUM

6.4 在某个地址上设置断点,当你调试的程序没有源程序是,这很有用

   break *ADDRESS

   除此之外,设置一个断点,让它只有在某些特定的条件成立时程序才会停下,我们可以称其为条件断点。这个功能很有用,尤其是当你要在一个程序会很多次执行到的地方设置断点时。如果没有这个功能,你必须有极大的耐心,加上大量的时间,一次一次让程序断下,检查一些值,接着再让程序继续执行。事实上,大部分的断下并不是我们所希望的,我们只希望在某些条件下让程序断下。这时,条件断点就可以大大提高你的效率,节省你的时间。条件断点的命令如下,在后面的例子中会有示例。

6.5 条件断点

   break ...if COND

7. 其它断点操作

   GDB给每个断点赋上一个整数数字,这个数字在操作断点时起到重要作用,它实际上就代表相应的断点。GDB中的断点有四种状态:

   有效(Enabled)

   禁止(Disabled)

   一次有效(Enabled once)

   有效后删除(Enabled for deletion)

   在上面的四个状态有效和禁止都很好理解,禁止就是让断点暂时失效。一次有效就是当程序在此断点断下后,断点状态自动变为禁止状态。有效后删除就是当程序在此断点断下后,断点被删除。实际上,后两种状态一般不会碰到。

    当你设置一个断点后,它的确省状态是有效。你可以用enable和disable指令来设置断点的状态为有效或禁止。例如,如果你想禁止2号断点,可以用下面的指令:

   disable 2

   相应的,如果想删除2号断点,可以有下面的指令:

   delete 2

8. 设置监视点 === watch

    当你调试一个很大的程序,并且在跟踪一个关键的变量时,发现这个变量不知在哪儿被改动过,如何才能找到改动它的地方。这时你可以使用watch命令。简单地说,监视点可以让你监视某个表达式或变量,当它被读或被写时让程序断下。watch命令的用法如下:

   watch EXPRESSION

    watch指令是监视被写的,当你想监视某个表达式或变量被读的话,需要使用rwatch指令,具体用法是一样的。要注意的是,监视点有硬件和软件两种方式,如果可能Linux尽可能用硬件方式,因为硬件方式在速度上要大大快于软件方式。软件方式由于要在每次执行一条指令后都要检查所要监视的值是否被改变,因此它的执行速度会大大降低。同时它也无法设置成被读时让程序断下,因为读操作不会改变值,所以GDB无法检测到读操作。幸运的是,目前的PC机基本都支持硬件方式。如果你想确认一下你的机器是否支持硬件,你可以在调试程序时用watch设置一个监视点,如果GDB向你显示:

   Hardware watchpoint NUM: EXPR

9. 检查数据

   最常用的检查数据的方法是使用print命令。

   print exp

   print指令打印exp表达式的值。却省情况下,表达式的值的打印格式依赖于它的数据类型。但你可以用一个参数/F来选择输出的打印格式。F是一个代表某种格式的字母,详细可参考输出格式一节。表达式可以是常量,变量,函数调用,条件表达式等。但不能打印宏定义的值。表达式exp中的变量必须是全局变量或当前堆栈区可见的变量。否则GDB会显示象下面的一条信息:

   No symbol "varible" in current context

10. 修改变量值

   在调试程序时,你可能想改变一个变量的值,看看在这种情况下会发生什么。用set指令可以修改变量的值:

   set varible=value

  例如你想将一个变量tmp的值赋为10,

  set tmp=10

11. 检查内存值

   检查内存值的指令是x,x是examine的意思。用法如下:

   x /NFU ADDR

   其中N代表重复数,F代表输出格式(见2.13),U代表每个数据单位的大小。U可以去如下值:

   b :字节(byte)

   h :双字节数值

   w :四字节数值

   g :八字节数值

   因此,上面的指令可以这样解释:从ADDR地址开始,以F格式显示N个U数值。例如:

    x/4ub 0x4000

   会以无符号十进制整数格式(u)显示四个字节(b),0x4000,0x4001,0x4002,0x4003。

12. 输出格式

    缺省情况下,输出格式依赖于它的数据类型。但你可以改变输出格式。当你使用print命令时,可以用一个参数/F来选择输出的打印格式。F可以是以下的一些值:

   'x' 16进制整数格式

   'd' 有符号十进制整数格式

   'u' 无符号十进制整数格式

   'f' 浮点数格式

13.单步执行指令

   单步执行指令有两个step和next。Step可以让你跟踪进入一个函数,而next指令则不会进入函数。

14. 继续执行指令

   当程序被断下后,你查看了所需的信息后,你会希望程序执行下去,输入 continue, 程序会继续执行下去。

15. 帮助指令help

   在GDB中,如果想知道一条指令的用法,最方便的方法是使用help。使用方法很简单,在help后跟上指令名。例如,想知道list指令用法,输入

   help list

16. 堆栈跟踪

   程序“调用堆栈”是当前函数之前的所有已调用函数的列表(包括当前函数)。每个函数及其变量都被分配了一个“帧”,最近调用的函数在 0 号帧中(“底部”帧)。要打
印堆栈,发出命令backtrace [回溯] 的缩写):

(gdb)bt
  
#0 0x80483ea in wib (no1=8, no2=8) at eg1.c:7 
#1 0x8048435 in main (argc=1, argv=0xbffff9c4) at eg1.c:21

   此结果显示了在 main() 的第 21 行中调用了函数 wib()(只要使用 list 21 就能证实这一点),而且 wib() 在 0 号帧中,main() 在 1 号帧中。由于 wib() 在 0 号帧中
,那么它就是执行程序时发生算术错误的函数。
 
  实际上,发出 info locals 命令时,gdb 会打印出当前帧中的局部变量,缺省情况下,这个帧中的函数就是被中断的函数(0 号帧)。可以使用命令 frame 打印当前帧。要查
看 main 函数(在 1 号帧中)中的变量,可以发出 frame 1 切换到 1 号帧,然后发出
info locals 命令:

(gdb) frame 1

#1 0x8048435 in main (argc=1, argv=0xbffff9c4) at eg1.c:21

21 result = wib(value, div);
 
(gdb) info locals 
 
value = 8
  
div = 8
 
result = 4
 
i = 2
  
total = 6

   此信息显示了在第三次执行 "for" 循环时(i 等于 2)发生了错误,此时 "value" 等于 "div"。
 
  可以通过如上所示在 frame 命令中明确指定号码,或者使用 up 命令在堆栈中上移以及down 命令在堆栈中下移来切换帧。要获取有关帧的进一步信息,如它的地址和程序语言,可以使用命令 info frame。






--转自



赞(0)    操作        顶端 
ettu
注册用户
等级:上尉
经验:787
发帖:0
精华:0
注册:2016-2-22
状态:离线
发送短消息息给ettu 加好友    发送短消息息给ettu 发消息
发表于: IP:您无权察看 2016-4-8 9:38:46 | [全部帖] [楼主帖] 2  楼

强大,学习了。谢谢!



赞(0)    操作        顶端 
k3neeb
注册用户
等级:上尉
经验:799
发帖:15
精华:0
注册:2015-5-28
状态:离线
发送短消息息给k3neeb 加好友    发送短消息息给k3neeb 发消息
发表于: IP:您无权察看 2016-4-11 10:10:48 | [全部帖] [楼主帖] 3  楼

*手动设置当前的程序语言为c++: 
(gdb) set language c++ 
这里,如果gdb没有检测出你的程序语言,你可以这样设置。 

*查看可以设置的程序语言: 
(gdb) set language 
这里,使用没有参数的set language可以查看gdb中可以设置的程序语言。 

*终止一个正在调试的程序: 
(gdb) kill 
这里,输入kill就会终止正在调试的程序了。 

*print显示变量(var)值: 
(gdb) print var 
这里,print可以简写为p,print 是gdb的一个功能很强的命令,利用它可以显示被调试的语言中任何有效的表达式。表达式除了包含你程序中的变量外,还可以包含函数调用,复杂数据结构和历史等等。 

*用16进制显示(var)值: 
(gdb) print /x var 
这里可以知道,print可以指定显示的格式,这里用'/x'表示16进制的格式。 
可以支持的变量显示格式有: 
x  按十六进制格式显示变量。 
d  按十进制格式显示变量。 
u  按十六进制格式显示无符号整型。 
o  按八进制格式显示变量。 
t  按二进制格式显示变量。 
a  按十六进制格式显示变量。 
c  按字符格式显示变量。 
f  按浮点数格式显示变量。 


*如果a是一个数组,10个元素,如果要显示则: 
(gdb) print *a@10 
这样,会显示10个元素,无论a是double或者是int的都会正确地显示10个元素。 

*修改运行时候的变量值: 
(gdb) print x=4 
这里,x=4是C/C++的语法,意为把变量x值改为4,如果你当前调试的语言是Pascal,那么你可以使用Pascal的语法:x:=4。 

*显示一个变量var的类型: 
(gdb) whatis var 

*以更详细的方式显示变量var的类型: 
(gdb) ptype var 
这里,会打印出var的结构定义。 

[其他] 
============= 
*在Qt4.x环境中打印QString msg;的msg变量: 
步骤如下: 
1)定义一个宏printqstring 
define printqstring 
    printf "(QString)0x%x (length=%i): \"",&$arg0,$arg0.d->size 
    set $i=0 
    while $i < $arg0.d->size 
        set $c=$arg0.d->data[$i++] 
        if $c < 32 || $c > 127 
                printf "\\u0x%04x", $c 
        else 
                printf "%c", (char)$c 
        end 
    end 
    printf "\"\n" 
end 
2)(gdb) printqstring msg 
这里,这个宏可以在gdb中直接定义,据说也可以写到$HOME/.gdbinit,这样每次启动自动加载。 

*调试同时指明生成core文件: 
$gdb <program> core 
用gdb同时调试一个运行程序和core文件,core是程序非法执行后core dump后产生的文件。当程序非法崩溃的时候会产生一个core文件,然后使用这个命令,会直接定位到发生程序崩溃的位置。注意:有时需要设置系统命令“ulimit -c unlimited”才能产生core文件。 


**没有实践过的 
*print显示存储块,如显示h后面的10个整数: 
print h@10 
** 



赞(0)    操作        顶端 
jinggege
注册用户
等级:中士
经验:241
发帖:0
精华:0
注册:2016-2-26
状态:离线
发送短消息息给jinggege 加好友    发送短消息息给jinggege 发消息
发表于: IP:您无权察看 2016-4-19 19:51:55 | [全部帖] [楼主帖] 4  楼



赞(0)    操作        顶端 
filogra
注册用户
等级:少校
经验:1408
发帖:13
精华:0
注册:2015-6-2
状态:离线
发送短消息息给filogra 加好友    发送短消息息给filogra 发消息
发表于: IP:您无权察看 2016-4-21 8:59:09 | [全部帖] [楼主帖] 5  楼

好帖~~



赞(0)    操作        顶端 
duff
注册用户
等级:少校
经验:968
发帖:0
精华:0
注册:2015-7-22
状态:离线
发送短消息息给duff 加好友    发送短消息息给duff 发消息
发表于: IP:您无权察看 2016-4-29 7:39:44 | [全部帖] [楼主帖] 6  楼



赞(0)    操作        顶端 
山友木樨
注册用户
等级:少校
经验:1040
发帖:9
精华:0
注册:2015-6-1
状态:离线
发送短消息息给山友木樨 加好友    发送短消息息给山友木樨 发消息
发表于: IP:您无权察看 2016-4-29 8:52:12 | [全部帖] [楼主帖] 7  楼



赞(0)    操作        顶端 
beefly
注册用户
等级:上尉
经验:758
发帖:1
精华:0
注册:2015-7-27
状态:离线
发送短消息息给beefly 加好友    发送短消息息给beefly 发消息
发表于: IP:您无权察看 2016-4-29 20:57:55 | [全部帖] [楼主帖] 8  楼

好厉害



赞(0)    操作        顶端 
伊恩dih
注册用户
等级:少校
经验:819
发帖:15
精华:0
注册:2015-5-28
状态:离线
发送短消息息给伊恩dih 加好友    发送短消息息给伊恩dih 发消息
发表于: IP:您无权察看 2016-5-17 16:17:42 | [全部帖] [楼主帖] 9  楼

不错,学习了



赞(0)    操作        顶端 
总帖数
9
每页帖数
101/1页1
返回列表
发新帖子
请输入验证码: 点击刷新验证码
您需要登录后才可以回帖 登录 | 注册
技术讨论