gdb使用说明

目录
1GDB简介  6
2GDB使用示例    6
3GDB的使用 10
3.1进入与退出GDB 10
3.1.1执行GDB  10
3.1.2选择文件   11
3.1.3选择模式   12
3.1.4退出GDB  13
3.1.5Shell命令    13
3.2GDB命令    13
3.2.1命令句法   13
3.2.2命令的完成  14
3.2.3获取帮助   15
3.3在GDB下运行程序    16
3.3.1为调试进行编译    16
3.3.2启动被调试程序    17
3.3.3程序参数   17
3.3.4程序环境   17
3.3.5程序工作目录 18
3.3.6程序输入输出 18
3.3.7调试一个正在运行的进程    18
3.3.8杀死子进程  18
3.3.9附加进程信息 18
3.3.10调试多线程程序   19
3.3.11调试多进程程序   19
3.4停止与继续    19
3.4.1断点、检查点和异常  19
3.4.2设置断点   19
3.4.3设置检查点  20
3.4.4断点与异常  21
3.4.5删除断点   21
3.4.6禁用断点   21
3.4.7中断条件   21
3.4.8断点命令列表 22
3.4.9断点菜单   22
3.4.10继续与单步执行   22
3.4.11信号    23
3.4.12停止与启动多线程程序    24
3.5检查堆栈 24
3.5.1堆栈帧    24
3.5.2回溯 24
3.5.3选择帧    25
3.5.4有关帧的信息 25
3.5.5MIPS机器和函数堆栈    26
3.6检查源文件    26
3.6.1打印源码行  26
3.6.2搜索源文件  27
3.6.3指定源目录  27
3.6.4源码和机器代码    27
3.7检查数据 28
 
GDB 使用说明
1   GDB简介
    GDB 一类的调试器可以用来观察另一个程序在执行时的内部操作,或着查看另一个程序出错时发生了什么。为了帮助找出程序中的 Bug,GDB 主要可以做以下四件事(加上作为支持的其它一些功能):
    1.  运行程序,设置所有能影响程序运行的东西。
    2.  保证程序在指定的条件下停止。
    3.  当程序停止时,可以检查发生了什么。
    4.  改变程序,这样可以试着修正某个Bug引起的问题,然后继续查找另一个Bug。
    GDB可以用来调试C和C++写的程序。细节请参考“C 和C++”一节。
    GDB部分支持Modula-2和Chill语言,Modula-2语言的细节请参考“Modula-2”一节,目前还没有有关Chill语言的文档。
    GDB目前还不能调试使用了集合、子域、文件变量或嵌套函数的Pascal程序,也不支持表达式输入、值输出或使用Pascal句法的类似特性。
    GDB可以用来调试Fortran语言编写的程序,虽然它目前还不支持表达式输入、值输出或使用Fortran句法的类似特性。可能需要使用一个尾随的下划线来引用某些变量。
    GDB 是受 GNU 的 GPL 保护的自由软件,其最初的作者是 Richard Stallman,随后有认同GNU宗旨的程序员加入了后续版本的开发。
2   GDB 使用示例
    在开始使用调试器 GDB 时,记住一组常用命令就足够了。有时间或者有进一步的需求时,可以阅读本文档以了解其全部内容。本节通过一个例子来说明这些常用命令的使用方法。
    例子中用户的输入用粗体字表示,以区别于程序的输出。
    在一个通用宏处理程序GNU m4的初期版本中存在以下Bug:有时改变引用字符串的缺省值会导致从另一个宏定义中获取一个宏定义的命令不起作用。下面我们先定义宏foo为0000,然后使用m4的内建defn把bar定义为相同的东西。但是,当把开引号字符串改为<QUOTE>,闭引号字符串改为<UNQUOTE>时,在定义新同义词baz时同样的过程就失败了:
    $ cd gnu/m4
    $ ./m4
    define(foo,0000)
    
    foo
    0000
    define(bar,defn(`foo'))
    
    bar
    0000
    changequote(<QUOTE>,<UNQUOTE>)
    
    define(baz,defn(<QUOTE>foo<UNQUOTE>))
    baz
    C-d
    m4: End of input: 0: fatal error: EOF in string
    让我们用GDB来看看发生了些什么吧。
    $ gdb m4
    GDB is free software and you are welcome to 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.
    
    GDB , Copyright 1995 Free Software Foundation, Inc...
    (gdb)
    GDB只读入足够的符号数据以了解需要时在哪里能找到剩下的符号就行了,因此,第一个提示符出现得非常快。接着让GDB使用一个比通常情况下窄一些的显示宽度。
    (gdb) set width 70
    我们需要知道m4内建的changequote是如何工作的。通过阅读源码,我们知道相关的子例程是m4_changequote,所以在那里用GDB的break命令设置一个断点。
    (gdb) break m4_changequote
    Breakpoint 1 at 0x62f4: file builtin.c, line 879.
    使用run命令,我们在GDB的控制下运行m4;在控制到达m4_changequote子例程之前,程序都正常运行:
    (gdb) run
    Starting program: /work/Editorial/gdb/gnu/m4/m4
    define(foo,0000)
    
    foo
    0000
    为了触发断点,我们调用changequote。GDB暂停m4的运行,显示停止时的上下文信息。
    changequote(<QUOTE>,<UNQUOTE>)
    
    Breakpoint 1, m4_changequote (argc=3, argv=0x33c70) 
        at builtin.c:879
    879         if (bad_argc(TOKEN_DATA_TEXT(argv[0]),argc,1,3))
    现在使用命令n (next)执行到当前函数的下一行。
    (gdb) n
    882         set_quotes((argc >= 2) ? TOKEN_DATA_TEXT(argv[1])\
     : nil,
    set_quotes看起来是一个可能的子例程。可以用命令s (step)代替next进入子例程。step会进入要执行的任一子例程的下一行,所以就进入了set_quotes。
    (gdb) s
    set_quotes (lq=0x34c78 "<QUOTE>", rq=0x34c88 "<UNQUOTE>")
        at input.c:530
    530         if (lquote != def_lquote)
    表明m4当前暂停的子例程(及其参数)的显示被成为堆栈帧显示。它显示了堆栈的概况。我们可以用backtrace命令(可简写为bt)来看看当前在堆栈中所处的位置:backtrace命令显示每个活动的子例程的堆栈帧。
    (gdb) bt
    #0  set_quotes (lq=0x34c78 "<QUOTE>", rq=0x34c88 "<UNQUOTE>")
        at input.c:530
    #1  0x6344 in m4_changequote (argc=3, argv=0x33c70) 
        at builtin.c:882
    #2  0x8174 in expand_macro (sym=0x33320) at macro.c:242
    #3  0x7a88 in expand_token (obs=0x0, t=209696, td=0xf7fffa30)
        at macro.c:71
    #4  0x79dc in expand_input () at macro.c:40
    #5  0x2930 in main (argc=0, argv=0xf7fffb20) at m4.c:195
    再多执行几行看看发生了什么。前两次,可以使用“s”;随后两次用n以避免进入xstrdup子例程。
    (gdb) s
    0x3b5c  532         if (rquote != def_rquote)
    (gdb) s
    0x3b80  535         lquote = (lq == nil || *lq == '\0') ?  \
    def_lquote : xstrdup(lq);
    (gdb) n
    536         rquote = (rq == nil || *rq == '\0') ? def_rquote\
     : xstrdup(rq);
    (gdb) n
    538         len_lquote = strlen(rquote);
    最后一行看起来有点奇怪;我们可以检查变量lquote和rquote来看看它们是否为新定义的左右引号。我们使用命令p (print)来查看它们的值。
    (gdb) p lquote
    $1 = 0x35d40 "<QUOTE>"
    (gdb) p rquote
    $2 = 0x35d50 "<UNQUOTE>"
    lquote和rquote确实是新定义的左右引号。要看看上下文,我们可以使用l (list)命令来显示包含当前行的10行源码。
    (gdb) l
    533             xfree(rquote);
    534
    535         lquote = (lq == nil || *lq == '\0') ? def_lquote\
     : xstrdup (lq);
    536         rquote = (rq == nil || *rq == '\0') ? def_rquote\
     : xstrdup (rq);
    537
    538         len_lquote = strlen(rquote);
    539         len_rquote = strlen(lquote);
    540     }
    541
    542     void
    让我们单步执行设置len_lquote和len_rquote的两行,然后检查那些变量的值。
    (gdb) n
    539         len_rquote = strlen(lquote);
    (gdb) n
    540     }
    (gdb) p len_lquote
    $3 = 9
    (gdb) p len_rquote
    $4 = 7
    假如len_lquote和len_rquote意味着lquote和rquote相应的长度,这看起来肯定有错。我们可以用p命令把它们设置为更好的值,因为它能打印出任一表达式的值,而表达式可以包括子例程调用和设置。
    (gdb) p len_lquote=strlen(lquote)
    $5 = 7
    (gdb) p len_rquote=strlen(rquote)
    $6 = 9
    这足以修补使用新引号和m4内建defn带来的问题吗?用c (continue)命令继续执行m4,然后尝试原来曾引起麻烦的那个例子:
    (gdb) c
    Continuing.
    
    define(baz,defn(<QUOTE>foo<UNQUOTE>))
    
    baz
    0000
    成功了!新的引号与缺省值一样起作用了。问题看来出自两个类型被定义了错误的长度。给m4一个EOF作为输入来退出m4:
    C-d
    Program exited normally.
    信息“Program exited normally.”是来自GDB;它表明m4结束执行。我们可以用GDB的quit命令来结束GDB。
    (gdb) quit
3   GDB的使用
    以下对GDB的使用及命令分别进行了简要的说明,具体应用中如果有疑问,可以查看相应的帮助信息。
.1  进入与退出GDB
    本节讨论如何启用GDB和如何退出。其要点是:
        * 键入“gdb”启用GDB。
        * 键入quit或C-d退出。
.1  执行GDB
    运行程序gdb就执行了GDB。一旦启用,GDB就从终端读入命令,直到退出。
    在运行gdb时可以使用各种参数和选项,指定一开头的调试环境。这里描述的命令行选项覆盖了各种情况;在某些环境下,有些选项不可用。
    启动GDB最常见的方法是使用一个指定可执行程序的参数:
    gdb program
    还可以指定一个可执行程序和一个core文件来启动GDB:
    gdb program core
    如果想调试一个正在运行的进程,可以指定一个进程ID作为第二个参数:
    gdb program 1234
    将使GDB与进程1234联系起来(除非有一个文件名为“1234”;GDB先检查内存文件)。
    要利用第二个参数带来的便利需要一个相对完全的操作系统;在把GDB用作一块裸板的远程调试器时,可能没有什么进程的概念,也经常没法获得core文件。
    使用-silent可以在运行gdb时不显示那些描述GDB无保证的开头信息:
    gdb -silent
    使用命令行选项可以进一步控制GDB启动的方式。GDB会提示可用的选项。
    键入
    gdb -help
    可以显示所有可用选项及使用方法的简要描述(“gdb -h”与之等同。)
    所有选项和参数都按照顺序进行处理。仅在使用“-x”选项时顺序有一点不同。
.2  选择文件
    在GDB启动时,它把任何一个不带选项前缀的参数都当作为一个可执行文件或core文件(或进程ID),就象在前面加了-se或-c选项。gdb把第一个前面没有选项说明的参数看作前面加了-se选项,而第二个(如果有的话)看作是跟着-c选项后面的。
    很多选项都有长短两种格式,下表把它们都列了出来。即使从把它们截断了,只要足以与其它选项相区别,GDB都能识别出来。如果愿意的话,还可以用“--”来代替“-”作为选项参数的标识。
    -symbols file
    -s file
    从文件file中读出符号表。
    -exec file
    -e file
    适当时把文件file作为可执行文件来运行,并结合core dump来检查数据。
    -se file
    从文件file中读出符号表并把file作为可执行文件。
    -core file
    -c file
    把文件file作为core dump来检查。
    -c number
    与进程ID相联系,与使用attach命令一样(除非有一个名为number的core-dump格式文件,那样“-c”就把文件指定为core-dump读入)。
    -command file
    -x file
    从文件file里执行GDB命令。参见“命令文件”一节。
    -directory directory
    -d directory
    把directory加入到搜索源文件的路径里。
    -m
    -mapped
    警告:此选项依赖于操作系统,不是所有的系统都支持。
    如果在系统中可以通过mmap系统调用来得到内存映射文件,就可以使用该选项让GDB把程序里的符号写到当前目录下一个可重用的文件里。若正在调试的程序叫“/tmp/fred”,那么映射符号文件名就为“./fred.syms”。下一次用GDB调试时会注意到该文件的存在,并可以迅速从它映射出符号信息,而不用从可执行程序读入符号表。“.syms”文件与GDB所运行的主机有关。它保持内部GDB符号表的一个确切映像,不能在多主机平台上交叉共享。
    -r
    -readnow
    立即读入每个符号文件的全部符号表,而不是缺省地在需要时逐渐读入。这使启动变慢,但后面的操作会快一些。
    选项-mapped和-readnow一般结合在一起使用以构造一个包含完整符号信息的“.syms”文件。(参见“指定文件的命令”一节)生成一个未来使用的“.syms”文件的命令为:
    gdb -batch -nx -mapped -readnow programname
.3  选择模式
    GDB可以运行在多种模式下——如批处理模式或静默模式。
    -nx
    -n       不执行初始化文件(一般叫“.gdbinit”)里的命令。通常这些文件里的命令在命令选项和参数处理完之后被执行。参见“命令文件”一节。
    -quiet
    -q       “静默”。不打印简介和版权信息。在批处理模式下也不打印这些信息。
    -batch
    运行在批处理模式下。在处理完所有以“-x”指定的命令文件(如果没有用“-n”禁止的话,还包括所有初始化文件中的命令)后退出并返回状态0。如果在执行命令文件中的GDB命令时出错,退出并返回非零的状态。在把GDB作为过滤器使用时,批处理模式比较有用,例如在另一台计算机上下载并运行一个程序;因此,在批处理模式下运行时不显示信息
    Program exited normally.
    (正常情况下这是在GDB控制下运行程序终止时所发出的信息)。
    -cd directory
    运行GDB时把directory作为工作目录,而不是当前目录。
    -fullname
    -f       在GNU Emacs把GDB作为子进程运行时设置该选项。它让GDB以一种标准的可识别方式,每次显示一个堆栈帧(包括程序每次的暂停)地输出完整的文件名和行号。这种可识别格式看起来是两个“\32”字符后跟文件名、行号与逗号分隔的字符位置以及一个换行符。Emacs和GDB接口程序用两个“\32”字符作为显示帧源码的信号。
    -b bps
    设置远程调试时GDB使用的串口线速度(波特率或每秒的比特数)。
    -tty device
    运行时使用device作为程序的标准输入输出。
.4  退出GDB
    要退出GDB,使用quit命令(缩写为q),或者键入文件结束符(通常为C-d)。如果没提供表达式,GDB将正常终止;否则,用表达式的结果作为错误码终止。
    中断(通常为C-c)并不能退出GDB,只是终止正在处理的GDB命令并返回GDB命令行。在任意时刻键入中断符都是安全的,因为GDB只有在安全的时刻才会使中断生效。
    如果GDB被用来控制一个联接的进程或设备,可以用detach命令来释放它(参见“调试已运行的进程”一节)。
.5  Shell命令
    如果在调试过程中需要偶尔执行一下shell命令,无需离开或暂停GDB,可以如下使用shell命令:
    shell command string
    用一个标准的shell来执行command string。如果环境变量SHELL存在的话,由它决定运行哪一个shell。否则,GDB使用/bin/sh。
    在开发环境中经常需要用到make程序。不必为此在GDB中使用shell命令:
    make make-args
    使用指定参数执行make程序。它等价于“shell make make-args”。
.2  GDB命令
    只要缩写是不含糊的,GDB命令就可以简写为开头的若干个字母;而且简单地使用回车就可以重复特定的命令。使用TAB键可以让GDB完成命令的剩余部分(如果有多种可能,会显示可用的几个命令)。
.1  命令句法
    一个GDB命令是一行简单的输入。对该行的长度没有限制。它由命令名称开头,后接参数的意义依赖于命令名称。某些命令名不接受任何参数。
    空行作为GDB的输入(简单地回车)意味着重复上一个命令。有些命令(如run)不能如此重复;这些命令在无条件重复时会引起麻烦,而且一般也没人愿意重复使用它们。
    list和x命令在用回车键重复时可以重构参数,而不是完全地重复。这样在扫描源码或内存时就简单了许多。
    在GDB中回车键还有另一种用途:将过长的输出分段,类似于通用命令more(参见“屏幕大小”一节)。由于此时很容易键入多个回车键,在产生该类显示的命令之后GDB禁止命令重复的功能。
    从#开始到行尾之间的文本被视为注释。这主要用在命令文件里(参见“命令文件”一节)。
.2  命令的完成
    如果只有一种可能,GDB可以代为填充命令中的剩余部分;在任意时刻,GDB都可以显示命令中下一个词的可用选择。这对GDB命令、GDB子命令和程序中的符号名都起作用。
    若要由GDB代为填充一个词的剩余部分,只要按TAB键就可以了。若只有一种可能,GDB完成该词并等待命令的完成(或键入回车来输入)。例如,如果键入
    (gdb) info bre TAB
    GDB完成“breakpoints”的剩余部分,因为它是唯一以“bre”开头的info子命令:
    (gdb) info breakpoints
    此时可以敲回车运行info breakpoints命令,如果“breakpoints”不是希望的命令,也可以敲退格键并输入其它的东西。(如果能确定希望的就是info breakpoints,也可以直接在“info bre”后敲回车,使用命令的缩写,而不是完整的命令)。
    如果在键入TAB键后下一个词存在多个选择,GDB会发出一声振铃。然后可以再键入若干字符并再次尝试,或者再按一次TAB键;GDB显示该词所有可能的完全形式。如下例:
    (gdb) b make_ TAB
    GDB sounds bell; press TAB again, to see:
    make_a_section_from_file     make_environ               
    make_abs_section            make_function_type         
    make_blockvector            make_pointer_type          
    make_cleanup               make_reference_type        
    make_command             make_symbol_completion_list
    (gdb) b make_
    在显示完所有可能后,GDB复制你的部分输入(例中的“b make_”)让你来完成该命令。
    如果只是想查看一下可用的选择,可以键入M-?,而不用敲两下TAB键。M-?即META-?。可以在敲?时按下键盘上设计为META shift的键,或者在ESC键后敲?来输入这一组合键。
    有时所需要的字符串可能包含GDB在词的定义里一般不包括的括号或其它字符。为了在此情况下实现词的完成,需要在GDB命令里用‘(单引号)把词包起来。如:
    (gdb) b 'bubble( M-?
    bubble(double,double)    bubble(int,int)
    (gdb) b 'bubble(
    这一般在输入C++函数名时会用到。
    在某些情况下,GDB会告诉你某名称需要使用引号。此时,如果一开始没键入引号,GDB会代为插入引号:
    (gdb) b bub TAB
    GDB alters your input line to the following, and rings a bell:
    (gdb) b 'bubble(
.3  获取帮助
    使用命令help可以获得GDB对其命令的帮助信息。
    help
    h     不带参数使用help可以显示命令类名的简短列表:
    (gdb) help
    List of classes of commands:
    
    running -- Running the program
    stack -- Examining the stack
    data -- Examining data
    breakpoints -- Making program stop at certain points
    files -- Specifying and examining files
    status -- Status inquiries
    support -- Support facilities
    user-defined -- User-defined commands
    aliases -- Aliases of other commands
    obscure -- Obscure features
    
    Type "help" followed by a class name for a list of 
    commands in that class.
    Type "help" followed by command name for full 
    documentation.
    Command name abbreviations are allowed if unambiguous.
    (gdb)
    help class
    使用一个类名作为参数,可以得到该类命令的列表。例如,下面就是status类的帮助显示:
    (gdb) help status
    Status inquiries.
    
    List of commands:
    
    show -- Generic command for showing things set with "set"
    info -- Generic command for printing status
    
    Type "help" followed by command name for full documentation.
    Command name abbreviations are allowed if unambiguous.
    (gdb)
    help command
    使用命令名作为help的参数,GDB会显示如何使用该命令的一短段说明。
    complete args
    命令complete args会列出以args开头的所有可能的命令的完整形式。如:
    complete i 的结果为:
    info
    inspect
    ignore
    除了help,还可以使用GDB命令info和show来查看程序的状态或GDB本身的状态。每个命令都支持多个查询主题。
    info命令是描述程序状态的,用help info可以得到info子命令的完整列表。例如,info args可以列出传给程序的参数,info registers可以列出当前使用的寄存器,而info breakpoints列出设置的断点。
    set命令可以把一个表达式的值赋给一个环境变量。如set prompt $就会把GDB的提示符设为$。
    show命令是描述GDB本身的状态。使用set命令可以改变大部分show显示出来的状态。用不带参数的show命令可以显示所有可设置的参数及其当前值;也可以用info set来显示。这二者的显示相同。下面三个show子命令没有相应的set命令:
    show version
    显示运行的GDB版本。在报告Bug,或同时使用多个GDB版本时,需要了解版本信息。
    show copying
    显示有关GDB复制的许可信息。
    show warranty
    显示GNU的“无保证”声明。
.3  在GDB下运行程序
    在GDB下运行程序之前,必须先在编译时生成调试信息。可以在选定的环境里使用参数启动GDB,可以重新定向程序的输入输出、调试一个正在运行的进程、或杀死一个子进程。
.1  为调试进行编译
    编译时生成的调试信息存储在目标文件中;它描述了每个变量或函数的数据类型以及源码行号与可执行代码地址间的对应关系。要得到调试信息,在运行编译器时要指定“-g”选项。
    GCC支持选项“-g”与“-O”一起使用,以调试优化后的代码,但优化后的代码在执行时其路径可能与源文件不完全相同。
.2  启动被调试程序
    run
    r    在GDB下使用run命令来启动程序。首先必须用GDB参数指定程序名,或者用命令file或exec-file来指定程序名。
    如果程序运行的环境支持多进程,run创建一个内部进程并由该进程运行程序。如果环境不支持多进程,run就跳到程序的开头。
    程序的执行受以下四种信息影响,GDB可以指定它们,但必须在程序运行前进行:
    arguments
    指定作为run命令参数传递给程序的参数。参见“程序参数”一节。
    environment
    程序一般从GDB继承环境,但可以用GDB命令set environment和unset environment来改变部分环境。 参见“程序环境”一节。 
    working directory
    程序从GDB继承工作目录。可以用GDB命令cd来改变它。 参见“程序工作目录”一节。
    standard input and output
    程序一般使用GDB用的标准输入输出。可以在run命令行重定向输入输出,或者使用tty命令为程序设置一个不同的命令。参见“程序输入输出”一节。
.3  程序参数
    set args
    指定程序下次运行时使用的参数。如果set args无参数,run就不带参数执行程序。一旦带参数运行了程序,只有在下次运行前使用set args才能使程序不带参数运行。
    show args
    显示给程序的参数。
.4  程序环境
    environment由一组环境变量及其值组成。环境变量可以用shell进行设置,并被运行的所有其它程序继承。在调试时,无需重启GDB就可以修改环境。以下为相应的命令:
    path directory
    show paths
    show environment [varname]
    set environment varname [=] value
    unset environment varname
.5  程序工作目录
    每次用run启动程序时,它都从GDB的当前工作目录继承自己的工作目录。而GDB的当前工作目录可以用GDB的cd命令进行修改。
    cd directory
    把GDB的工作目录改为directory。
    pwd      打印GDB的工作目录。
.6  程序输入输出
    缺省情况下,GDB下运行的程序使用GDB的终端进行输入输出。GDB切换到自己的终端模式进行人机交互,但会记录程序使用的终端模式,并在程序继续运行时切换过去。
    info terminal
    显示GDB记录的程序所用终端模式信息。
    可以在run命令中使用shell重定向来改变程序的输入输出。如
    run > outfile
    就启动程序并把输出转向到文件“outfile”。
    另一种方法就是使用tty命令进行重定向。如
    tty /dev/ttyb
    就把后续的run命令启动的进程的输入输出定向到终端“/dev/ttyb”并把它作为那些进程的控制终端。
    run命令中的重定向可以覆盖tty命令对输入输出设备的影响,但对控制终端不起作用。
    GDB的输入不受这些命令的影响,还是从原来的终端获取。
.7  调试一个正在运行的进程
    只有在支持多进程的环境下才可以进行这样的操作;比如在一个缺乏操作系统的裸板上就无法对程序进行attach操作。
    attach process-id
    进程ID可以用ps命令或“jobs -l”shell命令得到。在使用attach前,需要先用file命令来指定运行在进程中的程序名和载入符号表。GDB在调试该进程前,先得停止该进程的运行,然后才能检查并修改进程,设置断点等。要使其继续运行,可以在把GDB与该进程联接上之后使用continue命令。
    detach   在调试之后,可以用该命令解除GDB的控制。
    如果在有一个联接进程时退出GDB或使用run命令,该联接进程就被杀死了。在缺省情况下,GDB会要求确认是否执行该操作;用set confirm命令可以改变此缺省设置。
.8  杀死子进程
    kill命令可以杀死在GDB下用来运行程序的子进程。
.9  附加进程信息
    某些操作系统提供“/proc”机制来检查使用文件系统子例程的运行进程的映像。
    info proc
    info proc mappings
    info proc times
    info proc id
    info proc status
    info proc all
.10 调试多线程程序
    GDB提供以下方法来调试多线程程序:
        自动通告新线程
        “thread threadno”,在线程间切换的命令
        “info threads”,查询现有线程的命令
        “thread apply [threadno] [all] args”,对一串线程使用某个命令的命令
        线程特有的断点
.11 调试多进程程序
    GDB对此没有特别的支持。在一个程序创建进程时,GDB继续调试父进程,子进程的运行不受影响。
.4  停止与继续
    在GDB里,程序可能因多种原因停止执行,如信号、断点、或在单步执行命令后达到了下一行。可以用info命令查看程序当前状态。
    info program
    显示程序状态信息:是否正在运行,是哪个进程,以及停止的原因。
.1  断点、检查点和异常
    断点是在程序达到时停止程序的一个特定位置。对每个断点可以设置条件,来更好地控制是否停止程序运行。
    检查点是一种特殊的断点,在表达式的值改变时停止程序的运行。必须使用与断点不同的命令来进行设置,其它操作与断点相同:启用、禁用和删除断点和检查点使用相同的命令。
.2  设置断点
    断点用break命令进行设置。调试器通常用变量“$bpnum”来记录最近设置的断点数。
    break function
    在函数function入口处设置一个断点。
    break +offset
    break -offset
    break linenum
    break filename:linenum
    break filename:function
    break *address
    break
    在选定的堆栈帧要执行的下一条指令设置一个断点。
    break ... if cond
    设置一个有条件的断点,只有满足条件才停止。“...”代表上面描述的参数。
    tbreak args
    设置一个只启用一次的断点,随后就自动删除它。
    hbreak args
    设置一个硬件辅助支持的断点。
    thbreak args
    是“tbreak”与“hbreak”的结合。
    rbreak regex
    对所有与规则表达式regex匹配的函数设置断点。
    info breakpoints [n]
    info break [n]
    info watchpoints [n]
    GDB本身有时会设置一些特殊目的的断点,如longjmp的特殊处理。这些内部断点无法用命令“info breakpoints”显示,但可以用GDB的“maint info breakpoints”命令来查看,所显示的断点类型如下:
    breakpoint
    一般明确设置的断点。
    watchpoint
    一般明确设置的检查点。
    longjmp
    内部断点,用来正确处理单步执行的longjmp调用。
    longjmp resume
    在longjmp目的地的内部断点。
    untill
    GDB的untill命令使用的临时内部断点。
    finish
    GDB的finish命令使用的临时内部断点。
.3  设置检查点
    watch expr
    为一个表达式设置检查点,GDB在expr被程序写及其值改变时停止。
    rwatch expr
    设置一个检查点,GDB在expr被程序读时停止。
    awatch expr
    设置一个检查点,GDB在expr被程序读和写时停止。
    info watchpoints
.4  断点与异常
    某些语言,如GNU C++,实现异常处理。可以用GDB来检查导致程序异常的原因,并列出程序准备处理的异常。
    catch exceptions
    使用catch命令可以在激活的异常处理程序处设置断点。exceptions是要捕获的异常名列表。
.5  删除断点
    clear
    删除选定的堆栈帧要执行的下一条指令处设置的断点。
    clear function
    clear filename:function
    删除函数入口处的断点。
    clear linenum
    clear filename:linenum
    删除指定代码行的断点。
    delete [breakpoints] [bnums...]
    删除参数指定数目的断点或检查点。如果无参数,则删除所有断点。
.6  禁用断点
    一个断点或检查点可以有以下四种启用状态:启用、禁用、启用一次(断点停止程序,随后被禁用)和启用并删除(断点停止程序,随后被删除)。以下为相应的命令:
    disable [breakpoints] [bnums...]
    enable [breakpoints] [bnums...]
    enable [breakpoints] once bnums...
    disable [breakpoints] delete bnums...
.7  中断条件
    condition bnum expression
    指定expression作为第bnum个断点或检查点的中断条件。
    condition bnum
    移去第bnum个断点或检查点的中断条件,使其变成无条件断点。
    ignore bnum count
    忽略count次第bnum个断点。
.8  断点命令列表
    可以为断点设置一系列命令,在程序遇到断点停止时执行它们。
    commands [bnum] 
    ... command-list ... 
    end     为第bnum个断点指定一串命令。用不带命令的commands可以移去为断点设置的命令。如果没有bnum参数,则命令被设置为上一个断点或检查点的。
    如下例就是在x的值大于零时打印foo入口处的x的值:
    break foo if x>0
    commands
    silent
    printf "x is %d\n",x
    cont
    end
.9  断点菜单
    有些语言(如C++)允许函数名重载,这样当某个函数名重载时,“break function”就不足以让GDB了解希望在哪里设置个断点。此时使用“break function(types)”就可以指定希望的那个特殊函数版本。否则,GDB会提供一个菜单,要求进行选择。下例就是对重载的符号String::after设置断点:
    (gdb) b String::after
    [0] cancel
    [1] all
    [2] file:String.cc; line number:867
    [3] file:String.cc; line number:860
    [4] file:String.cc; line number:875
    [5] file:String.cc; line number:853
    [6] file:String.cc; line number:846
    [7] file:String.cc; line number:735
    > 2 4 6
    Breakpoint 1 at 0xb26c: file String.cc, line 867.
    Breakpoint 2 at 0xb344: file String.cc, line 875.
    Breakpoint 3 at 0xafcc: file String.cc, line 846.
    Multiple breakpoints were set.
    Use the "delete" command to delete unwanted
     breakpoints.
    (gdb)
.10 继续与单步执行
    continue [ignore-count]
    c [ignore-count]
    fg [ignore-count]
    从当前位置恢复程序的运行。可选参数ignore-count允许对该位置断点的忽略次数,其效果等于ignore。参数ignore-count仅在程序由于断点停止时有效。
    从其它位置恢复运行,可以使用return返回调用函数,或jump跳转到程序的任意位置。
    step的典型用法是在函数的开始设置一个断点,或在怀疑有问题的程序段设置一个断点,然后使用step单步执行,以检查有关变量。
    step
    step count
    next [count]
    与step类似,但不进入函数的内部。
    finish
    继续运行到函数返回,并打印函数返回值。
    u
    untill
    可避免step在循环内的单步执行,一下就到达循环终点。
    untill location
    u location
    stepi
    si
    执行一条机器指令,然后停止并返回调试器。
    nexti
    ni
    执行一条机器指令,如果是函数调用,则处理到函数返回才停止。
.11 信号
    信号是程序里可能发生的异步事件。GDB可以检测程序里信号的发生,可以事先设置GDB对每类信号的操作。
    info signals
    打印信号种类表及GDB对它们相应的处理。
    handle signal keywords...
    改变GDB对signal信号的处理。keywords为处理方式,有以下几种:
    nostop
    信号发生时程序不停止,但可以打印通知信息。
    stop
    信号发生时程序停止,同时打印通知信息。
    print
    信号发生时打印通知信息。
    noprint
    GDB 不留意信号的发生。这同时隐含了nostop。
    pass
    GDB允许程序看到该信号;程序可以处理信号,若信号是致命的或没被处理,程序可能会终止。
    nopass
    GDB不允许程序看到该信号。
.12 停止与启动多线程程序
    break linespec thread threadno
    break linespec thread threadno if ...
    linespec指定源码行,“thread threadno”指定只有在线程threadno到达该行时才停止。如果不指定“thread threadno”,则对所有线程都起作用。
    一旦在GDB下程序停止,所有的执行线程都停止,而不仅仅是当前线程。同样,程序重启时所有的线程都开始执行。
.5  检查堆栈
    在程序停止时,首先要了解的是它停在哪里和它是怎么到达那里的。每次程序执行函数调用时,都生成相应的调用信息,包括调用在程序中的位置、调用参数以及被调用函数的局部变量。这些信息保存在一块叫堆栈帧的数据里,堆栈帧分配的内存区域叫调用堆栈。
.1  堆栈帧
    调用堆栈被分为一些被叫做堆栈帧的连续片断,每个堆栈帧都是某函数的某次调用有关的数据。每次函数被调用,就产生一个新的堆栈帧;每次函数返回时,相应的堆栈帧就消失了。
    在程序里,堆栈帧由其地址相区别。堆栈帧由很多字节组成,每个字节都有自己的地址;每种计算机都有自己的约定来选择一个字节的地址作为堆栈帧的地址。通常在运行到某帧时,该地址被保存在一个叫做帧指针寄存器的寄存器里。
    frame args
    命令frame用来从一个堆栈帧移动到另一个堆栈帧,并打印所选择的堆栈帧。args可以是堆栈帧的地址,也可以是堆栈帧号。无参数时打印当前的堆栈帧。
    select-frame
    与frame命令相同,不过不打印信息。
.2  回溯
    回溯是说明程序如何运行到该处的概要。对多帧情况,它一行显示一帧,从当前帧开始,然后是其调用者,一直到堆栈顶部。
    backtrace
    bt
    打印整个堆栈的回溯。
    backtrace n 
    bt n 
    只打印最内层的n帧。
    backtrace -n 
    bt -n
    只打印最外层的n帧。
.3  选择帧
    frame n
    f n
    选择第n帧。注意,帧0为最内层的(当前执行的)帧,帧1为其调用者,依次类推。
    frame addr
    f addr
    选择地址为addr的帧。
    up n
    down n
    向堆栈顶部(底部)移动n帧。
    up-silently n
    down-silently n
    在操作时不打印新帧的信息。适用于GDB命令脚本文件。
.4  有关帧的信息
    frame
    f
    不改变所选的帧,只打印当前选定堆栈帧的简要描述。
    info frame
    info f
    打印当前选定堆栈帧的详细描述。
    info frame addr
    info f addr
    打印地址为addr的堆栈帧的详细描述。
    info args
    打印选定堆栈帧的参数。
    info locals
    打印选定堆栈帧的局部变量。这些变量是所有在执行选定堆栈帧时可存取的变量。
    info catch
    打印当前堆栈帧在当前执行点激活的所有异常处理程序列表。
.5  MIPS机器和函数堆栈
    基于MIPS的计算机使用非通常的堆栈帧,有时需要GDB在目标代码中反向查找以发现函数的起始位置。为了改善响应时间,可以用以下命令限制查找的范围:
    set heuristic-fence-post limit
    限制GDB在查找函数的起始位置时最多检查limit个字节。缺省或零值意味着没有限制。
    show heuristic-fence-post
    显示当前的限制。
.6  检查源文件
.1  打印源码行
    list linenum
    打印当前源文件以第linenum行为中心的源码。
    list function
    打印以函数function开头为中心的源码。
    list linespec
    打印以linespec指定行为中心的源码。
    list first, last
    打印从first到last的源码。
    list , last
    list first,
    list
    打印更多的源码。
    list +
    list -
    打印上次打印行之前(后)的源码。
    缺省情况下,GDB打印上述list命令形式的10行源码。可以用以下命令改变此设置:
    set listsize count
    使list命令显示count 行源码。 
    show listsize
    显示list打印的行数。
    下面为指定源码行的可能的linespec种类:
    number 
    +offset 
    -offset 
    filename:number 
    function 
    filename:function 
    *address
.2  搜索源文件
    forward-search regexp
    search regexp
    reverse-search regexp
    在当前源文件里向前(后)查找与“regexp”匹配的规则表达式。
.3  指定源目录
    如果没有指定源目录,GDB在当前目录下查找源文件。在启动GDB时,源目录为空。
    directory dirname ...
    dir dirname ...
    把目录dirname加到源目录的开头,多个目录之间用“:”或空格分开。
    directory
    把源目录重置为空。
    show directories
    打印源目录。
.4  源码和机器代码
    info line linespec
    打印行linespec源码编译出的代码的起始和结束地址。
    disassemble
    把某范围内存内容反编译为机器指令。缺省情况下,内存范围是选定帧的程序计数器周围的函数。只有一个参数时,参数值为程序计数器的值;两个参数则是指定地址范围。
    set assembly-language instruction-set
    选择反编译所用的指令集。目前只定义了Intel x86系列,可以把instruction-set设置为i386或i8086,缺省为i386。
    下面为一个disassemble命令应用的例子:
    (gdb) disas 0x63e4 0x6404
    Dump of assembler code from 0x63e4 to 0x6404:
    0x63e4 <builtin_init+5340>:     ble 0x63f8 <builtin_init+5360>
    0x63e8 <builtin_init+5344>:     sethi %hi(0x4c00), %o0
    0x63ec <builtin_init+5348>:     ld [%i1+4], %o0
    0x63f0 <builtin_init+5352>:     b 0x63fc <builtin_init+5364>
    0x63f4 <builtin_init+5356>:     ld [%o0+4], %o0
    0x63f8 <builtin_init+5360>:     or %o0, 0x1a4, %o0
    0x63fc <builtin_init+5364>:     call 0x9288 <path_search>
    0x6400 <builtin_init+5368>:     nop
    End of assembler dump.
.7  检查数据
    通常检查程序的数据使用print命令,或其同义词inspect。
    print exp
    print /f exp
    exp是表达式,/f指定打印时的格式。
    print
    print /f
    打印格式可以为以下几种:
    x   用16进制形式打印整数。
    d   用带符号的十进制形式打印整数。
    u   用无符号的十进制形式打印整数。
    o   用八进制形式打印整数。
    t   用二进制形式打印整数。
    a   把值打印成地址,包括16进制绝对地址和与上一个符号的偏移量。
    c   用字符常量的形式打印整数。
    f   用标准的浮点句法打印浮点数。
 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值