gdb调试从入门到精通.doc_第1页
gdb调试从入门到精通.doc_第2页
gdb调试从入门到精通.doc_第3页
gdb调试从入门到精通.doc_第4页
gdb调试从入门到精通.doc_第5页
已阅读5页,还剩45页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

无论是多么优秀的程序员,都难以保证自己在编写代码时不会出现任何错误,因此调试是软件开发过程中的一个必不可少的组成部分。当程序完成编译之后,它很可能无法正常运行,或者会彻底崩溃,或者不能实现预期的功能。此时如何通过调试找到问题的症结所在,就变成了摆在开发人员面前最严峻的问题。通常说来,软件项目的规模越大,调试起来就会越困难,越需要一个强大而高效的调试器作为后盾。对于Linux程序员来讲,目前可供使用的调试器非常多,GDB(GNU DeBugger)就是其中较为优秀的。 初识GDB GDB是自由软件基金会(Free Software Foundation,FSF)的软件工具之一。它的作用是协助程序员找到代码中的错误。如果没有GDB的帮助,程序员要想跟踪代码的执行流程,唯一的办法就是添加大量的语句来产生特定的输出。但这一手段本身就可能会引入新的错误,从而也就无法对那些导致程序崩溃的错误代码进行分析。GDB的出现减轻了开发人员的负担,他们可以在程序运行的时候单步跟踪自己的代码,或者通过断点暂时中止程序的执行。此外,他们还能够随时察看变量和内存的当前状态,并监视关键的数据结构是如何影响代码运行的。 调试方法 如果想对程序进行调试,必须先在用GCC编译源代码时加上-g选项,以便产生GDB所需要的调试符号信息。例如,debugme.c是一个存在错误程序,可以使用如下的命令对其进行编译,同时产生调试符号: # gcc -g debugme.c -o debugme 如果愿意的话,还可以在编译时使用“-ggdb”选项来生成更多的调试信息。由于这些调试信息中的相当一部分是GDB所特有的,所以生成的代码将无法在其它调试器中正常调试。对于大多数情况来说,普通的-g选项就足够了。需要注意的是,GCC虽然允许同时使用-g(调试)和-o(优化)选项,但优化会影响最终生成的代码,导致程序源代码和二进制代码之间的关系变得复杂起来。如果不想为调试制造障碍,建议不要将-g和-o选项一同使用,并且只在程序彻底调试完后才开始进行代码优化。这样调试过程将变得相对轻松和愉快。 基本应用 现在可以启动GDB来调试已经生成的可执行程序debugme,命令如下:# gdb debugme GNU gdb Red Hat Linux (5.3post-0.20021129.18rh) (gdb) 如果一切正常,GDB将被启动并在屏幕上输出版权信息,但如果使用了-q或-quiet选项则不会显示它们。启动GDB时另外一个有用的命令行选项是“-d dirname”,其中dirname是一个目录名。该目录名告诉GDB应该到哪里去寻找源代码。 一旦出现GDB的命令提示符(gdb),就表明GDB已经准备好接收来自用户的各种调试命令了。如果想在调试环境下运行这个程序,可以使用GDB提供的“run”命令,而程序在正常运行时所需的各种参数可以作为“run”命令的参数传入,或者使用单独的“set args”命令进行设置。如果在执行“run”命令时没有给出任何参数,GDB将使用上一次“run”或“set args”命令指定的参数。如果想取消上次设置的参数,可以执行不带任何参数的“set args”命令。下面尝试在调试器中运行这个程序:(gdb) run Program received signal SIGSEGV, Segmentation fault. 0x4000c6ac in _dl_fini () from /lib/ld-linux.so.2 最后一行输出表明程序在调用动态链接库/lib/ld-linux.so.2中的_dl_fini()函数时出现了错误,地址是0x4000c6ac。这些对调试是非常重要的线索。另外还有一种信息对调试也很重要,就是错误发生时的函数调用层级关系,可以通过执行“backtrace”命令来获得。在使用GDB调试命令时,用户可以不必输入完整的命令名称,使用任何惟一的缩写都可以。例如“backtrace”命令就可以缩写成“back”甚至“bt”。GDB还支持很多常用的Shell命令编辑特征,比如可以像在bash或tcsh中那样按Tab键补齐命令。如果相关命令不惟一的话,则列出所有可能的匹配项。此外键盘上的方向键可用来翻动历史命令。 GDB是一个源代码级的调试器,使用“list”命令可以查看当前调试对象的源代码。该命令的通用格式为“list m,n”,表示显示从m行开始到n行结束的代码段,而不带任何参数的“list”命令将显示最近10行源代码。 设置断点 在调试有问题的代码时,在某一点停止运行往往很管用。这样程序运行到此外时会暂时挂起,等待用户的进一步输入。GDB允许在几种不同的代码结构上设置断点,包括行号和函数名等,并且还允许设置条件断点,让程序只有在满足一定的条件时才停止执行。要根据行号设置断点,可以使用“ break linenum”命令。要根据函数名设置断点,则应该使用“break funcname”命令。 在以上两种情况中,GDB将在执行指定的行号或进入指定的函数之前停止执行程序。此时可以使用“print”显示变量的值,或者使用“list”查看将要执行的代码。对于由多个源文件组成的项目,如果想在执行到非当前源文件的某行或某个函数时停止执行,可以使用如下形式的命令:# break 20041126110727.htm:linenum # break 20041126110727.htm:funcname 条件断点允许当一定条件满足时暂时停止程序的执行。它对于调试来讲非常有用。设置条件断点的正确语法如下:break linenum if expr break funcname if expr 其中expr是一个逻辑表达式。当该表达式的值为真时,程序将在该断点处暂时挂起。例如,下面的命令将在debugme程序的第38行设置一个条件断点。当程序运行到该行时,如果count的值等于3,就将暂时停止执行: (gdb) break 38 if count=3 设置断点是调试程序时最常用到的一种手段。它可以中断程序的运行,给程序员一个单步跟踪的机会。使用命令“ break main”在main函数上设置断点可以在程序启动时就开始进行跟踪。 接下去使用“continue”命令继续执行程序,直到遇到下一个断点。如果在调试时设置了很多断点,可以随时使用“info breakpoints”命令来查看设置的断点。此外,开发人员还可以使用“delete”命令删除断点,或者使用“disable”命令来使设置的断点暂时无效。被设置为无效的断点在需要的时候可以用“enable”命令使其重新生效。 观察变量 GDB最有用的特性之一是能够显示被调试程序中几乎任何表达式、变量或数组的类型和值,并且能够用编写程序所用的语言打印出任何合法表达式的值。查看数据最简单的办法是使用“print”命令,只需在“print”命令后面加上变量表达式,就可以打印出此变量表达式的当前值,示例如下:(gdb) print str $1 = 0x40015360 Happy new year!n 从输出信息中可以看出,输入字符串被正确地存储在了字符指针str所指向的内存缓冲区中。除了给出变量表达式的值外,“print”命令的输出信息中还包含变量标号($1)和对应的内存地址(0x40015360)。变量标号保存着被检查数值的历史记录,如果此后还想访问这些值,就可以直接使用别名而不用重新输入变量表达式。 如果想知道变量的类型,可以使用“whatis”命令,示例如下:(gdb) whatis str type = char * 对于第一次调试别人的代码,或者面对的是一个异常复杂的系统时,“whatis”命令的作用不容忽视。 单步执行 为了单步跟踪代码,可以使用单步跟踪命令“step”,它每次执行源代码中的一行。 在GDB中可以使用许多方法来简化操作,除了可以将“step”命令简化为“s”之外,还可以直接输入回车键来重复执行前面一条命令。 除了可以用“step”命令来单步运行程序之外,GDB还提供了另外一条单步调试命令“next”。两者功能非常相似,差别在于如果将要被执行的代码行中包含函数调用,使用step命令将跟踪进入函数体内,而使用next命令则不进入函数体内。 在进入下一部分之前,使用下面的命令退出GDB: (gdb) quit 分析核心(core)文件 在程序发生崩溃时,有时可能无法直接运行GDB来进行调试。比如程序可能是在另外一台机器上运行的,或者因为程序对时间比较敏感,所以手动跟踪调试会产生无法接受的延迟等。遇到这些情况,就只能等到程序运行结束后才能判断崩溃的原因了。这时需要用到Linux提供的core dump机制。当程序中出现内存操作错误时,会发生崩溃并产生核心文件。使用GDB可以对产生的核心文件进行分析,找出程序是在什么时候崩溃的和在崩溃之前程序都做了些什么。当然,如果要用GDB来分析核心文件,也必须在编译时加上-g选项来产生调试符号表。 在分析核心文件之前必须确认系统是否允许生成核心文件,很多Linux发行版在默认时禁止生成核心文件。为了生成核心文件,首先必须执行下面的命令: # ulimit -c unlimited 然后就可以生成核心文件了。这里仍以前面的debugme程序为例,再次执行下面命令将产生核心文件:# ./debugme Enter a string to count words:Happy new year! The number of words is 3. Segmentation fault (core dumped) 生成的核心文件名根据系统配置的不同会有所差异。要在GDB中分析核心文件,除了要给出核心文件的文件名外,还必须给出生成该核心文件的可执行程序的名称,示例如下:#gdb debugme core.547 Program terminated with signal 11, Segmentation fault. Reading symbols from /lib/libc.so.6.done. 从GDB的输出信息中可以看出,产生这个核心文件的原因是因为程序收到了序号为11的信号。如果想知道程序在崩溃之前运行到了哪里,可以使用“backtrace”或“info stack”命令查看一下堆栈的历史记录。示例如下:(gdb) info stack #0 0x4000c6ac in _dl_fini () from /lib/ld-linux.so.2 #1 0x40057940 in exit () from /lib/libc.so.6 #2 0x4004291f in _libc_start_main () from /lib/libc.so.6 由上可知,程序崩溃时正处于_dl_fini()函数之中。但很多时候程序员感兴趣的可能并不是这个,而是exit()或_libc_start_main()函数,因为它们才可能是问题真正的症结所在。GDB提供的“frame”命令可以用来在不同的调用上下文中切换。例如下面的命令可以查看exit()函数在执行时的状况:(gdb) frame 1 #1 0x40057940 in exit () from /lib/libc.so.6 此外还可以用“up”或“down”命令在不同的函数调用上下文中切换。开发人员使用这三条命令可以很轻松地实现调用栈的遍历。在分析核心文件时,通过将遍历栈的命令和检查变量值的“print”命令结合起来,就能够复原程序运行时的全部景象。 调试其它进程 有时会遇到一种很特殊的调试需求,对当前正在运行的其它进程进行调试。这种情况有可能发生在那些无法直接在调试器中运行的进程身上,例如有的进程只能在系统启动时运行。另外如果需要对进程产生的子进程进行调试的话,也只能采用这种方式。GDB可以对正在执行的程序进行调度,它允许开发人员中断程序并查看其状态,之后还能让这个程序正常地继续执行。 GDB提供了两种方式来调试正在运行的进程:一种是在GDB命令行上指定进程的PID,另一种是在GDB中使用“attach”命令。例如,开发人员可以先启动debugme程序,让其开始等待用户的输入。示例如下:#./debugme Enter a string to count words: 接下去在另一个虚拟控制台中用下面的命令查出该进程对应的进程号:# ps -ax | grep debugme 555 pts/1 S 0:00 ./debugme 得到进程的PID后,就可以使用GDB对其进行调试了:# gdb debugme 555 GNU gdb Red Hat Linux (5.3post-0.20021129.18rh) Attaching to program: /home/xiaowp/debugme, process 555 Reading symbols from /lib/libc.so.6.done. 在上面的输出信息中,以Attaching to program开始的行表明GDB已经成功地附加在PID为555的进程上了。另外一种连接到其它进程的方法是先用file命令加载调试时所需的符号表,然后再通过“attach”命令进行连接:(gdb) file /home/xiaowp/debugme Reading symbols from /home/xiaowp/debugme.done. (gdb) attach 555 如果想知道程序现在运行到了哪里,同样可以使用“backtrace”命令。当然也可以使用“step”命令对程序进行单步调试。 在完成调试之后,不要忘记用detach命令断开连接,让被调试的进程可以继续正常运行: GDB是Linux下一个最基本的调试器,其功能非常丰富。完整地介绍GDB的功能可能需要几百页,本文只涵盖了GDB的一些最常见的用法。作为一个合格的Linux程序员,花在GDB上的功夫和时间越多,从调试中获得的益处就越多。 Linux 包含了一个叫 gdb 的 GNU 调试程序. gdb 是一个用来调试 C 和 C+ 程序的强力调试器. 它使你能在程序运行时观察程序的内部结构和内存的使用情况. 以下是 gdb 所提供的一些功能:它使你能监视你程序中变量的值.它使你能设置断点以使程序在指定的代码行上停止执行.它使你能一行行的执行你的代码.在命令行上键入 gdb 并按回车键就可以运行 gdb 了, 如果一切正常的话, gdb 将被启动并且你将在屏幕上看到类似的内容:GDB is free software and you are welcome to distribute copies of itunder certain conditions; type show copying to see the conditions.There is absolutely no warranty for GDB; type show warranty for details.GDB 4.14 (i486-slakware-linux), Copyright 1995 Free Software Foundation, Inc.(gdb)当你启动 gdb 后, 你能在命令行上指定很多的选项. 你也可以以下面的方式来运行 gdb :gdb 当你用这种方式运行 gdb , 你能直接指定想要调试的程序. 这将告诉gdb 装入名为 fname 的可执行文件. 你也可以用 gdb 去检查一个因程序异常终止而产生的 core 文件, 或者与一个正在运行的程序相连. 你可以参考 gdb 指南页或在命令行上键入 gdb -h 得到一个有关这些选项的说明的简单列表.为调试编译代码(Compiling Code for Debugging)为了使 gdb 正常工作, 你必须使你的程序在编译时包含调试信息. 调试信息包含你程序里的每个变量的类型和在可执行文件里的地址映射以及源代码的行号. gdb 利用这些信息使源代码和机器码相关联.在编译时用 -g 选项打开调试选项.gdb 基本命令gdb 支持很多的命令使你能实现不同的功能. 这些命令从简单的文件装入到允许你检查所调用的堆栈内容的复杂命令, 表27.1列出了你在用 gdb 调试时会用到的一些命令. 想了解 gdb 的详细使用请参考 gdb 的指南页.表 27.1. 基本 gdb 命令.命 令 描 述file 装入想要调试的可执行文件.kill 终止正在调试的程序.list 列出产生执行文件的源代码的一部分.next 执行一行源代码但不进入函数内部.step 执行一行源代码而且进入函数内部.run 执行当前被调试的程序quit 终止 gdbwatch 使你能监视一个变量的值而不管它何时被改变.break 在代码里设置断点, 这将使程序执行到这里时被挂起.make 使你能不退出 gdb 就可以重新产生可执行文件.shell 使你能不离开 gdb 就执行 UNIX shell 命令.gdb 支持很多与 UNIX shell 程序一样的命令编辑特征. 你能象在 bash 或 tcsh里那样按 Tab 键让 gdb 帮你补齐一个唯一的命令, 如果不唯一的话 gdb 会列出所有匹配的命令. 你也能用光标键上下翻动历史命令.gdb 应用举例本节用一个实例教你一步步的用 gdb 调试程序. 被调试的程序相当的简单, 但它展示了 gdb 的典型应用.下面列出了将被调试的程序. 这个程序被称为 greeting , 它显示一个简单的问候, 再用反序将它列出.#include main ()char my_string = hello there;my_print (my_string);my_print2 (my_string);void my_print (char *string)printf (The string is %sn, string);void my_print2 (char *string)char *string2;int size, i;size = strlen (string);string2 = (char *) malloc (size + 1);for (i = 0; i size; i+)string2size - i = stringi;string2size+1 = 0;printf (The string printed backward is %sn, string2);用下面的命令编译它:gcc -o test test.c这个程序执行时显示如下结果:The string is hello thereThe string printed backward is输出的第一行是正确的, 但第二行打印出的东西并不是我们所期望的. 我们所设想的输出应该是:The string printed backward is ereht olleh由于某些原因, my_print2 函数没有正常工作. 让我们用 gdb 看看问题究竟出在哪儿, 先键入如下命令:gdb greeting-注意: 记得在编译 greeting 程序时把调试选项打开.-如果你在输入命令时忘了把要调试的程序作为参数传给 gdb , 你可以在 gdb 提示符下用 file 命令来载入它:(gdb) file greeting这个命令将载入 greeting 可执行文件就象你在 gdb 命令行里装入它一样.这时你能用 gdb 的 run 命令来运行 greeting 了. 当它在 gdb 里被运行后结果大约会象这样:(gdb) runStarting program: /root/greetingThe string is hello thereThe string printed backward isProgram exited with code 041这个输出和在 gdb 外面运行的结果一样. 问题是, 为什么反序打印没有工作? 为了找出症结所在, 我们可以在 my_print2 函数的 for 语句后设一个断点, 具体的做法是在 gdb 提示符下键入 list 命令三次, 列出源代码:(gdb) list(gdb) list(gdb) list-技巧: 在 gdb 提示符下按回车健将重复上一个命令.-第一次键入 list 命令的输出如下:1 #include 23 main ()4 5 char my_string = hello there;67 my_print (my_string);8 my_print2 (my_string);9 10如果按下回车, gdb 将再执行一次 list 命令, 给出下列输出:11 my_print (char *string)12 13 printf (The string is %sn, string);14 1516 my_print2 (char *string)17 18 char *string2;19 int size, i;20再按一次回车将列出 greeting 程序的剩余部分:21 size = strlen (string);22 string2 = (char *) malloc (size + 1);23 for (i = 0; i size; i+)24 string2size - i = stringi;25 string2size+1 = 0;26 printf (The string printed backward is %sn, string2);27 根据列出的源程序, 你能看到要设断点的地方在第24行, 在 gdb 命令行提示符下键入如下命令设置断点:(gdb) break 24gdb 将作出如下的响应:Breakpoint 1 at 0x139: file greeting.c, line 24(gdb)现在再键入 run 命令, 将产生如下的输出:Starting program: /root/greetingThe string is hello thereBreakpoint 1, my_print2 (string = 0xbfffdc4 hello there) at greeting.c :2424 string2size-i=stringi你能通过设置一个观察 string2size - i 变量的值的观察点来看出错误是怎样产生的, 做法是键入:(gdb) watch string2size - igdb 将作出如下回应:Watchpoint 2: string2size - i现在可以用 next 命令来一步步的执行 for 循环了:(gdb) next经过第一次循环后, gdb 告诉我们 string2size - i 的值是 h. gdb 用如下的显示来告诉你这个信息:Watchpoint 2, string2size - iOld value = 0 000New value = 104 hmy_print2(string = 0xbfffdc4 hello there) at greeting.c:2323 for (i=0; isize; i+)这个值正是期望的. 后来的数次循环的结果都是正确的. 当 i=10 时, 表达式 string2size - i 的值等于 e, size - i 的值等于 1, 最后一个字符已经拷到新串里了.如果你再把循环执行下去, 你会看到已经没有值分配给 string20 了, 而它是新串的第一个字符, 因为 malloc 函数在分配内存时把它们初始化为空(null)字符. 所以 string2 的第一个字符是空字符. 这解释了为什么在打印 string2 时没有任何输出了.现在找出了问题出在哪里, 修正这个错误是很容易的. 你得把代码里写入 string2 的第一个字符的的偏移量改为 size - 1 而不是 size. 这是因为 string2 的大小为 12, 但起始偏移量是 0, 串内的字符从偏移量 0 到 偏移量 10, 偏移量 11 为空字符保留.为了使代码正常工作有很多种修改办法. 一种是另设一个比串的实际大小小 1 的变量. 这是这种解决办法的代码:#include main ()char my_string = hello there;my_print (my_string);my_print2 (my_string);my_print (char *string)printf (The string is %sn, string);my_print2 (char *string)char *string2;int size, size2, i;size = strlen (string);size2 = size -1;string2 = (char *) malloc (size + 1);for (i = 0; i size; i+)string2size2 - i = stringi;string2size = 0;printf (The string printed backward is %sn, string2);在Linux下调试程序一般用GDB来执行。这里简要介绍一下是否gdb调试程序的方法:(1)进入gdb调试:gdb + 已经编译通过的可执行程序 - 就进入调试模式。例如:gdb MiddlePublisher(2)r + 运行时的参数 - 开始运行可执行程序。例如 r -lxml2 -f refile(3)b + 断点 -设置调试的断点。两种:一种是:b CMSTask.cpp:200 表示在CMSTask.cpp文件的第200行设置断点。另一种:b TaskManager:buildPubWinTask 表示在执行buildPubWinTask这个函数的时候停止。(4)取消断点:dis 1 表示取消第一个断点dis 2 表示取消第二个断点(5)查看设置断点信息: info b(6)在断点停止处查看所在代码的详细信息:l(7)可以在gdb中直接编译,然后再重新运行时,gdb会直接执行新编译好的可执行程序。例如:直接在gdb下执行make后再重庆运行。(8)跟进一个函数:s如果设置的断点是在一个函数入口。到达该断点时,键入s就可以进入该函数内部进行调试。如果有多个函数就多次键入S来进入内部的函数。PS:1、在SecureCRT远程登录界面上开启多个窗口。在窗口之间切换时用:Alt+1,Alt+2.表示切换到第1个,第2个窗口。2、同样在在SecureCRT远程登录界面上要粘贴复制好的内容用:Shift+Insert。检查一切memcpy, strcpy, strcat sprintf 动态数组下标。这种问题多半世内存访问错误或者缓冲区溢出覆盖堆栈造成的。调试方法:gdb 调试程序或者gdb调试core文件 回复 更多评论 编译时加入-g调试选项,去掉-Ox选项使用gdb运行,如果中断退出,使用bt命令查看调用堆栈,如果不是可以通过thr n (n表示线程号,用 info thr查看)切换,然后bt看堆栈以上方法在kernel 2.6+gdb 6中有问题 一:列文件清单 1 List (gdb) list line1,line2 二:执行程序 要想运行准备调试的程序,可使用run命令,在它后面可以跟随发给该程序的任何参数,包括标准输入和标准输出说明符()和外壳通配符(*、?、)在内。 如果你使用不带参数的run命令,gdb就再次使用你给予前一条run命令的参数,这是很有用的。 利用set args 命令就可以修改发送给程序的参数,而使用show args 命令就可以查看其缺省参数的列表。 (gdb)set args b x (gdb) show args backtrace命令为堆栈提供向后跟踪功能。 Backtrace 命令产生一张列表,包含着从最近的过程开始的所以有效过程和调用这些过程的参数。 三:显示数据 利用print 命令可以检查各个变量的值。 (gdb) print p (p为变量名) whatis 命令可以显示某个变量的类型 (gdb) whatis p type = int * print 是gdb的一个功能很强的命令,利用它可以显示被调试的语言中任何有效的表达式。表达式除了包含你程序中的变量外,还可以包含以下内容: l 对程序中函数的调用 (gdb) print find_entry(1,0) l 数据结构和其他复杂对象 (gdb) print *table_start $8=e=reference=000,location=0x0,next=0x0 l 值的历史成分 (gdb)print $1 ($1为历史记录变量,在以后可以直接引用 $1 的值) l 人为数组 人为数组提供了一种去显示存储器块(数组节或动态分配的存储区)内容的方法。早期的调试程序没有很好的方法将任意的指针换成一个数组。就像对待参数一样,让我们查看内存中在变量h后面的10个整数,一个动态数组的语法如下所示: baselength 因此,要想显示在h后面的10个元素,可以使用h10: (gdb)print h10 $13=(-1,345,23,-234,0,0,0,98,345,10) 四:断点(breakpoint) break命令(可以简写为b)可以用来在调试的程序中设置断点,该命令有如下四种形式: l break line-number 使程序恰好在执行给定行之前停止。 l break function-name 使程序恰好在进入指定的函数之前停止。 l break line-or-function if condition 如果condition(条件)是真,程序到达指定行或函数时停止。 l break routine-name 在指定例程的入口处设置断点 如果该程序是由很多原文件构成的,你可以在各个原文件中设置断点,而不是在当前的原文件中设置断点,其方法如下: (gdb) break filename:line-number (gdb) break filename:function-name 要想设置一个条件断点,可以利用break if命令,如下所示: (gdb) break line-or-function if expr 例: (gdb) break 46 if testsize=100 从断点继续运行:countinue 命令 五断点的管理 1 显示当前gdb的断点信息: (gdb) info break 他会以如下的形式显示所有的断点信息: Num Type Disp Enb Address What 1 breakpoint keep y 0x000028bc in init_random at qsort2.c:155 2 breakpoint keep y 0x0000291c in init_organ at qsort2.c:168 (gdb) 2.删除指定的某个断点: (gdb) delete breakpoint 1 该命令将会删除编号为1的断点,如果不带编号参数,将删除所有的断点 (gdb) delete breakpoint 3.禁止使用某个断点 (gdb) disable breakpoint 1 该命令将禁止断点 1,同时断点信息的 (Enb)域将变为 n 4允许使用某个断点 (gdb) enable breakpoint 1 该命令将允许断点 1,同时断点信息的 (Enb)域将变为 y 5清除原文件中某一代码行上的所有断点 (gdb)clean number 注:number 为原文件的某个代码行的行号 六变量的检查和赋值 l whatis:识别数组或变量的类型 l ptype:比whatis的功能更强,他可以提供一个结构的定义 l set variable:将值赋予变量 l print 除了显示一个变量的值外,还可以用来赋值 七单步执行 l next 不进入的单步执行 l step 进入的单步执行 如果已经进入了某函数,而想退出该函数返回到它的调用函数中,可使用命令finish 八函数的调用 l call name 调用和执行一个函数 (gdb) call gen_and_sork( 1234,1,0 ) (gdb) call printf(“abcd”) $1=4 l finish 结束执行当前函数,显示其返回值(如果有的话) 九机器语言工具 有一组专用的gdb变量可以用来检查和修改计算机的通用寄存器,gdb提供了目前每一台计算机中实际使用的4个寄存器的标准名字: l $pc : 程序计数器 l $fp : 帧指针(当前堆栈帧) l $sp : 栈指针 l $ps : 处理器状态 十信号 gdb通常可以捕捉到发送给它的大多数信号,通过捕捉信号,它就可决定对于正在运行的进程要做些什么工作。例如,按CTRL-C将中断信号发送给gdb,通常就会终止gdb。但是你或许不想中断gdb,真正的目的是要中断gdb正在运行的程序,因此,gdb要抓住该信号并停止它正在运行的程序,这样就可以执行某些调试操作。 Handle命令可控制信号的处理,他有两个参数,一个是信号名,另一个是接受到信号时该作什么。几种可能的参数是: l nostop 接收到信号时,不要将它发送给程序,也不要停止程序。 l stop 接受到信号时停止程序的执行,从而允许程序调试;显示一条表示已接受到信号的消息(禁止使用消息除外) l print 接受到信号时显示一条消息 l noprint 接受到信号时不要显示消息(而且隐含着不停止程序运行) l pass 将信号发送给程序,从而允许你的程序去处理它、停止运行或采取别的动作。 l nopass 停止程序运行,但不要将信号发送给程序。 例如,假定你截获SIGPIPE信号,以防止正在调试的程序接受到该信号,而且只要该信号一到达,就要求该程序停止,并通知你。要完成这一任务,可利用如下命令: (gdb) handle SIGPIPE stop print 请注意,UNIX的信号名总是采用大写字母!你可以用信号编号替代信号名 如果你的程序要执行任何信号处理操作,就需要能够测试其信号处理程序,为此,就需要一种能将信号发送给程序的简便方法,这就是signal命令的任务。该 命令的参数是一个数字或者一个名字,如SIGINT。假定你的程序已将一个专用的SIGINT(键盘输入,或CTRL-C;信号2)信号处理程序设置成采 取某个清理动作,要想测试该信号处理程序,你可以设置一个断点并使用如下命令: (gdb) signal 2 continuing with signal SIGINT(2) 该程序继续执行,但是立即传输该信号,而且处理程序开始运行. 十一. 原文件的搜索 search text:该命令可显示在当前文件中包含text串的下一行。 Reverse-search text:该命令可以显示包含text 的前一行。 十二.UNIX接口 shell 命令可启动UNIX外壳,CTRL-D退出外壳,返回到 gdb. 十三.命令的历史 为了允许使用历史命令,可使用 set history expansion on 命令 (gdb) set history expansion on 小结:常用的gdb命令 backtrace 显示程序中的当前位置和表示如何到达当前位置的栈跟

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论