用GDB调试程序(笔记)

来源:互联网 发布:vb如何连接access 编辑:程序博客网 时间:2024/05/16 01:11
本文转自 http://blog.csdn.net/lilingcx/archive/2007/07/26/1708680.aspx

GDB调试程序(笔记)

    本文是基于陈皓所写<GDB调试程序>一文的学习笔记,主要仅仅记录一些命令和格式,以供以后查找方便.碰到新的命令也可增加在其中.

    原文的链结是:

    http://blog.csdn.net/haoel/archive/2003/07/02/2879.aspx

    如果还有其他需要,就可以参考GDB的手册,英文手册可以直接去GUN网站上搜索.相关的有一个中文翻译版本(没有完全翻译好).

    中文版本链结是:

    http://wiki.chinaunix.net/index.php/%E4%BD%BF%E7%94%A8GDB%E8%B0%83%E8%AF%95

使用GDB

    要调试C/C++的程序,首先在编译时,我们必须要把调试信息加到可执行文件中。使用编译器(cc/gcc/g++)的 -g 参数可以做到这一点。

    1gdb <program>
       program
也就是你的执行文件,一般在当然目录下。

    2gdb <program> core
      
gdb同时调试一个运行程序和core文件,core是程序非法执行后core dump 后产生的文件。

    3gdb <program> <PID>
      
如果你的程序是一个服务程序,那么你可以指定这个服务程序运行时的进程ID gdb会自动attach上去,并调试他。program应该在PATH环境变量中搜索得到。

GDB的命令概貌

    可以通过help查询命令的帮助,通常命令是以类显示的.

    可以使用命令的简写,比如break==b

    Tab可以补全命令,补全函数名,补全函数的参数.

GDB中运行UNIXshell程序

    shell <command string>

    调用UNIXshell来执行<command string>


       make  <make-args>

       可以在gdb中执行make命令来重新build自己的程序。这个命令等价于“shell make <make-args>”

 

GDB中运行程序

    llist,看看gdb是否能列出源代码。

    r或是run, 程序的运行.

    set args 可指定运行时参数。(如:set args 10 20 30 40 50
    show args
命令可以查运行参数。

    path <dir> 可设定程序的运行路径。
    show paths
查看程序的运行路径。


    set environment varname [=value]
设置环境变量。如:set env USER=hchen
    show environment [varname]
查看环境变量。


    cd <dir>
相当于shellcd命令。
    pwd
显示当前的所在目录。


    info terminal
显示你程序用到的终端的模式。
   
使用重定向控制程序输出。如:run > outfile
    tty
命令可以指写输入输出的终端设备。如:tty /dev/ttyb

 

调试已运行的程序

    两种方法:
    1
、在UNIX下用ps查看正在运行的程序的PID(进程ID),然后用gdb <program> PID格式挂接正在运行的程序。
    2
、先用gdb <program>关联上源代码,并进行gdb,在gdb中用attach命令来挂接进程的PID。并用detach来取消挂接的进程。

暂停 / 恢复程序运行

    gdb中,我们可以有以下几种暂停方式:断点(BreakPoint)、观察点(WatchPoint)、捕捉点(CatchPoint)、信号(Signals)、线程停止(Thread Stops)。如果要恢复程序运行,可以使用c或是continue命令。

一、设置断点(BreakPoint
    
我们用break命令来设置断点。正面有几点设置断点的方法:
        break <function>     //
指定函数

       break <linenum>      //在指定行号停住。

       break +offset
       break -offset
           //
在当前行号的前面或后面的offset行停住。offiset为自然数。

       break filename:linenum
           //
在源文件filenamelinenum行处停住。

       break filename:function
           //
在源文件filenamefunction函数的入口处停住。

       break *address
           //
在程序运行的内存地址处停住。

       break
           //break
命令没有参数时,表示在下一条指令处停住。

       break ... if <condition>
           //condition
表示条件,在条件成立时停住。比如在循环境体中,可以设置        //break if i=100,表示当i100时停住程序。

    查看断点时,可使用info命令,如下所示:(注:n表示断点号)
       info breakpoints [n]
       info break [n]

二、设置观察点(WatchPoint
   
   
观察点一般来观察某个表达式(变量也是一种表达式)的值是否有变化了,如果有变化,马上停住程序。我们有下面的几种方法来设置观察点:
   
    watch <expr>
        //
为表达式(变量)expr设置一个观察点。       
    rwatch <expr>
        //
当表达式(变量)expr被读时,停住程序。
    awatch <expr>
       //
当表达式(变量)的值被读或被写时,停住程序。
    info watchpoints
        //
列出当前所设置了的所有观察点。

 

三、设置捕捉点(CatchPoint

    你可设置捕捉点来补捉程序运行时的一些事件。如:载入共享库(动态链接库)或是C++的异常。设置捕捉点的格式为:
   
    catch <event>
event发生时,停住程序。event可以是下面的内容:
        1
throw 一个C++抛出的异常。
        2
catch 一个C++捕捉到的异常。

        以下5个只有在HP-UX上有用.
        3
exec 调用系统调用exec时。
        4
fork 调用系统调用fork时。
        5
vfork 调用系统调用vfork时。
        6
load load <libname> 载入共享库(动态链接库)时。
        7
unload unload <libname> 卸载共享库(动态链接库)时。

    tcatch <event>
       
只设置一次捕捉点,当程序停住以后,应点被自动删除。

四、维护停止点

    GDB中,如果你觉得已定义好的停止点没有用了,你可以使用deletecleardisableenable这几个命令来进行维护。

    Clear  //清除所有的已定义的停止点。

    clear <function>
    clear <filename:function>   //
清除所有设置在函数上的停止点。

    clear <linenum>
    clear <filename:linenum>    //
清除所有设置在指定行上的停止点。

    delete [breakpoints] [range...]
        //
删除指定的断点,breakpoints为断点号。如果不指定断点号,则表示删除      //所有的断点。range 表示断点号的范围(如:3-7)。其简写命令为d


   
比删除更好的一种方法是disable停止点,disable了的停止点,GDB不会删除,当你还需要时,enable即可,就好像回收站一样。

    disable [breakpoints] [range...]
        //disable
所指定的停止点,breakpoints为停止点号。如果什么都不指定,     //表示disable所有的停止点。简写命令是dis.

    enable [breakpoints] [range...]
        //enable
所指定的停止点,breakpoints为停止点号。

    enable [breakpoints] once range...
        //enable
所指定的停止点一次,当程序停止后,该停止点马上被GDB自动        //disable

    enable [breakpoints] delete range...
        //enable
所指定的停止点一次,当程序停止后,该停止点马上被GDB自动删除。

 

五、停止条件维护

    面在说到设置断点时,我们提到过可以设置一个条件,当条件成立时,程序自动停止。一 般来说,为断点设置一个条件,我们使用if关键词,后面跟其断点条件。并且,条件设置好后,我们可以用condition命令来修改断点的条件。(只有 breakwatch命令支持ifcatch目前暂不支持if

    condition <bnum> <expression>
        //
修改断点号为bnum的停止条件为expression

    condition <bnum>
        //
清除断点号为bnum的停止条件。


   
还有一个比较特殊的维护命令ignore,你可以指定程序运行时,忽略停止条件几次。

    ignore <bnum> <count>
       
表示忽略断点号为bnum的停止条件count次。

 

六、为停止点设定运行命令

    我们可以使用GDB提供的command命令来设置停止点的运行命令。也就是说,当运行的程序在被停止住时,我们可以让其自动运行一些别的命令,这很有利行自动化调试。对基于GDB的自动化调试是一个强大的支持。


    commands [bnum]
    ... command-list ...
    end

    为断点号bnum指写一个命令列表。当程序被该断点停住时,gdb会依次运行命令列表中的命令。

    例如:

        break foo if x>0
        commands
        printf "x is %d/n",x
        continue
        end
   
断点设置在函数foo中,断点条件是x>0,如果程序被断住后,也就是,一旦x的值在foo函数中大于0GDB会自动打印出x的值,并继续运行程序。

    如果你要清除断点上的命令序列,那么只要简单的执行一下commands命令,并直接在打个end就行了。

七、断点菜单

    C ++中,可能会重复出现同一个名字的函数若干次(函数重载),在这种情况下,break <function>不能告诉GDB要停在哪个函数的入口。当然,你可以使用break <function(type)>也就是把函数的参数类型告诉GDB,以指定一个函数。否则的话,GDB会给你列出一个断点菜单供你选择你所 需要的断点。你只要输入你菜单列表中的编号就可以了。如:

    (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)

    可见,GDB列出了所有after的重载函数,你可以选一下列表编号就行了。0表示放弃设置断点,1表示所有函数都设置断点。

八、恢复程序运行和单步调试

    当程序被停住了,你可以用continue命令恢复程序的运行直到程序结束,或下一个断点到来。也可以使用stepnext命令单步跟踪程序。

    continue [ignore-count]
    c [ignore-count]
    fg [ignore-count]
       
恢复程序运行,直到程序结束,或是下一个断点到来。ignore-count表示忽      略其后的断点次数。continuecfg三个命令都是一样的意思。


    step <count>
       
单步跟踪,如果有函数调用,他会进入该函数。进入函数的前提是,此函数被编 译有debug信息。后面可以加count也可以不加,不加表示一条条地执行,加表示执   行后面的count条指令.

    next <count>
       
同样单步跟踪,如果有函数调用,他不会进入该函数。后面可以加count也可      以不加,不加表示一条条地执行,加表示执行后面的count条指令,然后再停住。

    set step-mode
    set step-mode on
       
打开step-mode模式,于是,在进行单步跟踪时,程序不会因为没有debug       信息而不停住。这个参数有很利于查看机器码。

    set step-mod off
       
关闭step-mode模式。

    finish
       
运行程序,直到当前函数完成返回。并打印函数返回时的堆栈地址和返回值及参 数值等信息。

    until u
       
当你厌倦了在一个循环体内单步跟踪时,这个命令可以运行程序直到退出循环      体。

    stepi si
    nexti
ni
       
单步跟踪一条机器指令!一条程序代码有可能由数条机器指令完成,stepi   nexti可以单步执行机器指令。与之一样有相同功能的命令是 “display/i $pc” 当运行完这个命令后,单步跟踪会在打出程序代码的同时打出机器指令(也就是汇编代  码)

九、信号(Signals

    GDB有能力在你调试程序的时候处理任何一种信号,你可以告诉GDB需要处理哪一种信号。你可以要求GDB收到你所指定的信号时,马上停住正在运行的程序,以供你进行调试。你可以用GDBhandle命令来完成这一功能。

    handle <signal> <keywords...>
       
GDB中定义一个信号处理。信号<signal>可以以SIG开头或不以SIG开头, 可以用定义一个要处理信号的范围,也可以使用关键字 all来标明要处理所有的信号。  一旦被调试的程序接收到信号,运行程序马上会被GDB停住,以供调试。其<keywords> 可以是以下几种 关键字的一个或多个。

        nostop
           
当被调试的程序收到信号时,GDB不会停住程序的运行,但会打出消息告         诉你收到这种信号。
        stop
           
当被调试的程序收到信号时,GDB会停住你的程序。
        print
           
当被调试的程序收到信号时,GDB会显示出一条信息。
        noprint
           
当被调试的程序收到信号时,GDB不会告诉你收到信号的信息。
        pass
        noignore
           
当被调试的程序收到信号时,GDB不处理信号。这表示,GDB会把这个信         号交给被调试程序会处理。
        nopass
        ignore
           
当被调试的程序收到信号时,GDB不会让被调试程序来处理这个信号。

        info signals
        info handle
          
查看有哪些信号在被GDB检测中。

十、线程(Thread Stops

    break <linespec> thread <threadno>
    break <linespec> thread <threadno> if ...
        linespec
指定了断点设置在的源程序的行号。threadno指定了线程的ID,注意,这个IDGDB分配的,你可以通过“info threads”命令来查看正在运行程序中的线程信息。如果你不指定thread <threadno>则表示你的断点设在所有线程上面。你还可以为某线程指定断点条件。如:
   
        (gdb) break frik.c:13 thread 28 if bartab > lim

    当你的程序被GDB停住时,所有的运行线程都会被停住。这方便你你查看运行程序的总体情况。而在你恢复程序运行时,所有的线程也会被恢复运行。那怕是主进程在被单步调试时。

 

查看栈信息

    当你的程序调用了一个函数,函数的地址,函数参数,函数内的局部变量都会被压入Stack)中。你可以用GDB命令来查看当前的栈中的信息。

下面是一些查看函数调用栈信息的GDB命令:

    backtrace
    bt
       
打印当前的函数调用栈的所有信息。如:
       
        (gdb) bt
        #0  func (n=250) at tst.c:6
        #1  0x08048524 in main (argc=1, argv=0xbffff674) at tst.c:30
        #2  0x400409ed in __libc_start_main () from /lib/libc.so.6
       
       
从上可以看出函数的调用栈信息:__libc_start_main --> main() -->    func()
       
   
    backtrace <n>
    bt <n>
        n
是一个正整数,表示只打印栈顶上n层的栈信息。

    backtrace <-n>
    bt <-n>
        -n
表一个负整数,表示只打印栈底下n层的栈信息。
       
如果你要查看某一层的信息,你需要在切换当前的栈,一般来说,程序停止时,最顶层的栈就是当前栈,如果你要查看栈下面层的详细信息,首先要做的是切换当前栈。

    frame <n>
    f <n>
        n
是一个从0开始的整数,是栈中的层编号。比如:frame 0,表示栈顶,frame   1,表示栈的第二层。
   
    up <n>
       
表示向栈的上面移动n层,可以不打n,表示向上移动一层。
       
    down <n>
       
表示向栈的下面移动n层,可以不打n,表示向下移动一层。
       

    上面的命令,都会打印出移动到的栈层的信息。如果你不想让其打出信息。你可以使用这三个命令:
   
    select-frame <n>
对应于 frame 命令。
    up-silently <n>
对应于 up 命令。
    down-silently <n>
对应于 down 命令。

   
查看当前栈层的信息,你可以用以下GDB命令:

    frame f
       
会打印出这些信息:栈的层编号,当前的函数名,函数参数值,函数所在文件及行号,函数执行到的语句。
   
    info frame
    info f
       
这个命令会打印出更为详细的当前栈层的信息,只不过,大多数都是运行时的内内地址。比如:函数地址,调用函数的地址,被调用函数的地址,目前的函数是由什么样的程序语言写成的、函数参数地址及值、局部变量的地址等等。如:
            (gdb) info f
            Stack level 0, frame at 0xbffff5d4:
             eip = 0x804845d in func (tst.c:6); saved eip 0x8048524
             called by frame at 0xbffff60c
             source language c.
             Arglist at 0xbffff5d4, args: n=250
             Locals at 0xbffff5d4, Previous frame's sp is 0x0
             Saved registers:
              ebp at 0xbffff5d4, eip at 0xbffff5d8
             
     info args
       
打印出当前函数的参数名及其值。
    
     info locals
       
打印出当前函数中所有局部变量及其值。
       
     info catch
       
打印出当前的函数中的异常处理信息。

查看源程序

一、显示源代码

      
    list <linenum>
       
显示程序第linenum行的周围的源程序。
    list <function>
       
显示函数名为function的函数的源程序。  
    list
       
显示当前行后面的源程序。 
    list -
       
显示当前行前面的源程序。

 

    使用下面命令可以设置一次显示源程序的行数。

    set listsize <count>
       
设置一次显示源代码的行数。    
    show listsize
       
查看当前listsize的设置。
       

list命令还有下面的用法:

    list <first>, <last>
       
显示从first行到last行之间的源代码。
    list , <last>
       
显示从当前行到last行之间的源代码。
    list +
       
往后显示源代码。
       

一般来说在list后面可以跟以下这们的参数:

    <linenum>   行号。
    <+offset>  
当前行号的正偏移量。
    <-offset>  
当前行号的负偏移量。
    <filename:linenum> 
哪个文件的哪一行。
    <function> 
函数名。
    <filename:function>
哪个文件中的哪个函数。
    <*address> 
程序运行时的语句在内存中的地址。
   

二、搜索源代码

不仅如此,GDB还提供了源代码搜索的命令:

    forward-search <regexp>
    search <regexp>
       
向前面搜索。

    reverse-search <regexp>
       
全部搜索。
       
其中,<regexp>就是正则表达式.

三、指定源文件的路径

某些时候,用-g编译过后的执行程序中只是包括了源文件的名字,没有路径名。GDB提供了可以让你指定源文件的路径的命令,以便GDB进行搜索。

    directory <dirname ... >
    dir <dirname ... >
       
加一个源文件路径到当前路径的前面。如果你要指定多个路径,UNIX下你可以使用“:”Windows下你可以使用“;”
    directory
       
清除所有的自定义的源文件搜索路径信息。
   
    show directories
       
显示定义了的源文件搜索路径。
       

四、源代码的内存

你可以使用info line命令来查看源代码在内存中的地址。info line后面可以跟行号函数名文件名:行号文件名:函数名,这个命令会打印出所指定的源码在运行时的内存地址,如:

        (gdb) info line tst.c:func
        Line 5 of "tst.c" starts at address 0x8048456 <func+6> and ends at 0x804845d <func+13>.

还有一个命令(disassemble)你可以查看源程序的当前执行时的机器码,这个命令会把目前内存中的指令dump出来。

 

查看运行时数据


   
在你调试程序时,当程序被停住时,你可以使用print命令(简写命令为p),或是同义命令inspect来查看当前程序的运行数据。print命令的格式是:
   
    print <expr>
    print /<f> <expr>
        <expr>
是表达式,是你所调试的程序的语言的表达式(GDB可以调试多种编程语言),<f>是输出的格式,比如,如果要把表达式按16进制的格式输出,那么就是/x
       
   

一、表达式

    print和许多GDB的命令一样,可以接受一个表达式,GDB会根据当前的程序运行的数据来计算这个表达式,既然是表达式,那么就可以是当前程序运行中的const常量、变量、函数等内容。可惜的是GDB不能使用你在程序中所定义的宏。
   
   
表达式的语法应该是当前所调试的语言的语法.在表达式中,有几种GDB所支持的操作符,它们可以用在任何一种语言中。
    @
       
是一个和数组有关的操作符,在后面会有更详细的说明.    
    ::
       
指定一个在文件或是一个函数中的变量。    
    {<type>} <addr>
       
表示一个指向内存地址<addr>的类型为type的一个对象。
  

二、程序变量

    GDB中,你可以随时查看以下三种变量的值:
        1
、全局变量(所有文件可见的)
        2
、静态全局变量(当前文件可见的)
        3
、局部变量(当前Scope可见的)
       
   
如果你的局部变量和全局变量发生冲突(也就是重名),一般情况下是局部变量会隐藏全局变量,也就是说,如果一个全局变量和一个函数中的局部变量同名时,如 果当前停止点在函数中,用print显示出的变量的值会是函数中的局部变量的值。如果此时你想查看全局变量的值时,你可以使用“::”操作符:
   
       file::variable
       function::variable
              
   
另外,需要注意的是,如果你的程序编译时开启了优化选项,那么在用GDB调试被优化过的程序时,可能会发生某些变量不能访问,或是取值错误码的情况。   

三、数组

    有时候,你需要查看一段连续的内存空间的值。比如数组的一段,或是动态分配的数据的大小。你可以使用GDB“@”操作符,“@”的左边是第一个内存的地址的值,“@”的右边则你你想查看内存的长度。例如,你的程序中有这样的语句:
    
        int *array = (int *) malloc (len * sizeof (int));
       
   
于是,在GDB调试过程中,你可以以如下命令显示出这个动态数组的取值:

        p *array@len

    @的左边是数组的首地址的值,也就是变量array所指向的内容,右边则是数据的长度,其保存在变量len.       

    如果是静态数组的话,可以直接用print数组名,就可以显示数组中所有数据的内容了。

四、输出格式

    一般来说,GDB会根据变量的类型输出变量的值。但你也可以自定义GDB的输出的格式。  
    x 
十六进制格式显示变量。
    d 
按十进制格式显示变量。
    u 
按十六进制格式显示无符号整型。
    o 
按八进制格式显示变量。
    t 
按二进制格式显示变量。
    a 
按十六进制格式显示变量。
    c 
按字符格式显示变量。
    f 
按浮点数格式显示变量。

     

五、查看内存

    你可以使用examine命令(简写是x)来查看内存地址中的值。x命令的语法如下所示:
   
    x/<n/f/u> <addr>
   
    n
fu是可选的参数。
   
    n
是一个正整数,表示显示内存的长度。长度的单位是由u决定的.
    f
表示显示的格式.
      
如果地址所指的是字符串,那么格式可以是s
      
如果地十是指令地址,那么格式可以是i
    u
表示从当前地址往后请求的字节数,如果不指定的话,GDB默认是4bytesu参数可以用下面的字符来代替,b表示单字节,h表示双字节,w表示四字 节,g表示八字节。   
    n/f/u
三个参数可以一起使用。例如:
   
   

六、自动显示

    你可以设置一些自动显示的变量,当程序停住时,或是在你单步跟踪时,这些变量会自动显示。相关的GDB命令是display
   
    display <expr>
    display/<fmt> <expr>
    display/<fmt> <addr>
   
    expr
是一个表达式,fmt表示显示的格式,addr表示内存地址,当你用display设定好了一个或多个表达式后,只要你的程序被停下来,GDB会自动显示你所设置的这些表达式的值。
   
   
格式is同样被display支持,一个非常有用的命令是:
   
        display/i $pc
   
    $pc
GDB的环境变量,表示着指令的地址,/i则表示输出格式为机器指令码,也就是汇编。于是当程序停下后,就会出现源代码和机器指令码相对应的情形,这是一个很有意思的功能。
   
   
下面是一些和display相关的GDB命令:
   
    undisplay <dnums...>
    delete display <dnums...>
   
删除自动显示,dnums意为所设置好了的自动显式的编号。如果要同时删除几个,编号可以用空格分隔,如果要删除一个范围内的编号,可以用减号表示(如:2-5
   
    disable display <dnums...>
    enable display <dnums...>
    disable
enalbe不删除自动显示的设置,而只是让其失效和恢复。
   
    info display
   
查看display设置的自动显示的信息。GDB会打出一张表格,向你报告当然调试中设置了多少个自动显示设置,其中包括,设置的编号,表达式,是否enable

七、设置显示选项

    GDB中关于显示的选项比较多,这里我只例举大多数常用的选项。

    set print address
    set print address on
       
打开地址输出,当程序显示函数信息时,GDB会显出函数的参数地址。系统默认为打开的.
    set print address off
       
关闭函数的参数地址显示,如:
    show print address
       
查看当前地址显示选项是否打开。
       
    set print array
    set print array on
       
打开数组显示,打开后当数组显示时,每个元素占一行,如果不打开的话,每个元素则以逗号分隔。这个选项默认是关闭的。与之相关的两个命令如下,我就不再多说了。
    set print array off
    show print array

    set print elements <number-of-elements>
       
这个选项主要是设置数组的,如果你的数组太大了,那么就可以指定一个      <number-of-elements>来指定数据显示的最大长度,当到达这个长度时,GDB就不    再往下显示了。如果设置为0,则表示不限制。
    show print elements
       
查看print elements的选项信息。
       
    set print null-stop <on/off>
       
如果打开了这个选项,那么当显示字符串时,遇到结束符则停止显示。这个选项 默认为off
   
    set print pretty on
       
如果打开printf pretty这个选项,那么当GDB显示结构体时会比较漂亮。           set print pretty off
       
关闭printf pretty这个选项,GDB显示结构体时会如下显示:
    show print pretty
       
查看GDB是如何显示结构体的。
       
   
    set print sevenbit-strings <on/off>
       
设置字符显示,是否按“/nnn”的格式显示,如果打开,则字符串或字符数据按  /nnn显示,如“/065”
    show print sevenbit-strings
       
查看字符显示开关是否打开。
       
    set print union <on/off>
       
设置显示结构体时,是否显式其内的联合体数据。
    show print union
       
查看联合体数据的显示方式
       
    set print object <on/off>
       
C++中,如果一个对象指针指向其派生类,如果打开这个选项,GDB会自动按 照虚方法调用的规则显示输出,如果关闭这个选项的话,GDB就不管虚函数表了。这个    选项默认是off
    show print object
       
查看对象选项的设置。
       
    set print static-members <on/off>
       
这个选项表示,当显示一个C++对象中的内容是,是否显示其中的静态数据成员。   默认是on
    show print static-members
       
查看静态数据成员选项设置。
       
    set print vtbl <on/off>
       
当此选项打开时,GDB将用比较规整的格式来显示虚函数表时。其默认是关闭的。
    show print vtbl
       
查看虚函数显示格式的选项。
       
       

八、历史记录

    当你用GDBprint查看程序运行时的数据时,你每一个print都会被GDB记录下来。GDB会以$1, $2, $3 .....这样的方式为你每一个print命令编上号。于是,你可以使用这个编号访问以前的表达式,如$1。这个功能所带来的好处是,如果你先前输入了一 个比较长的表达式,如果你还想查看这个表达式的值,你可以使用历史记录来访问,省去了重复输入。
   
   

九、GDB环境变量

    你可以在GDB的调试环境中定义自己的变量,用来保存一些调试程序中的运行数据。要定义一个GDB的变量很简单只需。使用GDBset命令。GDB的环境变量和UNIX一样,也是以$起头。如:
   
    set $foo = *object_ptr
   
   
使用环境变量时,GDB会在你第一次使用时创建这个变量,而在以后的使用中,则直接对其賦值。环境变量没有类型,你可以给环境变量定义任一的类型。包括结构体和数组。
   
    show convenience
       
该命令查看当前所设置的所有的环境变量。
       
   
这是一个比较强大的功能,环境变量和程序变量的交互使用,将使得程序调试更为灵活便捷。例如:
        set $i = 0
        print bar[$i++]->contents
   
   
于是,当你就不必,print bar[0]->contents, print bar[1]->contents地输入命令了。输入这样的命令后,只用敲回车,重复执行上一条语句,环境变量会自动累加,从而完成逐个输出的功能。
   

十、查看寄存器

    要查看寄存器的值,很简单,可以使用如下命令:
    info registers
       
查看寄存器的情况。(除了浮点寄存器)
    info all-registers
       
查看所有寄存器的情况。(包括浮点寄存器)
    info registers <regname ...>
       
查看所指定的寄存器的情况。
       
   
你同样可以使用print命令来访问寄存器的情况,只需要在寄存器名字前加一个$符号就可以了。如:p $eip