付费下载
下载本文档
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、1.1 gdb1.1.1 gdb 概述无论多么优秀的程序员,必须经常面对的一个问题就是调试。当程序编译完成后,他可能无法正常运行;或许程序会彻底;或许只是不能正常地运行某些功能;或许它的输出会被挂起;或许不会提示要求正常的输入。无论在何种情况下,这些问题,特别是在大的工程中,将是开发中最的部分,本章将介绍使用 gdb(GNU debugger)调试程序的方法,该程序是一个调试器,是用来帮助程序员寻找程序中的错误的。gdb 是 GNU 开发组织发布的一个强大的 UNIX/Linux 下的程序调试工具。或许,有人比较图形界面方式的,像 VC、BCB 等 IDE 环境,但是在 UNIX/Linux下
2、做,gdb这个调试工具有比 VC、BCB 的图形化调试器更强大的功能。所谓“寸有是这个道理。一般来说,gdb 主要帮忙用户完成下面 4 个方面的功能:,尺有所短”就启动程序,可以按照用户自定义的要求随心所欲的运行程序。可让被调试的程序在用户所指定的调试的断点处停住 (断点可以是条件表达式)。当程序停住时,可以检查此时程序中所发生的事。动态地改变程序的执行环境。从上面来看,gdb 和一般的调试工具区别不大,基本上也是完成这些功能,不过在细节上,会发现 gdb 这个调试工具的强大。大家可能了图形化的调试工具,但有时候,命令行的调试工具却有着图形化工具所不能完成的功能。下面通过实例进行说明。#inc
3、lude func(n)sum=0,i; for(i=0; in; i+)sum+=i;return sum;main()i;long result = 0; for(i=1; i=100; i+)result += i;prf(result1-100 = %d n, result ); prf(result1-250 = %d n, func(250) );编译生成执行文件:$ gcc g test.c -o test使用 gdb 调试:$ gdb test启动 gdb然后,键入l 命令相当于 list 命令,从第一行开始列出源码:在第 14 行设置断点:键入 break 14:在 func
4、 函数处设置断点:键入 break func:可以用 info break 查看断点信息:要运行程序,只需键入 r:这时,如果要单步执行的话,可以键入 n,表示执行下一条语句:如果要继续运行程序直至下个断点,可以键入 c:发现程序运行至 func 函数的路口。用 n 命令单步进去:这时候,如果要察查看变量 i 的值,可以用pi:继续单步:可以用 bt 命令查看函数调用堆栈:要退出函数,可以直接敲入 finish:按 c 继续运行,则程序执行完毕,调试结束要退出 gdb 程序,只需敲入 q。有了以上的感性认识,下面来系统地学下 gdb。1.1.2 启动 gdbgdb 主要调试的是 C/C+程序,
5、要调试 C/C+程序,首先在编译时,必须要把调试信息加到可执行文件中。使用 gcc 的-g 参数即可。如:$gcc go.c oo如果没有-g,将看不见程序的函数名和变量名,代替它们的全是运行时的内存地址。当用-g 把调试信息加入,并成功编译目标代码以后,看看如何用 gdb 来调试。启动 gdb 的方法有以下几种:1、gdb program 也就是执行文件,一般在当前目录下。2、 gdb core用 gdb 同时调试一个运行程序和 core 文件,core 是程序生的文件。执行后,core dump 后产3、 gdb 如果程序是一个服务程序,那么可以指定这个服务程序运行时的进程 ID。gdb
6、会自动attach 上去,并调试它。program 应该在 PATH 环境变量中搜索得到。gdb 启动时,可以加上一些 gdb 的启动开关,详细的开关可以用 gdb -help 查看。1.1.3 在 gdb 中运行程序当以 gdb 方式启动 gdb 后,gdb 会在 PATH 路径和当前目录中搜索的源文件。如要确认 gdb 是否读到源文件,可使用 l 或 list 命令,看看 gdb 是否能列出源代码。在 gdb 中,运行程序使用 r 或是 run 命令。程序的运行,有可能需要设置下面四方面的事。1、程序运行参数set args 可指定运行时的参数。如:set args 10 20 30 40
7、 50show args 命令可以查看设置好的运行参数。2、运行环境path 可设定程序的运行路径。shoths 查看程序的运行路径。set env varname=value设置环境变量。如: show environment 查看环境变量。3、工作目录cd 相当于 s的 cd 命令。pwd 显示当前所在目录。4、程序的输入输出可以使用重定向方式将程序的输出重定向到指定文件中。如:routfile1.1.4 暂停/恢复程序运行调试程序中,暂停程序运行是必需的,gdb 可以方便地暂停程序的运行。可以设置程序在哪行停住,在什么条件下停住,在收到什么信号时停往等,以便于用户查看运行时的变量,以及运
8、行时的流程。当进程被 gdb 停住时,可以使用 info program 来查看程序是否在运行、进程号、被暂停的原因。在 gdb 中,有以下几种暂停方式: 断点(BreakPo)、观察点(WatchPo)、捕捉点(CatchPo)、信号(Signals)及线程停止(Thread Stops)。如果要恢复程序运行,可以使用 c 或是 continue 命令。1.1.4.1设置断点(BreakPo)用 break 命令来设置断点。有以下几种设置断点方法:1、break 在进入指定函数时停住。 2、break 在指定行号停住3、break +offset;break offset在当前行号的前面 o
9、ffset 行或后面 offset 行设置断点,offset 为自然数4、break filename:function在源文件 filename 的 function 函数5、break filename:行号处设置断点在源文件 filename 的指定行号处设置断点6、break *address在程序运行的内存地址处设置断点7、break不代参数,表示在下一条指令处设置断点8、break if condition 表示条件,在条件成立时停住。比如在循环体中,可以设置 break if i=100,表示当 i 为 100 时停住程序。要查看断点信息,可以使用 info 命令。1.1.4.2
10、设置观察点(WatchPo)观察点一般用来观察某个表达式(变量也是一种表达式)的值是否变化了。如果有变化,马上停住程序。有下面的几种方法来设置观察点:1、watch 为表达式(变量)expr 设置一个观察点。一旦表达式值有变化时,马上停住程序。2、rwatch 当表达式(变量)expr 被读时,停住程序。3、awatch 当表达式(变量)的值被读或被写时,停住程序。info watchpos列出当前设置的所有观察点。1.1.4.3设置捕捉点(CatchPo)可设置捕捉点来补捉程序运行时的一些事件。如载入共享库(动态常。设置捕捉点的格式为:catch 当 event 发生时,停住程序。event
11、 可以是下面的内容:库)或是 C+的异throw catch exec forkvfork一个 C+抛出的异常 (throw 为关键字)。 一个 C+捕捉到的异常 (catch 为关键字)。调用系统调用 exec 时(exec 为关键字,目前此功能只在 HP-UX 下有用)。调用系统调用 fork 时(fork 为关键字,目前此功能只在 HP-UX 下有用)。调用系统调用 vfork 时(vfork 为关键字,目前此功能只在 HP-UX 下有)。load 或 load 载入共享库(动态功能只在 HP-UX 下有用)。unload 或 unload 卸载共享库(动态目前此功能只在 HP-UX 下
12、有用)。库)时 (load 为关键字,目前此库)时 (unload 为关键字,tcatch 只设置一次捕捉点,当程序停住以后,被自动删除。1.1.4.4停止点上面说了如何设置程序的停止点,gdb 中的停止点也就是上述的三类。在 gdb 中,如果觉得已定义好的停止点没有用了,可以使用 delete、clear、disable、enable 这几个命令来进行。clear 清除所有的已定义的停止点。clear 可以有如下几种形式:clear clear clearcleardelete breakpos range删除指定的断点,breakpos 为断点号。如果不指定断点号,则表示删除所有的断点。r
13、ange 表示断点号的范围(如:3-7)。其简写命令为 d。disable breakpos range 使断点不可用,被 disable 了的停止点,gdb 不会删除,当还需要时,enable 即可,就好像回收站一样。breakpo不指定,表示 disable 所有的停止点。简写命令是 dis。s 为停止点号。如果什么都enable breakpos range 使指定的停止点可用,breakpos 为停止点号。enable breakpos once rangeenable 所指定的停止点一次,当程序停止后,该停止点马上被 gdb 自动 disable。enable breakpos de
14、lete rangeenable 所指定的停止点一次,当程序停止后,该停止点马上被 gdb 自动删除。1.1.4.5停止条件前面在介绍设置断点时,提到过可以设置一个条件,当条件成立时,程序自动停止。这是一个非常强大的功能,这里,专门介绍这个条件的相关命令。一般来说,为断点设置一个条件,可使用 if,后面跟其断点条件。并且,条件设置好后,可以用condition 命令来修改断点的条件(只有break 和watch 命令支持if,catch目前暂不支持 if)。condition 修改断点号为 bnum 的停止条件为 expres condition 清除断点号为 bnum 的停止条件。还有一个比
15、较特殊的ignore 命令 ignore,可以指定程序运行时,忽略停止条件几次。表示忽略断点号为 bnum 的停止条件 count 次。1.1.4.6为停止点设定运行命令可以使用 gdb 提供的d 命令来设置停止点的运行命令。也就是说,当运行的程序在被停住时,ds.end可以让其自动运行一些别bnumd-list .令,这很有利行自动化调试。为断点号 bnum 指定一个命令列表。当程序被该断点停住时,gdb 会依次运行命令列表中令。例如:break foo if x0dsprf x is %dn,xcontinueend断点设置在函数 foo 中,断点条件是 x0,如果程序被断住后,也就是一旦
16、 x 的值在 foo函数中大于 0,gdb 会自动打印出 x 的值,并继续运行程序。如果要清除断点上入 end 就行了。令序列,那么只要简单地执行一下ds 命令,并直接在输1.1.4.7恢复程序运行和单步调试当程序被停住后,可以用 continue 命令恢复程序的运行直到程序结束,或下一个断点到来。也可以使用 step 或 next 命令单步continue ignore-count程序。恢复程序运行,直到程序结束,或是下一个断点到来。ignore-count 表示忽略其后的断点次数。step 单步,如果有函数调用,它会进入该函数。进入函数的前提是,此函数被编译有debug 信息。很像 VC
17、等工具中的 stn。后面可以加 count 也可以不加,不加表示一条条地执行,加表示执行后面的 count 条指令,然后再停住。next 同样单步,如果有函数调用,它不会进入该函数(很像 VC 等工具中的 step over)。后面可以加 count 也可以不加,不加表示一条条地执行,加表示执行后面的 count 条指令,然后再停住。finish运行程序,直到当前函数完成返回。并打印函数返回时的堆栈地址和返回值及参数值等信息。until 或 u当厌倦了在一个循环体内单步时,这个命令可以运行程序直到退出循环体。1.1.5 查看栈信息当程序被停住时,需要做的第一件事就是查看程序是在哪里停住的。当程
18、序调用了一个函数时,函数的地址、函数参数、函数内的局部变量都会被压入“栈”(Stack)中。可以用 gdb 命令来查看当前的栈中的信息。下面是一些查看函数调用栈信息的 gdb 命令:backtrace 或 bt打印当前的函数调用栈的所有信息。如:从上可以看出函数的调用栈信息: libc_start_main - main() - func() backtrace 或 bt n 是一个正整数,表示只打印栈顶上 n 层的栈信息。(gdb) bt#0 func (n=250) at tst.c:6#1 0 x08048524ain (argc=1, argv=0 xbf674) at tst.c:3
19、0 #2 0 x400409ed in libc_start_main () from /lib/libc.so.6backtrace 或 bt -n 表示一个负整数,表示只打印栈n 层的栈信息。如果要查看某一层的信息,需要切换当前的栈。一般来说,程序停止时,最顶层的栈就是当前栈,如果要查看栈下面层的详细信息,首先要做的是切换当前栈。frame 或 f n 是一个从 0 开始的整数,是栈中的层栈的第二层。up 。比如:frame 0 表示栈顶,frame 1 表示表示向栈的上面移动n 层,可以不输入n,表示向上移动一层。 down 表示向栈的下面移动n 层,可以不输入n,表示向下移动一层。上面
20、命令:令,都会输出移动到的栈层的信息。如果不想让其输出信息。可以使用这三个select-frame 对应于 frame 命令。up-silently 对应于 up 命令。down-silently 对应于 down 命令。查看当前栈层的信息,可以用以下 gdb 命令:frame 或 f显示出这些信息:栈的层数执行到的语句。info frame 或 info f,当前的函数名,函数参数值,函数所在文件及行号,函命令会显示出更为详细的当前栈层的信息,只不过,大多数都是运行时的内内地址。比如:函数地址,调用函数的地址,被调用函数的地址,目前函数的程序语言、函数参数地址及值、局部变量的地址等。如:in
21、fo args显示出当前函数的参数名及值。info locals显示出当前函数中所有局部变量及值。info catch显示出当前函数中的异常处理信息。(gdb) bt#0 main () at test.c:23#1 0 x42015574 in libc_start_main () from /lib/tls/libc.so.6 (gdb) info fStack level 0, frame at 0 xbef48:eip = 0 x80483c3ain (test.c:23); saved eip 0 x42015574 called by frame at 0 xbef68source
22、 language c.Arglis0 xbef48, args:Locals at 0 xbef48, Previous frames sp in esp Saved registers:t 0 xbef48, eip at 0 xbef4c(gdb)1.1.6 查看运行时数据在调试程序时,当程序被停住时,可以使用 pr命令(简写命令为 p),或是同义命令inspect 来查看当前程序的运行数据。pr命令的格式是:prpr/ 是表达式,是所调试的程序的语言的表达式(gdb 可以调试多种编程语言);是输出的格式。比如,如果要把表达式按 16 进制的格式输出,那么就是/x。1.1.6.1表达式p
23、r和许多 gdb令一样,可以接受一个表达式,gdb 会根据当前的程序运行的数据来计算这个表达式。既然是表达式,那么就可以是当前程序运行中的常量、变量、函数等内容。可惜的是 gdb 不能使用在程序中所定义的宏。表达式的语法应该是当前所调试的语言的语法,由于 C/C+是一种大众型的语言,所以,本文中的例子都是关于 C/C+的。在表达式中,有几种 gdb 所支持的操作符,它们可以用在任何一种语言中。:是一个和数组有关的操作符,在后面会有更详细的说明。指定一个在文件或是一个函数中的变量。表示一个指向内存地址的类型为 type 的一个对象。1.1.6.2程序变量在 gdb 中,可以随时查看以下 3 种变
24、量的值:全局变量(所有文件可见的)静态全局变量(当前文件可见的)局部变量(当前 Scope 可见的)如果局部变量和全局变量发生(也就是重名),一般情况下是局部变量会隐藏全局变量。也就是说,如果一个全局变量和一个函数中的局部变量同名时,如果当前停止点在函数中,用 pr显示出的变量的值会是函数中的局部变量的值。如果此时想查看全局变量的值,可以使用“:”操作符: file:variable function:variable可以通过这种形式指定所要查看的变量,是哪个文件中的或是哪个函数中的。例如,查看文件 f2.c 中的全局变量 x 的值:(gdb) pf2.c:x当然,“:”操作符会和 C+中的发
25、生所以不必担心在调试 C+程序时会出现异常。,gdb 能自动识别“:”是否 C+的操作符,另外,需要注意的是,如果程序编译时开启了优化选项,那么在用 gdb 调试被优化过的程序时,可能会发生某些变量不能,或是取值错误的情况。这个是很正常的,因为优化程序会删改程序,整理程序的语句顺序,剔除一些无意义的变量等。所以在 gdb 调试这种程序时,运行时的指令和所编写的指令就不一样,也就会出现想象不到的结果。对付这种情况,需要在编译程序时关闭编译优化。一般来说,几乎所有的编译器都支持编译优化的开关,例如,GNU 的 C/C+编译器 GCC,可以使用-gstabs 选项来解决这个问题。关于编译器的参数,请
26、查看编译器的使用说明文档。1.1.6.3数组有时候需要查看一段连续的内存空间的值。比如数组的一段,或是动态分配的数据的大小。可以使用 gdb 的操作符。的左边是第一个内存地址的值,的右边则是想查看的内存的长度。例如,程序中有这样的语句:*array = (*) malloc (len *sizeof ();于是,在 gdb 调试过程中,可以用如下命令显示出这个动态数组的取值:p *arraylen的左边是数组的首地址的值,也就是变量 array 所指向的内容,右边则是数据的长度,其保存在变量 len 中。其输出结果,大约是下面这个样子的:(gdb) p *arraylen$1=2,4,6,8,
27、10,12,14,16,18,20,22,24,26,28,30,32,34,36,38,40如果是静态数组的话,直接用 pr数组名就可以显示数组中所有数据的内容了。1.1.6.4输出格式一般来说,gdb 会根据变量的类型输出变量的值。但也可以自定义 gdb 的输出格式。例如,想输出一个整数的十六进制或是二进制来查看这个整型变量中的位的情况。要做到这样,可以使用 gdb 的数据显示格式:x du按十六进制格式显示变量。按十进制格式显示变量。按十六进制格式显示无符号整型。按八进制格式显示变量。t a cf按二进制格式显示变量。 按十六进制格式显示变量。按字符格式显示变量。按浮点数格式显示变量。p
28、 i 101p/a i0 x65(gdb)$21 =(gdb)$22 =(gdb)$23 =(gdb)$24 =(gdb)$25 =(gdb)$26 =p/c 101p/fie i1.41531145e-43p/x i 0 x65p/t i11001011.1.6.5查看内存可以使用 examine 命令(简写是 x)来查看内存地址中的值。x 命令的语法如下所示:x/ n、f、u 是可选的参数。n 是一个正整数,表示显示内存的长度,也就是说从当前地址向后显示几个地址的内容。f 表示显示的格式,参见上面。如果地址所指的是字符串,那么格式可以是 s,如果是指令地址,那么格式可以是 i。u 表示从当
29、前地址往后请求的字节数,如果不指定的话,gdb 默认是 4 个 bytes。u参数可以用下面的字符来代替:b 表示单字节,h 表示双字节,w 表示四字节,g表示八字节。当指定了字节长度后,gdb 会从指定的内存地址开始,读写指定字节,并把其当作一个值取出来。表示一个内存地址。n/f/u 三个参数可以一起使用。例如:x/3uh 0 x54320表示从内存地址 0 x54320表示按十六进制显示。内容,h 表示以双字节为 1 个,3 表示 3 个,u1.1.6.6自动显示可以设置一些自动显示的变量,当程序停住时,或是在单步示。相关的 gdb 命令是 display。display display/
30、 display/ 时,这些变量会自动显expr 是一个表达式,fmt 表示显示的格式,addr 表示内存地址。当用 display 设定好了一个或多个表达式后,只要程序停下来,gdb 会自动显示所设置的这些表达式的值。格式i 和 s 同样被 display 支持,一个非常有用display/i $pc令是:$pc 是 gdb 的环境变量,表示指令的地址,/i 则表示输出格式为机器指令码,也就是汇编。于是当程序停下后,就会出现源代码和机器指令码相对应的情形,这是一个很有意思的功能。下面是一些和 display 相关的 gdb 命令:undisplay delete display 删除自动显示
31、,dnums 意为设置好了的自动显示的。如果要同时删除几个,可以用空格分隔;如果要删除一个范围内的disable display enable display ,可以用减号表示(如:2-5)。disable 和 enalbe 不删除自动显示的设置,而只是让其失效和恢复。info display查看 display 设置的自动显示的信息。gdb 会显示出一张表格,调试中设置了多少个自动显示设置,其中包括设置的、表达式及是否 enable。1.1.6.7查看寄存器要查看寄存器的值,很简单,可以使用如下命令:infoinfo inforegistersall-registers registers 寄存
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 吞咽障碍患者的语言治疗与沟通训练
- (2026年)心力衰竭治疗过程中WRF评价及对策
- 2025届甘肃省张掖市高台县城关初级中学三年级数学第二学期期中综合测试试题(含答案解析)
- 危重患者电解质紊乱处理
- 老年护理学:跌倒的预防与管理技巧
- 2025-2026学年人教七下u7听说课教学设计
- 2026新教材 小学数学人教版二年级下3.有余数除法的计算教学课件
- 2025-2026学年统编版姓氏歌教学设计
- 3.14明朝的统治教学设计2023~2024学年统编版七年级历史下册
- 阿根廷Mercado美客多2026年电动剃须刀6月市场月度报告
- 2026北京北控物业管理有限责任公司招聘运营总监及市场型公建项目管理中心经理2人考试备考试题及答案解析
- 环境监测人员持证上岗考核试题及答案2025年
- 某仪器仪表厂外协加工管控方案
- 3 b p m f公开课一等奖创新教学设计(2课时)
- 《四川省老旧小区物业服务标准》
- 信访紧急突发情况应急预案(3篇)
- 安徽省2025年公需科目三安徽农业大学测验参考答案
- DB32∕T 4972.8-2024 传染病突发公共卫生事件应急处置技术规范 第8部分:标本的采集、保存和运输
- 2024年江苏省南京市中考英语试卷真题(含答案)
- 肛裂中西医结合诊疗指南
- 麻醉患者恢复期的气道管理
评论
0/150
提交评论