分享
分享赚钱 收藏 举报 版权申诉 / 50

类型gdb调试从入门到精通.doc

  • 上传人:gnk289057
  • 文档编号:7219160
  • 上传时间:2019-05-10
  • 格式:DOC
  • 页数:50
  • 大小:164KB
  • 配套讲稿:

    如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。

    特殊限制:

    部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。

    关 键  词:
    gdb调试从入门到精通.doc
    资源描述:

    1、无论是多么优秀的程序员,都难以保证自己在编写代码时不会出现任何错误,因此调试是软件开发过程中的一个必不可少的组成部分。当程序完成编译之后,它很可能无法正常运行,或者会彻底崩溃,或者不能实现预期的功能。此时如何通过调试找到问题的症结所在,就变成了摆在开发人员面前最严峻的问题。通常说来,软件项目的规模越大,调试起来就会越困难,越需要一个强大而高效的调试器作为后盾。对于 Linux 程序员来讲,目前可供使用的调试器非常多,GDB(GNU DeBugger )就是其中较为优秀的。初识 GDBGDB 是自由软件基金会(Free Software Foundation, FSF)的软件工具之一。它的作用是

    2、协助程序员找到代码中的错误。如果没有 GDB 的帮助,程序员要想跟踪代码的执行流程,唯一的办法就是添加大量的语句来产生特定的输出。但这一手段本身就可能会引入新的错误,从而也就无法对那些导致程序崩溃的错误代码进行分析。GDB 的出现减轻了开发人员的负担,他们可以在程序运行的时候单步跟踪自己的代码,或者通过断点暂时中止程序的执行。此外,他们还能够随时察看变量和内存的当前状态,并监视关键的数据结构是如何影响代码运行的。调试方法如果想对程序进行调试,必须先在用 GCC 编译源代码时加上-g 选项,以便产生GDB 所需要的调试符号信息。例如,debugme.c 是一个存在错误程序,可以使用如下的命令对其

    3、进行编译,同时产生调试符号:# gcc -g debugme.c -o debugme如果愿意的话,还可以在编译时使用“-ggdb”选项来生成更多的调试信息。由于这些调试信息中的相当一部分是 GDB 所特有的,所以生成的代码将无法在其它调试器中正常调试。对于大多数情况来说,普通的-g 选项就足够了。需要注意的是,GCC 虽然允许同时使用-g(调试)和-o(优化)选项,但优化会影响最终生成的代码,导致程序源代码和二进制代码之间的关系变得复杂起来。如果不想为调试制造障碍,建议不要将-g 和-o 选项一同使用,并且只在程序彻底调试完后才开始进行代码优化。这样调试过程将变得相对轻松和愉快。基本应用现在

    4、可以启动 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 已经准备好接收来自用户的各种调试命令了。如果想在调试环境下运行这个程序,可以使用

    5、 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最后一行

    6、输出表明程序在调用动态链接库/lib/ld-linux.so.2中的_dl_fini()函数时出现了错误,地址是0x4000c6ac。这些对调试是非常重要的线索。另外还有一种信息对调试也很重要,就是错误发生时的函数调用层级关系,可以通过执行“backtrace”命令来获得。在使用 GDB调试命令时,用户可以不必输入完整的命令名称,使用任何惟一的缩写都可以。例如“backtrace”命令就可以缩写成“back”甚至“bt”。GDB 还支持很多常用的 Shell 命令编辑特征,比如可以像在 bash 或 tcsh 中那样 按 Tab 键补齐命令。如果相关命令不惟一的话,则列出所有可能的匹配项。此外

    7、键盘上的方向键可用来翻动历史命令。GDB 是一个源代码级的调试器,使用“list”命令可以查看当前调试对象的源代码。该命令的通用格式为“list m,n”,表示显示从 m 行开始到 n 行结束的代码段,而不带任何参数的“list”命令将显示最近10行源代码。设置断点在调试有问题的代码时,在某一点停止运行往往很管用。这样程序运行到此外时会暂时挂起,等待用户的进一步输入。GDB 允许在几种不同的代码结构上设置断点,包括行号和函数名等,并且还允许设置条件断点,让程序只有在满足一定的条件时才停止执行。要根据行号设置断点,可以使用“ break linenum”命令。要根据函数名设置断点,则应该使用“b

    8、reak funcname”命令。在以上两种情况中,GDB 将在执行指定的行号或进入指定的函数之前停止执行程序。此时可以使用“print”显示变量的值,或者使用 “list”查看将要执行的代码。对于由多个源文件组成的项目,如果想在执行到非当前源文件的某行或某个函数时停止执行,可以使用如下形式的命令:# break 20041126110727.htm:linenum # break 20041126110727.htm:funcname条件断点允许当一定条件满足时暂时停止程序的执行。它对于调试来讲非常有用。设置条件断点的正确语法如下:break linenum if expr break fu

    9、ncname if expr其中 expr 是一个逻辑表达式。当该表达式的值为真时,程序将在该断点处暂时挂起。例如,下面的命令将在 debugme 程序的第38行设置一个条件断点。当程序运行到该行时,如果 count 的值等于3,就将暂时停止执行:(gdb) break 38 if count=3设置断点是调试程序时最常用到的一种手段。它可以中断程序的运行,给程序员一个单步跟踪的机会。使用命令“ break main”在 main 函数上设置断点可以在程序启动时就开始进行跟踪。接下去使用“continue”命令继续执行程序,直到遇到下一个断点。如果在调试时设置了很多断点,可以随时使用“info

    10、 breakpoints”命令来查看设置的断点。此外,开发人员还可以使用“delete”命令删除断点,或者使用“disable”命令来使设置的断点暂时无效。被设置为无效的断点在需要的时候可以用“enable”命令使其重新生效。观察变量GDB 最有用的特性之一是能够显示被调试程序中几乎任何表达式、变量或数组的类型和值,并且能够用编写程序所用的语言打印出任何合法表达式的值。查看数据最简单的办法是使用“print”命令,只需在“print”命令后面加上变量表达式,就可以打印出此变量表达式的当前值,示例如下:(gdb) print str $1 = 0x40015360 “Happy new year

    11、!n“从输出信息中可以看出,输入字符串被正确地存储在了字符指针 str 所指向的内存缓冲区中。除了给出变量表达式的值外, “print”命令的输出信息中还包含变量标号 ($1)和对应的内存地址(0x40015360)。变量标号保存着被检查数值的历史记录,如果此后还想访问这些值,就可以直接使用别名而不用重新输入变量表达式。如果想知道变量的类型,可以使用“whatis”命令,示例如下:(gdb) whatis str type = char *对于第一次调试别人的代码,或者面对的是一个异常复杂的系统时, “whatis”命令的作用不容忽视。单步执行为了单步跟踪代码,可以使用单步跟踪命令“step”

    12、,它每次执行源代码中的一行。在 GDB 中可以使用许多方法来简化操作,除了可以将“step”命令简化为“s”之外,还可以直接输入回车键来重复执行前面一条命令。除了可以用“step”命令来单步运行程序之外,GDB 还提供了另外一条单步调试命令“next”。两者功能非常相似,差别在于如果将要被执行的代码行中包含函数调用,使用 step命令将跟踪进入函数体内,而使用 next 命令则不进入函数体内。在进入下一部分之前,使用下面的命令退出 GDB:(gdb) quit分析核心(core)文件在程序发生崩溃时,有时可能无法直接运行 GDB 来进行调试。比如程序可能是在另外一台机器上运行的,或者因为程序对

    13、时间比较敏感,所以手动跟踪调试会产生无法接受的延迟等。遇到这些情况,就只能等到程序运行结束后才能判断崩溃的原因了。这时需要用到Linux 提供的 core dump 机制。当程序中出现内存操作错误时,会发生崩溃并产生核心文件。使用 GDB 可以对产生的核心文件进行分析,找出程序是在什么时候崩溃的和在崩溃之前程序都做了些什么。当然,如果要用 GDB 来分析核心文件,也必须在编译时加上-g 选项来产生调试符号表。在分析核心文件之前必须确认系统是否允许生成核心文件,很多 Linux 发行版在默认时禁止生成核心文件。为了生成核心文件,首先必须执行下面的命令:# ulimit -c unlimited然

    14、后就可以生成核心文件了。这里仍以前面的 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

    15、, 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 0x40042

    16、91f 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”命令在不同的函数调用上下文中切换。开发人员使

    17、用这三条命令可以很轻松地实现调用栈的遍历。在分析核心文件时,通过将遍历栈的命令和检查变量值的“print”命令结合起来,就能够复原程序运行时的全部景象。调试其它进程有时会遇到一种很特殊的调试需求,对当前正在运行的其它进程进行调试。这种情况有可能发生在那些无法直接在调试器中运行的进程身上,例如有的进程只能在系统启动时运行。另外如果需要对进程产生的子进程进行调试的话,也只能采用这种方式。GDB 可以对正在执行的程序进行调度,它允许开发人员中断程序并查看其状态,之后还能让这个程序正常地继续执行。GDB 提供了两种方式来调试正在运行的进程:一种是在 GDB 命令行上指定进程的PID,另一种是在 GDB

    18、 中使用“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: /hom

    19、e/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 如果想知道程序现

    20、在运行到了哪里,同样可以使用“backtrace”命令。当然也可以使用“step”命令对程序进行单步调试。在完成调试之后,不要忘记用 detach 命令断开连接,让被调试的进程可以继续正常运行:GDB 是 Linux 下一个最基本的调试器,其功能非常丰富。完整地介绍 GDB 的功能可能需要几百页,本文只涵盖了 GDB 的一些最常见的用法。作为一个合格的 Linux 程序员,花在 GDB 上的功夫和时间越多,从调试中获得的益处就越多。 Linux 包含了一个叫 gdb 的 GNU 调试程序. gdb 是一个用来调试 C 和 C+ 程序的强力调试器. 它使你能在程序运行时观察程序的内部结构和内存的

    21、使用情况. 以下是 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

    22、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 文件, 或者与一个正在运行的程序相连. 你可以

    23、参考 gdb 指南页或在命令行上键入 gdb -h 得到一个有关这些选项的说明的简单列表 .为调试编译代码(Compiling Code for Debugging)为了使 gdb 正常工作, 你必须使你的程序在编译时包含调试信息. 调试信息包含你程序里的每个变量的类型和在可执行文件里的地址映射以及源代码的行号. gdb 利用这些信息使源代码和机器码相关联.在编译时用 -g 选项打开调试选项.gdb 基本命令gdb 支持很多的命令使你能实现不同的功能. 这些命令从简单的文件装入到允许你检查所调用的堆栈内容的复杂命令, 表27.1列出了你在用 gdb 调试时会用到的一些命令. 想了解 gdb 的

    24、详细使用请参考 gdb 的指南页.表 27.1. 基本 gdb 命令.命 令 描 述file 装入想要调试的可执行文件.kill 终止正在调试的程序.list 列出产生执行文件的源代码的一部分.next 执行一行源代码但不进入函数内部.step 执行一行源代码而且进入函数内部.run 执行当前被调试的程序quit 终止 gdbwatch 使你能监视一个变量的值而不管它何时被改变.break 在代码里设置断点, 这将使程序执行到这里时被挂起 .make 使你能不退出 gdb 就可以重新产生可执行文件.shell 使你能不离开 gdb 就执行 UNIX shell 命令.gdb 支持很多与 UNI

    25、X shell 程序一样的命令编辑特征. 你能象在 bash 或 tcsh 里那样按 Tab 键让 gdb 帮你补齐一个唯一的命令, 如果不唯一的话 gdb 会列出所有匹配的命令. 你也能用光标键上下翻动历史命令.gdb 应用举例本节用一个实例教你一步步的用 gdb 调试程序. 被调试的程序相当的简单, 但它展示了 gdb 的典型应用.下面列出了将被调试的程序. 这个程序被称为 greeting , 它显示一个简单的问候, 再用反序将它列出.#include main ()char my_string = “hello there“;my_print (my_string);my_print2

    26、 (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 23 main ()4 5 char my_string = “hello there“;67 my_print (my_string);8 my_print2 (my_string);

    27、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 main ()char m

    28、y_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 ) 和外壳通配符(* 、?、 )在内。 如果你使用

    29、不带参数的 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

    30、 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 人为数组 人为数组提供了一种去显示存储器块(数组节或动态分配的存储区)内容的

    31、方法。早期的调试程序没有很好的方法将任意的指针换成一个数组。就像对待参数一样,让我们查看内存中在变量 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 使程序恰好在进入指

    32、定的函数之前停止。 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-functio

    33、n 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.删除指定的某个断点: (

    34、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:识别数

    35、组或变量的类型 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 结束执行当前函数,显示其返回值(如果有的话)

    36、 九机器语言工具 有一组专用的 gdb 变量可以用来检查和修改计算机的通用寄存器,gdb 提供了目前每一台计算机中实际使用的4个寄存器的标准名字: l $pc : 程序计数器 l $fp : 帧指针(当前堆栈帧) l $sp : 栈指针 l $ps : 处理器状态 十信号 gdb 通常可以捕捉到发送给它的大多数信号,通过捕捉信号,它就可决定对于正在运行的进程要做些什么工作。例如,按 CTRL-C 将中断信号发送给 gdb,通常就会终止 gdb。但是你或许不想中断 gdb,真正的目的是要中断 gdb 正在运行的程序,因此, gdb 要抓住该信号并停止它正在运行的程序,这样就可以执行某些调试操作。

    37、 Handle 命令可控制信号的处理,他有两个参数,一个是信号名,另一个是接受到信号时该作什么。几种可能的参数是: l nostop 接收到信号时,不要将它发送给程序,也不要停止程序。 l stop 接受到信号时停止程序的执行,从而允许程序调试;显示一条表示已接受到信号的消息(禁止使用消息除外) l print 接受到信号时显示一条消息 l noprint 接受到信号时不要显示消息(而且隐含着不停止程序运行) l pass 将信号发送给程序,从而允许你的程序去处理它、停止运行或采取别的动作。 l nopass 停止程序运行,但不要将信号发送给程序。 例如,假定你截获 SIGPIPE 信号,以防

    38、止正在调试的程序接受到该信号,而且只要该信号一到达,就要求该程序停止,并通知你。要完成这一任务,可利用如下命令: (gdb) handle SIGPIPE stop print 请注意,UNIX 的信号名总是采用大写字母!你可以用信号编号替代信号名 如果你的程序要执行任何信号处理操作,就需要能够测试其信号处理程序,为此,就需要一种能将信号发送给程序的简便方法,这就是 signal 命令的任务。该 命令的参数是一个数字或者一个名字,如 SIGINT。假定你的程序已将一个专用的 SIGINT(键盘输入,或 CTRL-C;信号2 )信号处理程序设置成采 取某个清理动作,要想测试该信号处理程序,你可以

    39、设置一个断点并使用如下命令: (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 hi

    40、story expansion on 小结:常用的 gdb 命令 backtrace 显示程序中的当前位置和表示如何到达当前位置的栈跟踪(同义词:where) breakpoint 在程序中设置一个断点 cd 改变当前工作目录 clear 删除刚才停止处的断点 commands 命中断点时,列出将要执行的命令 continue 从断点开始继续执行 delete 删除一个断点或监测点;也可与其他命令一起使用 display 程序停止时显示变量和表达时 down 下移栈帧,使得另一个函数成为当前函数 frame 选择下一条 continue 命令的帧 info 显示与该程序有关的各种信息 jump

    41、 在源程序中的另一点开始运行 kill 异常终止在 gdb 控制下运行的程序 list 列出相应于正在执行的程序的原文件内容 next 执行下一个源程序行,从而执行其整体中的一个函数 print 显示变量或表达式的值 pwd 显示当前工作目录 pype 显示一个数据结构(如一个结构或 C+类)的内容 quit 退出 gdb reverse-search 在源文件中反向搜索正规表达式 run 执行该程序 search 在源文件中搜索正规表达式 set variable 给变量赋值 signal 将一个信号发送到正在运行的进程 step 执行下一个源程序行,必要时进入下一个函数 undisplay

    42、 display 命令的反命令,不要显示表达式 until 结束当前循环 up 上移栈帧,使另一函数成为当前函数 watch 在程序中设置一个监测点(即数据断点) whatis 显示变量或函数类型 * GNU 的调试器称为 gdb,该程序是一个交互式工具,工作在字符模式。在 X Window 系统中,有一个 gdb 的前端图形工具,称为 xxgdb。gdb 是功能强大的调试程序,可完成如下的调试任务: * 设置断点; * 监视程序变量的值; * 程序的单步执行; * 修改变量的值。 在可以使用 gdb 调试程序之前,必须使用 -g 选项编译源文件。可在 makefile 中如下定义 CFLAG

    43、S 变量: CFLAGS = -g 运行 gdb 调试程序时通常使用如下的命令: gdb progname 在 gdb 提示符处键入 help,将列出命令的分类,主要的分类有: * aliases:命令别名 * breakpoints:断点定义; * data:数据查看; * files:指定并查看文件; * internals:维护命令; * running:程序执行; * stack:调用栈查看; * statu:状态查看; * tracepoints:跟踪程序执行。 键入 help 后跟命令的分类名,可获得该类命令的详细清单。 gdb 的常用命令 命令 解释 break NUM 在指定的

    44、行上设置断点。 bt 显示所有的调用栈帧。该命令可用来显示函数的调用顺序。 clear 删除设置在特定源文件、特定行上的断点。其用法为 clear FILENAME:NUM continue 继续执行正在调试的程序。该命令用在程序由于处理信号或断点而 导致停止运行时。 display EXPR 每次程序停止后显示表达式的值。表达式由程序定义的变量组成。 file FILE 装载指定的可执行文件进行调试。 help NAME 显示指定命令的帮助信息。 info break 显示当前断点清单,包括到达断点处的次数等。 info files 显示被调试文件的详细信息。 info func 显示所有的

    45、函数名称。 info local 显示当函数中的局部变量信息。 info prog 显示被调试程序的执行状态。 info var 显示所有的全局和静态变量名称。 kill 终止正被调试的程序。 list 显示源代码段。 make 在不退出 gdb 的情况下运行 make 工具。 next 在不单步执行进入其他函数的情况下,向前执行一行源代码。 print EXPR 显示表达式 EXPR 的值。 *gdb 使用范例* - 清单 一个有错误的 C 源程序 bugging.c 代码: - 1 include 2 3 static char buff 256; 4 static char* strin

    46、g; 5 int main () 6 7 printf (“Please input a string: “); 8 gets (string); 9 printf (“nYour string is: %sn“, string); 10 - 上面这个程序非常简单,其目的是接受用户的输入,然后将用户的输入打印出来。该程序使用了一个未经过初始化的字符串地址 string,因此,编译并运行之后,将出现 Segment Fault 错误: $ gcc -o bugging -g bugging.c $ ./bugging Please input a string: asfd Segmentatio

    47、n fault (core dumped) 为了查找该程序中出现的问题,我们利用 gdb,并按如下的步骤进行: 1运行 gdb bugging 命令,装入 bugging 可执行文件; 2执行装入的 bugging 命令 run; 3使用 where 命令查看程序出错的地方; 4利用 list 命令查看调用 gets 函数附近的代码; 5唯一能够导致 gets 函数出错的因素就是变量 string。用 print 命令查看 string 的值; 6在 gdb 中,我们可以直接修改变量的值,只要将 string 取一个合法的指针值就可以了,为此,我们在第8行处设置断点 break 8; 7程序重新运行到第 8行处停止,这时,我们可以用 set variable 命令修改 string 的取值; 8然后继续运行,将看到正确的程序运行结果 gdb 对于多线程程序的调试有如下的支持

    展开阅读全文
    提示  道客多多所有资源均是用户自行上传分享,仅供网友学习交流,未经上传用户书面授权,请勿作他用。
    关于本文
    本文标题:gdb调试从入门到精通.doc
    链接地址:https://www.docduoduo.com/p-7219160.html
    关于我们 - 网站声明 - 网站地图 - 资源地图 - 友情链接 - 网站客服 - 联系我们

    道客多多用户QQ群:832276834  微博官方号:道客多多官方   知乎号:道客多多

    Copyright© 2025 道客多多 docduoduo.com 网站版权所有世界地图

    经营许可证编号:粤ICP备2021046453号    营业执照商标

    1.png 2.png 3.png 4.png 5.png 6.png 7.png 8.png 9.png 10.png



    收起
    展开