gdb调节和测试命令,GDB单步调节和测试程序

# 首要表明

gdb

linux下gdb单步调节和测试

用 GDB 调节和测试程序

GDB 概述 ————**

GDB 是 GNU开源公司宣布的二个有力的 UNIX下的程序调节和测试工具。只怕,各位比较喜欢那种图形界面形式的,像 VC、 BCB等 IDE的调剂,但假诺你是在 UNIX平台下做软件,你会发现 GDB这一个调节和测试工具有比 VC、 BCB的图形化调节和测试器更有力的职能。所谓 “寸有所长,尺有所短 ”就是那么些道理。

貌似的话, GDB首要扶助你成功上面三个方面包车型客车成效:

    一 、运营你的主次,能够依据你的自定义的须要自由的周转程序。
   
2 、可让被调剂的先后在你所内定的调置的断点处停住。(断点能够是原则表达式)
    3 、当程序被停住时,能够检查此时您的先后中所产生的事。
    4 、动态的变动您程序的实施环境。

从下面看来, GDB和一般的调剂工具未有啥两样,基本上也是瓜熟蒂落这一个职能,可是在细节上,你会意识 GDB那些调节和测试工具的强有力,我们莫不及较习惯了图形化的调节工具,但偶尔,命令行的调节和测试工具却具有图形化学工业具所不能完毕的功用。让大家逐1看来。

五个调剂示例 ——————**

源程序: tst.c

     1 #include <stdio.h>
     2
     3 int func(int n)
     4 {
     5         int sum=0,i;
     6         for(i=0; i<n; i++)
     7         {
     8                 sum+=i;
     9         }
    10         return sum;
    11 }
    12
    13
    14 main()
    15 {
    16         int i;
    17         long result = 0;
    18         for(i=1; i<=100; i++)
    19         {
    20                 result += i;
    21         }
    22
    23        printf(“result[1-100] = %d \n”, result );
    24        printf(“result[1-250] = %d \n”, func(250) );
    25 }

编写翻译生成执行文书:( Linux下)
    hchen/test> cc -g tst.c -o tst

使用 GDB调试:

hchen/test> gdb tst  <———- 启动 GDB
GNU gdb 5.1.1
Copyright 2002 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you
are
welcome to change it and/or 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.
This GDB was configured as “i386-suse-linux”…
(gdb) l     <——————–
l 命令约等于 list,从第壹行起先例出原码。
1        #include <stdio.h>
2
3        int func(int n)
4        {
5                int sum=0,i;
6                for(i=0; i<n; i++)
7                {
8                        sum+=i;
9                }
10               return sum;
(gdb)       <——————– 直接回车表示,重复上一次命令
11       }
12
13
14       main()
15       {
16               int i;
17               long result = 0;
18               for(i=1; i<=100; i++)
19               {
20                       result += i;   
(gdb) break 1陆   
<——————– 设置断点,在源程序第 1陆行处。
Breakpoint 1 at 0x8048496: file tst.c, line 16.
(gdb) break func 
<——————– 设置断点,在函数 func()入口处。
Breakpoint 2 at 0x8048456: file tst.c, line 5.
(gdb) info break  <——————– 查看断点新闻。
Num Type           Disp Enb Address    What
1   breakpoint     keep y   0x08048496 in main at tst.c:16
2   breakpoint     keep y   0x08048456 in func at tst.c:5
(gdb) r           <——————— 运营程序, run命令简写
Starting program: /home/hchen/test/tst

Breakpoint 1, main () at tst.c:1七    <———- 在断点处停住。
17               long result = 0;
(gdb) n         
<——————— 单条语句执行, next命令简写。
18               for(i=1; i<=100; i++)
(gdb) n
20                       result += i;
(gdb) n
18               for(i=1; i<=100; i++)
(gdb) n
20                       result += i;
(gdb) c         
<——————— 继续运维程序, continue命令简写。
Continuing.
result[1-100] = 5050       <———- 程序输出。

Breakpoint 2, func (n=250) at tst.c:5
5                int sum=0,i;
(gdb) n
6                for(i=1; i<=n; i++)
(gdb) p i       
<——————— 打印变量 i的值, print命令简写。
$1 = 134513808
(gdb) n
8                        sum+=i;
(gdb) n
6                for(i=1; i<=n; i++)
(gdb) p sum
$2 = 1
(gdb) n
8                        sum+=i;
(gdb) p i
$3 = 2
(gdb) n
6                for(i=1; i<=n; i++)
(gdb) p sum
$4 = 3
(gdb) bt        <——————— 查看函数堆栈。
#0  func (n=250) at tst.c:5
#1  0x080484e4 in main () at tst.c:24
#2  0x400409ed in __libc_start_main () from /lib/libc.so.6
(gdb) finish    <——————— 退出函数。
Run till exit from #0  func (n=250) at tst.c:5
0x080484e4 in main () at tst.c:24
24              printf(“result[1-250] = %d \n”, func(250) );
Value returned is $6 = 31375
(gdb) c     <——————— 继续运行。
Continuing.
result[1-250] = 31375    <———- 程序输出。

Program exited with code 0二柒. <——– 程序退出,调节和测试完结。
(gdb) q     <——————— 退出 gdb。
hchen/test>

好了,有了上述的神志认识,依旧让我们来系统地认识一下 gdb吧。

 

使用 GDB ————**

壹般的话 GDB首要调试的是 C/C++的次第。要调节 C/C++的次第,首先在编写翻译时,我们必须要把调节和测试音信加到可执行文件中。使用编写翻译器( cc/gcc/g++)的 -g参数能够成功那一点。如:

    > cc -g hello.c -o hello
    > g++ -g hello.cpp -o hello

万1未有 -g,你将看不见程序的函数名、变量名,所取代的全是运行时的内部存款和储蓄器地址。当你用 -g把调节和测试新闻加入之后,并打响编写翻译目的代码未来,让大家来探视怎么样用 gdb来调节他。

开首 GDB的方式有以下三种:

    1 、 gdb <program>
       program 也便是你的执行文书,1般在自然目录下。

    2 、 gdb <program> core
       用 gdb同时调节和测试二个运营程序和 core文件, core是先后违规执行后 core
dump后发出的文本。

    3 、 gdb <program> <PID>
       即便您的顺序是1个服务程序,那么你能够钦定这些服务程序运维时的进程 ID。 gdb会自动 attach上去,并调节他。 program应该在 PATH环境变量中寻觅获得。

 

GDB 运营时,能够加上部分 GDB的开发银行开关,详细的开关可以用 gdb
-help查看。笔者在上面只例举一些比较常用的参数:

    -symbols <file>
    -s <file>
    从钦命文件中读取符号表。

    -se file
    从钦赐文件中读取符号表音讯,并把她用在可执行文件中。

    -core <file>
    -c <file>
    调试时 core dump的 core文件。

    -directory <directory>
    -d <directory>
    参与三个源文件的查找路径。暗许搜索路径是环境变量中 PATH所定义的路径。

GDB 的一声令下概貌 ———————**

启航 gdb后,就你被带走 gdb的调节环境中,就足以选取 gdb的通令初阶调节和测试程序了,gdb的授命能够使用 help命令来查看,如下所示:

    /home/hchen> gdb
    GNU gdb 5.1.1
    Copyright 2002 Free Software Foundation, Inc.
    GDB is free software, covered by the GNU General Public License, and
you are
    welcome to change it and/or 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.
    This GDB was configured as “i386-suse-linux”.
    (gdb) help
    List of classes of commands:

    aliases — Aliases of other commands
    breakpoints — Making program stop at certain points
    data — Examining data
    files — Specifying and examining files
    internals — Maintenance commands
    obscure — Obscure features
    running — Running the program
    stack — Examining the stack
    status — Status inquiries
    support — Support facilities
    tracepoints — Tracing of program execution without stopping the
program
    user-defined — User-defined commands

    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)

gdb 的指令很多, gdb把之分成很八个品种。 help命令只是例出 gdb的授命体系,假设要看档次中的命令,能够使用 help
<class>命令,如: help
breakpoints,查看设置断点的有着命令。也得以直接 help
<command>来查阅命令的支持。

gdb 中,输入指令时,能够毫无打全命令,只用打命令的前多少个字符就足以了,当然,命令的前多少个字符应该要申明着一个唯1的指令,在 Linux下,你能够打击三回 TAB键来补齐命令的全称,假如有再一次的,那么 gdb会把其例出来。
   
    示例1:在进入函数 func时,设置三个断点。能够敲入 break
func,或是直接正是 b func
    (gdb) b func
    Breakpoint 1 at 0x8048458: file hello.c, line 10.
 
    示例贰:敲入 b按五次 TAB键,你会面到全数 b打头的一声令下:
    (gdb) b
    backtrace  break      bt
    (gdb)

    示例3:只记得函数的前缀,能够那样:
    (gdb) b make_ < 按 TAB键 >
    (再按下一回 TAB键,你会晤到 :)
    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 把全体 make初阶的函数全部例出来给你查看。

    示例4:调节和测试 C++的次序时,有能够函数名相同。如:
    (gdb) b ‘bubble( M-?
    bubble(double,double)    bubble(int,int)
    (gdb) b ‘bubble(
    你能够查阅到 C++中的全部的重载函数及参数。(注: M-?和 “按四回 TAB键 ”是1个情趣)

要剥离 gdb时,只用发 quit或指令简称 q就行了。

 

GDB 中运行 UNIX 的 shell 程序 ————————————**

在 gdb环境中,你能够推行 UNIX的 shell的吩咐,使用 gdb的 shell命令来成功:

    shell <command string>
    调用 UNIX的 shell来施行 <command
string>,环境变量 SHELL中定义的 UNIX的 shell将会被用来实施 <command
string>,假若 SHELL没有定义,那就动用 UNIX的规范shell: /bin/sh。(在 Windows中应用 Command.com或 cmd.exe)

还有1个 gdb命令是 make:
    make <make-args>
    能够在 gdb中实施 make命令来重新 build自个儿的次序。那些命令等价于 “
shell make <make-args> ”。

在 GDB 中运作程序 ————————**

当以 gdb
<program>方式运维 gdb后, gdb会在 PATH路径和当前目录中追寻 <program>的源文件。如要确认 gdb是还是不是读到源文件,可利用 l或 list命令,看看 gdb是或不是能列出源代码。

在 gdb中,运营程序采纳 r或是 run命令。程序的运作,你有非常大可能率必要设置下边四方面包车型客车事。

一 、程序运转参数。
    set args 可钦赐运营时参数。(如: set args 十 20 30 40 50)
    show args 命令可以查看设置好的周转参数。

2 、运转条件。
    path <dir> 可设定程序的运营路线。
    show paths 查看程序的运作路线。
    set environment varname [=value] 设置环境变量。如: set env
USE猎豹CS六=hchen
    show environment [varname] 查看环境变量。

3 、工作目录。
    cd <dir> 相当于 shell的 cd命令。
    pwd 展现当前的各州目录。

四 、程序的输入输出。
    info terminal 突显你程序用到的极限的格局。
    使用重定向控制造进度序输出。如: run > outfile
    tty 命令能够指写输入输出的顶点设备。如: tty /dev/ttyb

调剂已运维的程序 ————————**

二种方法:
一 、在 UNIX下用 ps查看正在周转的次第的 PID(进程 ID),然后用 gdb
<program> PID格式挂接正在运转的顺序。
二 、先用 gdb
<program>关联上源代码,并开始展览 gdb,在 gdb中用 attach命令来挂接进度的 PID。并用 detach来撤销挂接的进度。

 

停顿 / 苏醒程序运维 —————————**

调节和测试程序中,暂停程序运维是必须的, GDB可以方便地暂停程序的运作。你能够安装程序的在哪行停住,在怎么样条件下停住,在接收什么随机信号时停往等等。以便于你查看运转时的变量,以及运维时的流水生产线。

当进程被 gdb停住时,你能够动用 info
program来查阅程序的是否在运营,进度号,被暂停的原故。

在 gdb中,大家得以有以下两种暂停形式:断点( BreakPoint)、观看点(沃特chPoint)、捕捉点( CatchPoint)、能量信号( Signals)、线程结束( Thread
Stops)。假使要恢复生机程序运行,能够动用 c或是 continue命令。

一、设置断点( BreakPoint )
   
    咱们用 break命令来安装断点。正面有几点设置断点的秘诀:
   
    break <function>
        在进入钦赐函数时停住。 C++中得以应用 class::function或 function(type,type)格式来钦定函数名。

    break <linenum>
        在钦命行号停住。

    break +offset
    break -offset
        在现阶段行号的前头或前边的 offset行停住。 offiset为自然数。

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

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

    break *address
        在程序运营的内部存款和储蓄器地址处停住。

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

    break … if <condition>
       
… 能够是上述的参数, condition代表原则,在标准化建立即停住。比如在循环境体中,能够安装 break
if i=100,表示当 i为 十0时停住程序。

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

二、设置观望点( 沃特chPoint )
   
    观看点一般来考察有个别表明式(变量也是1种表明式)的值是或不是有变化了,倘使有变化,立即停住程序。大家有上边包车型客车二种办法来安装观察点:
   
    watch <expr>
        为表达式(变量) expr设置一个观看点。一量抒发式值有变化时,马上停住程序。
       
    rwatch <expr>
        当表明式(变量) expr被读时,停住程序。
       
    awatch <expr>
        当表明式(变量)的值被读或被写时,停住程序。
   
    info watchpoints
        列出当前所设置了的享有观望点。

3、设置捕捉点( CatchPoint )

    你可设置捕捉点来补捉程序运维时的有的风浪。如:载入共享库(动态链接库)或是C++的充足。设置捕捉点的格式为:
   
    catch <event>
        当 event产生时,停住程序。 event能够是下边包车型客车内容:
        1 、 throw三个 C++抛出的万分。( throw为主要字)
        二 、 catch三个 C++捕捉到的相当。( catch为机要字)
       
三 、 exec调用系统调用 exec时。( exec为关键字,近期此意义只在 HP-UX下有用)
       
四 、 fork调用系统调用 fork时。( fork为第贰字,近来此意义只在 HP-UX下有用)
       
5 、 vfork调用系统调用 vfork时。( vfork为关键字,近来此成效只在 HP-UX下有用)
        陆 、 load或 load
<libname>载入共享库(动态链接库)时。( load为第2字,方今此成效只在 HP-UX下有用)
        柒 、 unload或 unload
<libname>卸载共享库(动态链接库)时。( unload为关键字,最近此意义只在 HP-UX下有用)

    tcatch <event>
        只设置2回捕捉点,当程序停住未来,应点被活动删除。

四、维护甘休点

上边说了如何设置程序的告1段落点, GDB中的结束点也正是上述的叁类。在 GDB中,借使您觉得已定义好的终止点并未用了,你能够运用 delete、 clear、 disable、 enable那多少个指令来展开保险。

    clear
        清除全体的已定义的平息点。

    clear <function>
    clear <filename:function>
        清除全部安装在函数上的告一段落点。

    clear <linenum>
    clear <filename:linenum>
        清除全部安装在钦赐行上的平息点。

    delete [breakpoints] [range…]
        删除内定的断点, breakpoints为断点号。借使不内定断点号,则象征删除全部的断点。 range表示断点号的范围(如: 三-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自动删除。

 

伍、截止条件保险

前边在提及安装断点时,大家提到过能够设置3个准绳,当规则建马上,程序自动停止,那是八个十分强大的机能,那里,小编想越发说说这一个规格的连锁保证命令。1般的话,为断点设置二个原则,大家使用 if关键词,前面跟其断点条件。并且,条件设置好后,我们得以用 condition命令来修改断点的条件。(只有 break和 watch命令援助 if, catch最近暂不扶助 if)

    condition <bnum> <expression>
        修改断点号为 bnum的停下条件为 expression。

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

还有1个相比特殊的掩护命令 ignore,你能够内定程序运转时,忽略结束条件五遍。

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

 

6、为平息点设定运维命令

大家得以应用 GDB提供的 command命令来安装截至点的运作命令。也正是说,当运维的次第在被终止住时,大家得以让其活动运营一些别的命令,那很有利行自动化调节和测试。对基于 GDB的自动化调节和测试是3个无敌的支持。

    commands [bnum]
    … command-list …
    end

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

    例如:

        break foo if x>0
        commands
        printf “x is %d\n”,x
        continue
        end
        断点设置在函数 foo中,断点条件是 x>0,假设程序被断住后,也正是,1旦 x的值在 foo函数中中国足球球组织一流联赛越 0, GDB会自动打字与印刷出 x的值,并继承运维程序。

倘若你要化解断点上的下令系列,那么只要简单的推行一下 commands命令,并向来在打个 end就行了。

柒、断点菜单

在 C++中,恐怕会再一次现身同一个名字的函数若干次(函数重载),在这种情形下,break
<function>不能够告诉 GDB要停在哪些函数的输入。当然,你能够运用 break
<function(type)>也正是把函数的参数类型告诉 GDB,以内定3个函数。否则的话, 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命令恢复程序的运作直到程序截至,或下三个断点到来。也足以选拔 step或 next命令单步跟踪程序。

    continue [ignore-count]
    c [ignore-count]
    fg [ignore-count]
        恢复生机程序运转,直到程序甘休,或是下七个断点到来。 ignore-count表示忽略其后的断点次数。 continue, c, fg四个指令都以同等的情致。

    step <count>
        单步跟踪,借使有函数调用,他会跻身该函数。进入函数的前提是,此函数被编写翻译有debug音讯。很像 VC等工具中的 step
in。后边能够加 count也足以不加,不加表示一条条地履行,加表示执行前边的 count条指令,然后再停住。

    next <count>
        同样单步跟踪,假如有函数调用,他不会进来该函数。很像 VC等工具中的 step
over。后边可以加 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 )

时域信号是1种软中断,是一种处理异步事件的措施。一般的话,操作系统都补助广大连续信号。特别是 UNIX,相比重要应用程序壹般都会处理能量信号。 UNIX定义了诸多随机信号,比如SIGINT表示暂停字符非频限信号,也便是 Ctrl+C的时域信号, SIGBUS表示硬件故障的实信号;SIGCHLD表示子进度意况改变非非确定性信号; SIGKILL代表终止程序运维的时限信号,等等。连续信号量编制程序是 UNIX下尤其重大的一种技术。

GDB 有力量在您调节和测试程序的时候处理任何1种数字信号,你能够告诉 GDB须要处理哪一类时限信号。你能够供给 GDB收到你所内定的时限信号时,立即停住正在运行的次第,以供您进行调节。你能够用 GDB的 handle命令来形成那1功用。

    handle <signal> <keywords…>
        在 GDB中定义3个信号处理。非实信号 <signal>能够以 SIG起先或不以 SIG开首,能够用定义三个要拍卖非实信号的范围(如: SIGIO-SIGKILL,表示处理从 SIGIO时限信号到 SIGKILL的复信号,当中囊括 SIGIO, SIGIOT, SIGKILL八个实信号),也足以动用首要字 all来申明要处理全数的随机信号。1旦被调剂的顺序接收到时域信号,运转程序及时会被 GDB停住,以供调节和测试。其 <keywords>能够是以下二种关键字的三个或四个。

        nostop
            当被调剂的主次收到功率信号时, GDB不会停住程序的运营,但会打出新闻告知您接到那种实信号。
        stop
            当被调剂的先后收到功率信号时, GDB会停住你的主次。
        print
            当被调剂的程序收到功率信号时, GDB会呈现出一条音讯。
        noprint
            当被调剂的次序收到功率信号时, GDB不会告诉您接到时限信号的新闻。
        pass
        noignore
            当被调剂的主次收到复信号时, GDB不处理确定性信号。那代表, GDB会把那几个能量信号交给被调节和测试程序会处理。
        nopass
        ignore
            当被调剂的先后收到非功率信号时, GDB不会让被调节和测试程序来处理那一个随机信号。

    info signals
    info handle
        查看有如何能量信号在被 GDB检验中。

十、线程( Thread Stops )

1旦您程序是二十八线程的话,你能够定义你的断点是还是不是在全数的线程上,或是在有个别特定的线程。 GDB很不难帮你完毕那一办事。

    break <linespec> thread <threadno>
    break <linespec> thread <threadno> if …
       
linespec 钦定了断点设置在的源程序的行号。 threadno内定了线程的 ID,注意,那个 ID是 GDB分配的,你能够通过 “
info threads ”命令来查看正在运维程序中的线程新闻。如若你不点名 thread
<threadno>则象征您的断点设在富无线程上边。你还能为某线程内定断点条件。如:
   
        (gdb) break frik.c:13 thread 28 if bartab > lim

    当您的次第被 GDB停住时,全部的运作线程都会被停住。那便于你你查看运转程序的1体化情状。而在你恢复程序运营时,全体的线程也会被还原运营。那怕是主进程在被单步调节和测试时。

查阅栈音讯 —————**

当程序被停住了,你必要做的率先件事正是翻开程序是在什么地方停住的。当你的程序调用了三个函数,函数的地点,函数参数,函数内的部分变量都会被压入 “栈 ”( 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层的栈新闻。
       
借使您要查看某1层的音信,你须求在切换当前的栈,1般的话,程序停止时,最顶层的栈就是近来栈,要是你要查阅栈上面层的详细音信,首先要做的是切换当前栈。

    frame <n>
    f <n>
        n 是二个从 0初始的平头,是栈中的层编号。比如: frame
0,表示栈顶, frame 一,表示栈的第三层。
   
    up <n>
        表示向栈的地点移动 n层,能够不打 n,表示发展移动一层。
       
    down <n>
        表示向栈的上边移动 n层,能够不打 n,表示向下活动1层。
       

    下边包车型地铁吩咐,都会打字与印刷出活动到的栈层的信息。固然你不想让其打出音信。你能够行使那八个指令:
   
            select-frame <n> 对应于 frame命令。
            up-silently <n> 对应于 up命令。
            down-silently <n> 对应于 down命令。

   
翻看当前栈层的音信,你能够用于下 GDB命令:

    frame 或 f
        会打字与印刷出那个音信:栈的层编号,当前的函数名,函数参数值,函数所在文书及行号,函数执行到的语句。
   
    info frame
    info f
        这些命令会打字与印刷出更为详细的当下栈层的新闻,只但是,半数以上都以运营时的Nene地址。比如:函数地址,调用函数的地点,被调用函数的地址,近期的函数是由什么的程序语言写成的、函数参数地址及值、局地变量的地址等等。如:
            (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
        打字与印刷出当下的函数中的非凡处理消息。

查看源程序 —————**

壹、彰显源代码

   
GDB 能够打字与印刷出所调节和测试程序的源代码,当然,在先后编写翻译时一定要抬高 -g的参数,把源程序音讯编写翻译到实施文书中。不然就看不到源程序了。当程序停下来之后, GDB会报告先后停在了丰富文件的第几行上。你能够用 list命令来打印程序的源代码。照旧来看1看查看源代码的 GDB命令吧。
   
    list <linenum>
        显示程序第 linenum行的方圆的源程序。
   
    list <function>
        呈现函数名称叫 function的函数的源程序。
       
    list
        突显当前行前面包车型地铁源程序。
   
    list –
        展现当前行前边的源程序。

貌似是打字与印刷当前行的上 五行和下 5行,假诺展现函数是是上 贰行下 八行,默许是 十行,当然,你也得以定制展现的限量,使用上边发号施令能够设置三遍显示源程序的行数。

    set listsize <count>
        设置三遍体现源代码的行数。
       
    show listsize
        查看当前 listsize的设置。
       

list 命令还有下边包车型客车用法:

    list <first>, <last>
        展现从 first行到 last行之间的源代码。
   
    list , <last>
        呈现从日前行到 last行之间的源代码。
       
    list +
        以往显得源代码。
       

1般的话在 list前边能够跟以下那们的参数:

    <linenum>   行号。
    <+offset>   当前行号的正偏移量。
    <-offset>   当前行号的负偏移量。
    <filename:linenum>  哪个文件的哪1行。
    <function>  函数名。
    <filename:function> 哪个文件中的哪个函数。
    <*address>  程序运营时的言语在内部存储器中的地方。
   

二、搜索源代码

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

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

    reverse-search <regexp>
        全部物色。
       
内部, <regexp>正是正则表明式,也主二个字符串的匹配形式,关叶昭君则表明式,笔者就不在那里讲了,还请各位查算命关资料。

3、钦命源文件的路径

或多或少时候,用 -g编写翻译过后的进行顺序中只是归纳了源文件的名字,未有路径名。 GDB提供了能够让您内定源文件的不二等秘书籍的指令,以便 GDB实行搜索。

    directory <dirname … >
    dir <dirname … >
        加二个源文件路径到方今路线的前边。假诺您要钦命多个路子, UNIX下你能够动用“
: ”, Windows下您能够使用 “ ; ”。
    directory
        清除全体的自定义的源文件搜索路径音讯。
   
    show directories
        显示定义了的源文件搜索路径。
       

4、源代码的内部存款和储蓄器

你能够采取 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出来。如下边包车型客车以身作则表示查看函数 func的汇编代码。

        (gdb) disassemble func
        Dump of assembler code for function func:
        0x8048450 <func>:       push   %ebp
        0x8048451 <func+1>:     mov    %esp,%ebp
        0x8048453 <func+3>:     sub    $0x18,%esp
        0x8048456 <func+6>:     movl   $0x0,0xfffffffc(%ebp)
        0x804845d <func+13>:    movl   $0x1,0xfffffff8(%ebp)
        0x8048464 <func+20>:    mov    0xfffffff8(%ebp),%eax
        0x8048467 <func+23>:    cmp    0x8(%ebp),%eax
        0x804846a <func+26>:    jle    0x8048470 <func+32>
        0x804846c <func+28>:    jmp    0x8048480 <func+48>
        0x804846e <func+30>:    mov    %esi,%esi
        0x8048470 <func+32>:    mov    0xfffffff8(%ebp),%eax
        0x8048473 <func+35>:    add    %eax,0xfffffffc(%ebp)
        0x8048476 <func+38>:    incl   0xfffffff8(%ebp)
        0x8048479 <func+41>:    jmp    0x8048464 <func+20>
        0x804847b <func+43>:    nop
        0x804847c <func+44>:    lea    0x0(%esi,1),%esi
        0x8048480 <func+48>:    mov    0xfffffffc(%ebp),%edx
        0x8048483 <func+51>:    mov    %edx,%eax
        0x8048485 <func+53>:    jmp    0x8048487 <func+55>
        0x8048487 <func+55>:    mov    %ebp,%esp
        0x8048489 <func+57>:    pop    %ebp
        0x804848a <func+58>:    ret
        End of assembler dump.

 

查阅运维时数据 ———————**
   
    在你调节和测试程序时,当程序被停住时,你能够行使 print命令(简写命令为 p),或是同义命令 inspect来查阅当前先后的周转数据。 print命令的格式是:
   
    print <expr>
    print /<f> <expr>
       
<expr> 是表明式,是您所调节和测试的主次的言语的表明式( GDB能够调剂各个编制程序语言), <f>是出口的格式,比如,固然要把表明式按 16进制的格式输出,那么就是 /x。
       
   
一、表达式**

   
print 和无数 GDB的吩咐一样,可以承受三个表明式, GDB会遵照当前的程序运维的数量来测算这些表明式,既然是表达式,那么就足以是近来程序运维中的 const常量、变量、函数等内容。可惜的是 GDB无法利用你在先后中所定义的宏。
   
    表达式的语法应该是日前所调节和测试的言语的语法,由于 C/C++是1种大众型的言语,所以,本文中的例子都以关于 C/C++的。(而有关用 GDB调节和测试别的语言的章节,小编将在末端介绍)
   
    在表达式中,有两种 GDB所援救的操作符,它们能够用在任何壹种语言中。
   
    @
        是2个和数组有关的操作符,在背后会有更详实的证实。
       
    ::
        钦定三个在文件只怕二个函数中的变量。
       
    {<type>} <addr>
        表示1个针对性内部存款和储蓄器地址 <addr>的品种为 type的一个对象。
       
       
2、程序变量

    在 GDB中,你能够每5日查看以下二种变量的值:
        1 、全局变量(全部文件可知的)
        2 、静态全局变量(当前文件可见的)
        叁 、局地变量(当前 Scope可知的)
       
    假诺您的局部变量和全局变量产生争执(约等于重名),一般景象下是有的变量会暗藏全局变量,也正是说,假若叁个全局变量和三个函数中的局地变量同名时,借使当前甘休点在函数中,用 print彰显出的变量的值会是函数中的局地变量的值。借使那时你想查看全局变量的值时,你能够使用 “
:: ”操作符:
   
        file::variable
    function::variable
    能够透过那种样式钦定你所想查看的变量,是哪位文件中的或是哪个函数中的。例如,查看文件 f二.c中的全局变量 x的值:
   
    gdb) p ‘f2.c’::x
   
    当然, “ :: ”操作符会和 C++中的产生争辩, GDB能自动识别 “ ::
”是或不是 C++的操作符,所以你不用顾虑在调节和测试 C++程序时会出现非常。
   
    别的,需求注意的是,假如您的次第编写翻译时打开了优化增选,那么在用 GDB调节和测试被优化过的程序时,恐怕会产生1些变量无法访问,或是取值错误码的动静。那一个是很健康的,因为优化程序会删改你的主次,整理你程序的语句顺序,剔除壹些抽象的变量等,所以在 GDB调节和测试那种程序时,运行时的下令和你所编纂指令就有不雷同,也就会现出你所想像不到的结果。对付那种情况时,供给在编写翻译程序时关闭编写翻译优化。壹般的话,大约拥有的编写翻译器都协助理编辑译优化的开关,例如, GNU的 C/C++编写翻译器 GCC,你能够使用 “
-gstabs
”选项来缓解这些难题。关于编写翻译器的参数,还请查看编写翻译器的采纳验证文档。
   

三、数组

    有时候,你须要查阅1段连接的内部存款和储蓄器空间的值。比如数组的一段,或是动态分配的数额的尺寸。你能够应用 GDB的 “
@ ”操作符, “ @ ”的右侧是首先个内存的地点的值, “ @
”的右边则你你想查看内部存款和储蓄器的尺寸。例如,你的主次中有如此的言语:
    
        int *array = (int *) malloc (len * sizeof (int));
       
    于是,在 GDB调试进度中,你能够以如下命令彰显出那一个动态数组的取值:

        p *array@len

   
@ 的右边是数组的首地址的值,也正是变量 array所指向的剧情,左侧则是数据的长短,其保存在变量 len中,其出口结果,大概是上边那些样子的:
   
        (gdb) p *array@len
        $1 = {2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30,
32, 34, 36, 38, 40}

    假使是静态数组的话,能够直接用 print数组名,就足以展示数组中颇具数据的内容了。

   
四、输出格式

    壹般的话, GDB会依照变量的种类输出变量的值。但您也得以自定义 GDB的输出的格式。例如,你想出口二个平头的十陆进制,或是二进制来查阅这一个整型变量的中的位的情景。要做到那样,你能够选用 GDB的数额展现格式:
   
    x  按十6进制格式突显变量。
    d  按10进制格式显示变量。
    u  按十陆进制格式突显无符号整型。
    o  按8进制格式呈现变量。
    t  按2进制格式呈现变量。
    a  按十陆进制格式突显变量。
    c  按字符格式展现变量。
    f  按浮点数格式呈现变量。

        (gdb) p i
        $21 = 101   
       
        (gdb) p/a i
        $22 = 0x65
       
        (gdb) p/c i
        $23 = 101 ‘e’
       
        (gdb) p/f i
        $24 = 1.41531145e-43
       
        (gdb) p/x i
        $25 = 0x65
       
        (gdb) p/t i
        $26 = 1100101

伍、查看内部存储器

    你能够动用 examine命令(简写是 x)来查看内部存款和储蓄器地址中的值。 x命令的语法如下所示:
   
    x/<n/f/u> <addr>
   
    n 、 f、 u是可选的参数。
   
   
n 是1个正整数,表示展现内部存款和储蓄器的长度,也正是说从脚下地方向后显得多少个地方的剧情。
   
f 表示显示的格式,参见上边。假设地方所指的是字符串,那么格式能够是 s,固然地十是命令地址,那么格式能够是 i。
   
u 表示从脚下地方以往呼吁的字节数,假诺不钦定的话, GDB暗中认可是 四个 bytes。 u参数能够用下边包车型客车字符来代表, b表示单字节, h代表双字节, w代表四字节, g代表八字节。当大家钦定了字节长度后, GDB会从指内存定的内部存款和储蓄器地址初始,读写内定字节,并把其视作二个值取出来。
   
    <addr> 表示2个内部存款和储蓄器地址。

    n/f/u 三个参数能够一并利用。例如:
   
    命令: x/叁uh
0x54320意味着,从内部存储器地址 0x54320读取内容, h表示以双字节为多个单位, 三代表两个单位, u代表按十6进制展现。
   
   
陆、自动显示

    你能够设置有个别机关展现的变量,当程序停住时,或是在你单步跟踪时,那些变量会自行展现。相关的 GDB命令是 display。
   
    display <expr>
    display/<fmt> <expr>
    display/<fmt> <addr>
   
   
expr 是三个表达式, fmt表示展现的格式, addr代表内部存储器地址,当您用 display设定好了三个或四个表明式后,只要你的次序被停下来, GDB会自动显示你所设置的这个表达式的值。
   
    格式 i和 s同样被 display帮忙,贰个那多少个有效的指令是:
   
        display/i $pc
   
   
$pc 是 GDB的环境变量,表示着命令的地址, /i则表示输出格式为机械指令码,也正是汇编。于是当程序停下后,就会冒出源代码和机器指令码相对应的情事,那是三个很风趣的机能。
   
    下边是一对和 display相关的 GDB命令:
   
    undisplay <dnums…>
    delete display <dnums…>
    删除自动展现, dnums意为所设置好了的自发性显式的编号。借使要同时删除多少个,编号能够用空格分隔,即使要删减多个范围内的号子,能够用减号表示(如: 二-伍)
   
    disable display <dnums…>
    enable display <dnums…>
    disable 和 enalbe不删除自动展现的装置,而只是让其失效和回复。
   
    info display
    查看 display设置的电动展现的音信。 GDB会打出一张表格,向您告知当然调节和测试中装置了多少个自动呈现设置,其中囊括,设置的号子,表明式,是或不是 enable。

7、设置显示选项

    GDB 中有关展现的选项相比多,那里作者只例举大多数常用的选项。

    set print address
    set print address on
        打开地址输出,当程序显示函数音讯时, GDB会显出函数的参数地址。系统暗许为打开的,如:
       
        (gdb) f
        #0  set_quotes (lq=0x34c78 “<<“, rq=0x34c88
“>>”)
            at input.c:530
        530         if (lquote != def_lquote)

    set print address off
        关闭函数的参数地址呈现,如:
       
        (gdb) set print addr off
        (gdb) f
        #0  set_quotes (lq=”<<“, rq=”>>”) at input.c:530
        530         if (lquote != def_lquote)

    show print address
        查看当前地方彰显选项是不是打开。
       
    set print array
    set print array on
        打开数组呈现,打开后当数组突显时,各类元素占1行,假设不打开的话,每一个成分则以逗号分隔。这些选项暗中同意是关门的。与之相关的多个指令如下,我就不再多说了。
       
    set print array off
    show print array

    set print elements <number-of-elements>
        那个选项主尽管安装数组的,假使您的数组太大了,那么就能够内定1个 <number-of-elements>来钦点数量突显的最大尺寸,当到达这么些尺寸时, GDB就不再往下显得了。假如设置为 0,则象征不限定。
       
    show print elements
        查看 print elements的选项信息。
       
    set print null-stop <on/off>
        借使打开了这么些选项,那么当展现字符串时,碰着甘休符则截止彰显。那个选项暗中同意为 off。
       
    set print pretty on
        如若打开 printf
pretty这一个选项,那么当 GDB展现结构体时会相比理想。如:

            $1 = {
              next = 0x0,
              flags = {
                sweet = 1,
                sour = 1
              },
              meat = 0x54 “Pork”
            }

    set print pretty off
        关闭 printf pretty这几个选项, GDB呈现结构体时会如下突显:
       
            $1 = {next = 0x0, flags = {sweet = 1, sour = 1}, meat = 0x54
“Pork”}
           
    show print pretty
        查看 GDB是何等映现结构体的。
       
   
    set print sevenbit-strings <on/off>
        设置字符呈现,是还是不是按 “ \nnn
”的格式展现,假诺打开,则字符串或字符数据按 \nnn显示,如 “ \065 ”。
   
    show print sevenbit-strings
        查看字符呈现开关是或不是打开。
       
    set print union <on/off>
        设置呈现结构体时,是还是不是显式其内的联合体数据。例如有以下数据结构:
       
        typedef enum {Tree, Bug} Species;
        typedef enum {Big_tree, Acorn, Seedling} Tree_forms;
        typedef enum {Caterpillar, Cocoon, Butterfly}
                      Bug_forms;
       
        struct thing {
          Species it;
          union {
            Tree_forms tree;
            Bug_forms bug;
          } form;
        };
       
        struct thing foo = {Tree, {Acorn}};

        当打开这么些开关时,执行 p foo命令后,会如下展现:
            $1 = {it = Tree, form = {tree = Acorn, bug = Cocoon}}
       
        当关闭那些开关时,执行 p foo命令后,会如下突显:
            $1 = {it = Tree, form = {…}}

    show print union
        查看联合体数据的展现方式
       
    set print object <on/off>
        在 C++中,如若一个目的指针指向其派生类,假使打开那些选项, GDB会自动遵照虚方法调用的条条框框展现输出,如若关闭这一个选项的话, GDB就不管虚函数表了。这几个选项默许是 off。
   
    show print object
        查看对象选拔的装置。
       
    set print static-members <on/off>
        这些选项表示,当展现3个 C++对象中的内容是,是还是不是出示中间的静态数据成员。默许是 on。
   
    show print static-members
        查看静态数据成员选项设置。
       
    set print vtbl <on/off>
        当此选项打开时, GDB将用相比较规整的格式来体现虚函数表时。其默许是关闭的。
       
    show print vtbl
        查看虚函数字展现示格式的选项。
       
       
8、历史记录

    当你用 GDB的 print查看程序运营时的数额时,你每一个 print都会被 GDB记录下来。GDB会以 $一,
$2, $叁…..这么的主意为您每1个 print命令编上号。于是,你可以使用那一个号码访问以前的表明式,如 $一。这几个效率所带来的好处是,假设你在此以前输入了三个相比较长的表明式,假设您还想查看这么些表明式的值,你能够运用历史记录来访问,省去了再也输入。
   
   
玖、 GDB 环境变量

    你能够在 GDB的调剂环境中定义自身的变量,用来保存1些调节和测试程序中的运维数据。要定义一个 GDB的变量很粗大略只需。使用 GDB的 set命令。 GDB的环境变量和 UNIX1样,也是以 $开端。如:
   
    set $foo = *object_ptr
   
    使用环境变量时, GDB会在你首先次利用时成立这几个变量,而在随后的行使中,则直接对其賦值。环境变量未有项目,你能够给环境变量定义任一的项目。包涵结构体和数组。
   
    show convenience
        该命令查看当前所设置的具有的环境变量。
       
    那是贰个相比强硬的功力,环境变量和程序变量的相互使用,将使得程序调节和测试更为灵活便捷。例如:
   
        set $i = 0
        print bar[$i++]->contents
   
    于是,当您就不必, print bar[0]->contents, print
bar[1]->contents地输入指令了。输入那样的授命后,只用敲回车,重复执行上一条语句,环境变量会自行抬高,从而成就每一个出口的成效。
   
   
10、查看寄存器

    要翻开寄存器的值,很简短,能够动用如下命令:
   
    info registers
        查看寄存器的情况。(除了浮点寄存器)
   
    info all-registers
        查看全体寄存器的动静。(包罗浮点寄存器)
   
    info registers <regname …>
        查看所钦定的寄存器的图景。
       
    寄存器中放置了程序运维时的数额,比如程序当前运维的授命地址( ip),程序的眼下堆栈地址( sp)等等。你1样可以动用 print命令来访问寄存器的状态,只需求在寄存器名字前加三个 $符号就能够了。如: p
$eip。

改变程序的执行 ———————**

    一旦选用 GDB挂上被调节和测试程序,当程序运转起来后,你能够依据本身的调节思路来动态地在 GDB中改变当前被调节和测试程序的运作路线或是其变量的值,那一个强大的功用能够让您更好的调剂你的先后,比如,你能够在程序的二回运维中走遍程序的富有支行。
   
   
一、修改变量值

    修改被调节和测试程序运转时的变量值,在 GDB中很简单完成,使用 GDB的 print命令即可达成。如:
   
        (gdb) print x=4
   
   
x=4 这么些表明式是 C/C++的语法,意为把变量 x的值修改为 四,假设您日前调节和测试的语言是 帕斯Carl,那么你能够采纳 帕斯Carl的语法: x:=4。
   
    在好几时候,很有极大希望您的变量和 GDB中的参数争辩,如:
   
        (gdb) whatis width
        type = double
        (gdb) p width
        $4 = 13
        (gdb) set width=47
        Invalid syntax in expression.

    因为, set width是 GDB的命令,所以,出现了 “ Invalid syntax in
expression ”的装置错误,此时,你能够行使 set
var命令来报告 GDB, width不是你 GDB的参数,而是程序的变量名,如:
   
        (gdb) set var width=47
       
    别的,还只怕有点情形, GDB并不报告那种指鹿为马,所以确认保证起见,在你改变程序变量取值时,最佳都使用 set
var格式的 GDB命令。
   

2、跳转执行

    一般的话,被调剂程序会依照程序代码的周转顺序依次执行。 GDB提供了乱序执行的效益,也等于说, GDB能够修改程序的实施各样,能够让程序执行随意跳跃。那几个意义能够由 GDB的 jump命令来完:
   
    jump <linespec>
    钦定下一条语句的运维点。 <linespce>可以是文本的行号,能够是 file:line格式,能够是 +num这种偏移量格式。表式着下一条运维语句从何地初阶。
   
    jump <address>
    那里的 <address>是代码行的内部存款和储蓄器地址。
   
    注意, jump命令不会变动最近的程序栈中的内容,所以,当你从一个函数跳到另2个函数时,当函数运行完回到时开始展览弹栈操作时必然会发出错误,大概结果要么不行想获得的,甚至于发生程序 Core
Dump。所以最佳是同三个函数中开始展览跳转。
   
    熟悉汇编的人都精通,程序运维时,有贰个寄存器用于保存当前代码所在的内存地址。所以, jump命令也正是改变了这几个寄存器中的值。于是,你能够使用 “
set $pc ”来改变跳转执行的地址。如:
   
    set $pc = 0x485

三、发生实信号量

    使用 singal命令,能够发生三个能量信号量给被调剂的主次。如:中断时限信号 Ctrl+C。那十三分方便于程序的调剂,能够在程序运营的妄动地方设置断点,并在该断点用 GDB发生1个信号量,那种精确地在某处产生时限信号非凡便宜程序的调剂。
   
    语法是: signal
<singal>, UNIX的体系非随机信号量常常从 一到 15。所以 <singal>取值也在这些界定。
   
   
single 命令和 shell的 kill命令差别,系统的 kill命令发非确定性信号给被调节和测试程序时,是由 GDB截获的,而 single命令所发出一非实信号则是直接发放被调节和测试程序的。
   

四、强制函数重返

    假使您的调节和测试断点在某个函数中,并还有语句未有履行完。你能够应用 return命令强制函数忽略还不曾执行的讲话并回到。
   
    return
    return <expression>
    使用 return命令撤销当前函数的推行,并马上回到,倘使内定了 <expression>,那么该表明式的值会被认作函数的再次来到值。
   
   
伍、强制调用函数

    call <expr>
    表明式中能够1是函数,以此达到强制调用函数的目标。并体现函数的重返值,尽管函数重临值是 void,那么就不显示。
   
    另二个相似的下令也足以成功那1功力 ——
print, print前面能够跟表明式,所以也能够用她来调用函数, print和 call的差别是,假若函数重临 void, call则不出示, print则展现函数再次来到值,并把该值存入历史数据中。

 

在区别语言中运用 GDB ——————————**

GDB 援救下列语言: C, C++, Fortran, PASCAL, Java, Chill,
assembly,和 Modula-贰。1般说来, GDB会依据你所调节和测试的程序来规定当然的调剂语言,比如:发现文件名后缀为 “
.c ”的, GDB会认为是 C程序。文件名后缀为 “ .C, .cc, .cp, .cpp, .cxx,
.c++ ”的, GDB会认为是 C++程序。而后缀是 “ .f, .F
”的, GDB会认为是 Fortran程序,还有,后缀为假若是 “ .s, .S
”的会觉得是汇编语言。

也正是说, GDB会依据你所调节和测试的程序的言语,来设置自身的言语环境,并让 GDB的指令跟着语言环境的更动而更改。比如1些 GDB命令必要采纳表明式或变量时,那几个表明式或变量的语法,完全是依据当前的言语环境而变更的。例如 C/C++中对指针的语法是*p,而在 Modula-第22中学则是 p^。并且,假若你日前的程序是由三种分歧语言一同编写翻译成的,那到在调节和测试进程中, GDB也能遵照不一样的语言自动地切换语言环境。那种跟着语言环境而改变的遵循,真是尊敬开发人士的1种设计。

下边是多少个相关于 GDB语言环境的一声令下:

    show language
        查看当前的语言环境。若是 GDB不能够识为您所调节和测试的编制程序语言,那么, C语言被认为是暗中认可的环境。
       
    info frame
        查看当前函数的程序语言。
       
    info source
        查看当前文件的程序语言。
   
假设 GDB未有检验出近年来的程序语言,那么你也能够手动设置当前的程序语言。使用 set
language命令即可形成。

    当 set
language命令后什么也不跟的话,你能够查看 GDB所支撑的言语类别:
   
        (gdb) set language
        The currently understood settings are:
       
        local or auto    Automatic setting based on source file
        c                Use the C language
        c++              Use the C++ language
        asm              Use the Asm language
        chill            Use the Chill language
        fortran          Use the Fortran language
        java             Use the Java language
        modula-2         Use the Modula-2 language
        pascal           Use the Pascal language
        scheme           Use the Scheme language
       
    于是你能够在 set
language后跟上被列出来的程序语言名,来设置当前的言语环境。
   
有关图片解释

 

符号表

 

l         
符号即变量或函数。符号表负责变量或函数名到其内部存款和储蓄器地址的关系。未有符号表,GDB不只怕理解变量或函数名,如不能透过变量名查看变量。

l         
假诺要为可执行文件发生符号表,须求在编写翻译时使用gcc的-g-ggdb选项。

l         
可以为-g-ggdb选料钦命爆发的信息级别(1到三级),如-g3。级别越高,音讯量越大。默许级别为二。


经过地址空间

 

高地址

命令行参数和环境变量

 

 

向下增长;

 

未使用空间

 

 

向上增长;

 

未初始化数据段(BSS)

未初始化全局变量,程序执行前初始化为0或NULL;

 

已初始化数据段

由exec从程序文件读取;

低地址

文本段

由exec从程序文件读取;

l         
栈中保存了函数调用关系。每调用二个函数,分配一个栈帧,记录函数重返地址、传递的参数以及一些变量。

l         
能够动用GDB的backtrace(缩写为bt)命令查看栈新闻。最前边的数字代表帧号。

(gdb) bt

#0  func2 () at gdb_test.c:35

#1  0x080484a9 in func1 (iptr=0xbf98a2f0) at gdb_test.c:28

#2  0x08048453 in main (argc=Cannot access memory at address 0xc) at gdb_test.c:14

l         
能够选取frame(缩写为f)命令查看当前栈帧,即当前所在的函数。

l         
GDB只好查看当前函数内的变量。如若要查看其余函数内的变量,供给切换栈帧,方法是为frame一声令下传递帧号。

(gdb) p i

No symbol "i" in current context.

(gdb) frame 2

#2  0x08048453 in main (argc=Cannot access memory at address 0xc) at gdb_test.c:14

(gdb) p i

$1 = 3


运维程序

 

l          要在GDB中运转程序,能够在shell中输入gdb ./filename

l          大概在运营GDB后,通过file一声令下打开程序。

l         
调用run(缩写为r)命令开头施行。能够为run命令传递命令行参数。set
args
指令撤除从前传递的参数。

(gdb) run 1 2 3

Starting program: /home/pydeng/gdb_test/gdb_test 1 2 3

There are 4 args.

l         
调用kill(缩写为k)命令甘休程序的执行,然后选择run重复运维。

l         
只怕在程序运维的时候重新调用run指令,GDB将领悟是否再次运维程序。


查看代码

 

l         
能够选拔list(缩写为l)命令呈现当前任务前边的十行代码。加上负号则显示后面十行,如list

l          能够以三种方法钦赐展现的岗位,如:

从第5行开始

(gdb) list 5, 

到28行结束

(gdb) list ,28 

显示21到25行之间的代码

(gdb) list 21,25 

显示func1函数

(gdb) list func1 

显示其它文件的12行

(gdb) list otherfile.c:12 

显示其它文件的函数

(gdb) list otherfile.c:func

l          能够通过set指令改变显示的代码行数,如set listsize 5


安装断点

 

l          使用break指令设置断点,断点的岗位能够透过二种艺术钦定。

通过函数名指定

(gdb) break func1 

通过行号指定

(gdb) break 9 

通过文件名和行号指定

(gdb) break main.c:10 

通过内存地址指定

(gdb) break *0x80483f4

l          也能够在到达断点的时候,依照如今的任务设置断点。如break
+2
在时下地方前面第3行的地点设置断点,break
-3
在近日地方的前边第②行的职位设置断点。

l          能够由此where指令查看当前所在的地点。

l          能够为断点添加条件,唯有当规则满意时才会在断点处暂停程序。

(gdb) b 17 if i==1

Breakpoint 8 at 0x8048455: file gdb_test.c, line 17.

l          程序到达断点暂停后,能够运用continue指令恢复生机执行。

l         
或然应用stepnext一声令下单步执行。两者的差距在于,step指令将进入被调用的函数,而next指令将函数调用看作一条语句。

l          info breakpoints(缩写为i
b
)命令能够查阅设置的保有端点。Num为断点号,Enb标识端点是不是启用。

(gdb) i b

Num     Type           Disp Enb Address    What

6       breakpoint     keep n   0x08048436 in main at gdb_test.c:12

8       breakpoint     keep y   0x08048455 in main at gdb_test.c:17

     stop only if i==1

l         
能够运用cleardelete命令删除断点,前者选用上述各个钦点断点地方的办法标识断点,后者使用断点号标识断点。

l         
通过传递断点号,disableenable命令能够一时半刻停用或重新启用断点。


翻开变量

 

l         
使用ptype(缩写为pt)命令查看变量的项目。要牢记,只好查看当前栈帧内的变量。

l         
使用print(缩写为p)命令加变量名,能够查看变量的值,也能够动用取地址符查看变量的地址,并且能够指引显示的格式。

 

o octal   x hex   d decimal  u unsigned decimal

t binary  f float  a address  c char 

 

(gdb) p /x i

$3 = 0x1

 

 

 

l         
查看数组时,能够内定彰显的因素初步地点和要素个数,可是不会检讨是或不是越界。

(gdb) p array[2]@5

$4 = {3, 4, 5, 6, 134514064}

l          也能够查看结构体。使用set print pretty一声令下优化显示格式。

(gdb) p p

$6 = {age = 25, name = 0x80485a7 "cying"}

(gdb) set print pretty

(gdb) p p

$7 = {

  age = 25,

  name = 0x80485a7 "cying"

}

l         
能够选拔setprint命令,在程序执行进程中,改变变量的值,如set
i = 5
print i = 5。两者分别在于,后者打字与印刷改变后的值。

(gdb) set array[0]=11

(gdb) p array[1]=22

$8 = 22

(gdb) p array

$9 = {11, 22, 3, 4, 5, 6}

 

后记 ——**

   
GDB 是三个强劲的命令行调节和测试工具。大家明白命令行的兵不血刃就是在乎,其得以形成执行连串,形成脚本。 UNIX下的软件全是命令行的,那给程序支付提代供了庞大的有益,命令行软件的优势在于,它们能够极度简单的融会在共同,使用多少个简单的已有工具的命令,就能够做出二个不胜强劲的效益。  

(一)  使用GCC进行编写翻译时,需在编写翻译选项中到场”-g“参数

git clone
git://github.com/cgdb/cgdb.git

       cc -g main.c -o main
       g++ -g main.cpp -o main

cd cgdb

(2)
 使用GCC举办编译时,为了能使指令与源代码对应上,编写翻译选项中并非进入启用优化的”-O”参数

./autogen.sh

(三)  使用gdb调节和测试前,要先进入待调试模块所在目录(使得能科学关联到源代码文件)

./configure –prefix=/usr/local

(四)  进入gdb调节和测试情形,直接回车表示”重复上3回命令”

make

(5)  按上下方向键可以浏览和选择之前输入过的通令

sudo make install

(六)
 gdb中,输入指令时,能够绝不打全命令,只用打命令的前多少个字符就足以了,当然,命令的前多少个字符应该要申明着一个唯一的通令。

  1. -g gcc 编写翻译加入指令 ffmpeg 编写翻译 打开 enable-debug
  2. 敞开log记录 gdb set logging on -> 打开记录作用。
  3. bt 查看堆栈
  4. b <行号>
    b <函数名称>
    b *<函数名称>
    b *<代码地址>
    d [编号]

      在Linux下,你能够打击两次TAB键来补齐命令的全称,要是有重复的,那么gdb会把其列出来

b:
Breakpoint的简写,设置断点。两足以动用“行号”“函数名称”“执行地址”等艺术钦点断点地点。
个中在函数名称前边加“*”符号表示将断点设置在“由编写翻译器生成的prolog代码处”。若是不打听汇编,能够不予理会此用法。
d: Delete
breakpoint的简写,删除钦定编号的某部断点,或删除全体断点。断点编号从一早先递增。

(7)  可从此刻下载最新的gdb [http://www.gnu.org/software/gdb/download/

(gdb) b 8
(gdb) b main
(gdb) b *main
(gdb) b *0x804835c
(gdb) d

#
调节和测试进度

五.跳出循环 until 钦点行

gdb test         // 调节和测试当前目录下的名字为test的可执行程序  
 输入r,运维程序

跳出函数 finish

gdb -p PID     // 勾住目的经过展开调节
 PID为对象经过ID,可因此ps
-ux
来查看当前运作的历程

6.gdb的命令watch,监视i,命令是watch i

attach
21四陆   // 附加到PID为21四6的进程上

r Run的简写,运转被调剂的次序。
若果原先未曾下过断点,则履行完全体程序;若是有断点,则程序暂停在第二个可用断点处。
(gdb) r
c 孔蒂nue的简写,继续执行被调节和测试程序,直至下八个断点或程序停止。

detach
214陆  // 释放对PID为21四陆进度的调剂

ignore 二 5,这一个意思就是忽视二号断点六次。

q                 // 结束gdb调试 [quit]

p <变量名称> Print的简写,突显钦定变量(一时半刻变量或全局变量)的值。
(gdb) p i
(gdb) p nGlobalVar

#
运维额外参数

q Quit的简写,退出GDB调节和测试环境。 (gdb) q

-se symbolfile    // 从钦赐文件中读取符号表消息,并用在可执行文件中

help [指令名称] GDB扶助命令,提供对GDB名种命令的诠释表达。
万一钦赐了“命令名称”参数,则体现该命令的详尽表达;借使未有点名参数,则分类展现全数GDB命令,供用户越来越浏览和询问。
(gdb) help display

-c corefile      // 调试core dump的core文件

display …
undisplay <编号>

如:gdb gamesvrd.0 -c
/data/corefile/core_gamesvrd.0_11833_1358767740  // 供给进入gamesvrd.0的目录

display,设置程序中断后欲展现的多寡及其格式。
比如说,假使愿意每一遍程序中断后方可看出就要被实践的下一条汇编指令,可以利用命令
“display /i $pc”
在那之中 $pc 代表当前汇编指令,/i
表示以十6实行显示。当须要关爱汇编代码时,此命令格外有效。
undispaly,打消从前的display设置,编号从一发端递增。

-d directory    // 参预三个源文件的查找路径  
私下认可搜索路径是环境变量中PATH所定义的不二法门

(gdb) display /i $pc
(gdb) undisplay 1

若当前调节和测试进度的可执行文件目录中盛名称为.gdbinit文件,在开发银行调试时会执行该脚本(下边为三个文书内容示例)

(gdb) l :(字母l)列出源码
(gdb) b n :在第n行处设置断点
(gdb) b func:在函数func()的入口处设置断点


(gdb) 条件断点:条件能够是别的合法的c 表明式。 例如 b n if val1==val二

b YXSCubeData.cpp : 2653

      当已经设置了断点,可以用condition 命令对断点号添加条件, 例: condition 2 val1==val2 , 注意,没有if 单词

      当对变量的改变更感兴趣时,可以用watch 命令

c

#
调试

0. 先后参数

set args -b -x  // 修改发送给程序的参数,将-b和-x参数发送给程序

show args       // 显示程序当前的参数

一. 安装断点  [break]

b worker.cpp : 四5   // 在worker.cpp文件的四五行处设置1个断点

b 45   // 在此时此刻文件的肆伍行处设置一个断点

b worker.cpp : CWorker::DoWork
 //
在worker.cpp文件的DoWork函数发轫处设置一个断点


若有命名空间,还应带上命名空间  b
worker.cpp : MYP纳瓦拉J::CWorker::DoWork

若函数被重载,还应带上参数类型  b
worker.cpp : CWorker::DoWork(bool)


b +五  // 在相距当前地方的后五行处设置贰个断点

b -6  // 在相距当前地方的前陆行处设置一个断点

b … if <条件>  // 条件断点

例:b worker.cpp : 45 if
workerNum==5 

例:b worker.cpp : CWorker::DoWork if
workerNum==5

贰. 查看断点   [info breakpoints]

i b    //
查看当前持有断点(各类断点都有1个数码)

三. 剥夺/启用断点

disable 一  // 禁止使用数码为1的断点

enable 壹   // 启用编号为一的断点

disable     // 禁止使用全数断点

enable      // 启用全体断点

四. 去除断点  [delete breakpoints]**

d 一   // 删除编号为一的断点

d      // 删除全体断点

伍. 调剂执行控制

r  //
调节和测试运营进度 [run]

k  //
结束方今调节和测试的长河 [kill]

c  //
继续运营 [continue]  
相当于vc中的F5

ctrl+c  // 暂停程序运营

n  //
单步执行 [next] 相当于vc中的F10

n 二  // 2为步进数目

s  //
step
into到函数内部 相当于vc中的F11

finish/fin  // step
out出函数 相当于vc中的shift+F11

u   // 当您厌倦了在二个循环体内单步跟踪时,这几个命令能够运转程序直到退出循环体
 [until]

u 1四5 //执行至1四五行代码停下 

陆. 翻看变量  [print]

p nSum   // 打字与印刷nSum变量的值 

p /fmt nSum  // 按钦命格式打字与印刷nSum变量的值


fmt为以下值
x 十陆进制  d 十进制
u 无符号数  o 八进制
t 贰进制     a
十6进制打印【地址】
c 字符格式  f 浮点数   s 字符串


p h@10  // 查看数组h的前13个值

p
*bar  // 查看指针bar所指对象内容

whatis nSum  // 查看变量nSum的品类

ptype
foo   // 查看foo的类型定义

w exp  // 查看表明式exp的值 [watch]

七. 改动变量

p x=4    // 将x的值修改为四

八.
翻看内部存款和储蓄器

x/<n/f/u> <addr>

n、f、u是可选的参数。
n
是1个正整数,表示彰显内部存款和储蓄器的长度,约等于说从眼下地点向后显得多少个地点的始末。
f 表示突显的格式,参见【6.查看变量fmt的验证】。假使地点所指的是字符串,那么格式能够是s,假若地点是命令地址,那么格式能够是i。
u 代表从此时此刻地点以后呼吁的字节数,若是不点名的话,GDB暗许是陆个bytes。
u参数可以用上面的字符来取代,b表示单字节,h表示双字节,w表示四字节,g表示八字节。
当大家钦命了字节长度后,GDB会从指内部存款和储蓄器定的内部存款和储蓄器地址开端,读写指定字节,并把其当作多少个值取出来。

如:x/3uh 0x54320EED

//
从内存地址0x54320EED读取内容,h表示以双字节为多个单位,三意味四个单位,u表示按十陆进制展现。

玖. 别的调节和测试音信查看

bt  // 查看堆栈调用 [backtrace]


有时大家经过bt命令,看到的仓库消息是错乱的(一堆的???),如下:

图片 1

本着那种景观,能够使用以下方法来查阅堆栈:
(一) 从ebp获取函数调用堆栈的head指针

图片 2

(二) 展现堆栈的heard指针内部存款和储蓄器块的始末

图片 3

(3) 对当下函数重回地址施行info
symbol命令,打印出最近函数栈帧新闻(含函数名)

图片 4

## 完整的事例:

图片 5


frame
三  // 跳转到函数堆栈中索引为3的函数上下文

i reg // 显示寄存器消息 [info]

i func  // 显示全数的函数名

i local  // 显示当前函数的有所片段变量的音信

i prog  // 呈现调节和测试程序的施市价况

十. 代码载入  [先后必须被断点断住]

Ctrl+ x  Ctrl + a  // 将代码载入到命令行中举行调节和测试

l  //
载入当前代码行的上下各4行代码 [list]

l 4伍  // 展现当前文件按第伍五行的四周代码

l worker.cpp
: 70 // 突显work.cpp第十0行的周边代码

l worker.cpp
: sum // 呈现work.cpp中sum函数的相近代码

l CWorker::DoWork(bool)  // 展现函数名叫CWorker::DoWork(bool)的函数的代码

l
0xabcd123四  //  查看地址为0xabcd123四的周边的代码

11. 多线程

i
threads  // 展现线程音信

thread
二   // 切换成线程表中索引为2的线程

b foo 二  // 在函数foo设置断点,并且只在目录为2的线程中命中

1贰. 强制操作

call A(一,贰)  // 强制调用函数A,并输出其重临值

return   // 使用return命令打消当前函数的实践,并及时再次回到

return exp  // 假若钦定了exp,那么该表明式的值会被认作函数的重临值

 

更详实请参考:用GDB调试程序(1) 
 用GDB调节和测试程序(二) 
 用GDB调节和测试程序(3)

                   用GDB调节和测试程序(4) 
  用GDB调节和测试程序(五) 
 用GDB调节和测试程序(6)  用GDB调节和测试程序(七)

(gdb) info break: 查看断点音讯
(gdb) r:运维程序
(gdb) n:单步执行
(gdb)
s:单步调节和测试若是有函数调用,则进入函数;与命令n分化,n是不进入调用的函数的
(gdb) c:继续运维
(gdb) p 变量 :打字与印刷变量的值 也能够修改变量的值(用 = 赋值) //
打字与印刷寄存器值。 p $eax

(gdb) x/nfu <addr> 展现内部存储器 // n为个数,f 为格式,u为每单元长度
(gdb) bt:查看函数堆栈
(gdb) finish:退出函数

(gdb) display <var> 每一遍中断或单步都呈现你关切的变量

(gdb)undisplay <编号>
(gdb) shell 命令行:执行shell命令行
(gdb) set args 参数:钦定运营时的参数
(gdb) show args:查看设置好的参数
(gdb)info program: 来查看程序的是还是不是在运作,进度号,被中止的因由。 //
打字与印刷寄存器数组, info reg, 简写 i reg
(gdb)clear 行号n:清除第n行的断点
(gdb)delete 断点号n:删除第n个断点
(gdb)disable 断点号n:暂停第n个断点
(gdb)enable 断点号n:开启第n个断点


gdb 条件调节和测试

“break … if cond” 命令
例: b fun() if i==20

ignore bnum count
watch var // 此时监测var的扭转


gdb 二10多线程调节和测试

info threads
thread ID 来切换
set scheduler-locking off|on|step
估量实际运用过多线程调节和测试的人都足以窥见,
在使用step恐怕continue命令调节和测试当前被调剂线程的时候,其余线程也是还要执行的,
怎么只让被调节和测试程序执行吗?通过这几个命令就足以兑现那一个需要。
off 不锁定任何线程,也正是独具线程都施行,那是暗中认可值。
on 唯有当前被调节和测试程序会实施。
设置 on 之后, step 在单步的时候, 唯有当前线程会执行。
next过叁个函数的意况(熟习景况的人只怕清楚,那实则是二个设置断点然后continue的表现)。

一.gdb有个很团结的调式界面,正是layout格局调节和测试,能够让你边调节和测试变查看源码,
只是layout格局有时候某个bug,但是大多还能利用,
能够用ctrl+x和ctrl+a
来切换。或者layout会造成控制台花屏,使用ctrl+L清屏。


GDB堆栈跟踪的措施

次第“调用堆栈”是日前函数以前的持有已调用函数的列表(包蕴近期函数)。每一种函数及其变量都被分配了三个“帧”,
近来调用的函数在 0 号帧中(“头部”帧)。要打印堆栈,发出指令
‘bt’(’backtrace’ [回溯] 的缩写):
(gdb) bt

0 0x80483ea in wib (no1=8, no2=8) at eg1.c:7

1 0x8048435 in main (argc=1, argv=0xbffff9c4) at eg1.c:21

此结果展现了在 main() 的第 二一 行中调用了函数 wib()(只要使用 ‘list 二一’
就能印证这点),而且 wib() 在 0 号帧中,
main() 在 1 号帧中。由于 wib() 在 0
号帧中,那么它即是进行顺序时发生算术错误的函数。
事实上,发出 ‘info locals’ 命令时,gdb
会打字与印刷出当下帧中的局部变量,缺省情况下,那一个帧中的函数正是被搁浅的函数(0
号帧)。
能够行职责令 ‘frame’ 打字与印刷当前帧。要翻开 main 函数(在 1号帧中)中的变量,能够生出 ‘frame 一’ 切换来 一 号帧,
接下来发出 ‘info locals’ 命令:
(gdb) frame 1

1 0x8048435 in main (argc=1, argv=0xbffff9c4) at eg1.c:21

21 result = wib(value, div);
(gdb) info locals
value = 8
div = 8
result = 4
i = 2
total = 6

此新闻显示了在第2回施行 “for” 循环时(i 等于 2)发生了错误,此时
“value” 等于 “div”。
能够透过如上所示在 ‘frame’ 命令中显然钦定编号,恐怕采取 ‘up’
命令在库房中上移以及 ‘down’ 命令在仓库中下移来切换帧。
要博取有关帧的愈加消息,如它的地址和程序语言,能够使用命令 ‘info
frame’。
gdb 堆栈命令能够在程序执行时期选择,也足以在 core
文件中央银行使,因而对此复杂的先后,能够在程序运行时跟踪它是何许转到函数的。
查阅栈音信
当程序被停住了,你要求做的率先件事正是查看程序是在哪儿停住的。
当你的主次调用了3个函数,
函数的地方,函数参数,函数内的某些变量都会被压入“栈”(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是3个正整数,表示只打字与印刷栈顶上n层的栈消息。
backtrace <-n> ,bt <-n>
-n表一个负整数,表示只打字与印刷栈底下n层的栈音信。
假使您要翻看某1层的音讯,你要求在切换当前的栈,1般的话,程序截止时,最顶层的栈正是最近栈,若是你要翻开栈上面层的详细消息,首先要做的是切换当前栈。
frame <n>,f <n>
n是2个从0伊始的整数,是栈中的层编号。比如:frame 0,表示栈顶,frame
一,表示栈的第一层。
up <n> 表示向栈的地点移动n层,能够不打n,表示发展移动一层。
down <n> 表示向栈的下边移动n层,能够不打n,表示向下活动1层。
下边包车型地铁吩咐,都会打字与印刷出活动到的栈层的音信。借使你不想让其打出新闻。你能够选拔那八个指令:
select-frame <n> 对应于 frame 命令。
up-silently <n> 对应于 up 命令。
down-silently <n> 对应于 down 命令。
查看当前栈层的音讯,你能够用以下GDB命令:
frame 或 f
会打字与印刷出这几个音讯:栈的层编号,当前的函数名,函数参数值,函数所在文书及行号,函数执行到的说话。
info frame,info f
那么些命令会打字与印刷出更为详细的当下栈层的音信,只不过,超越1/三都是运营时的Nene地址。比如:函数地址,调用函数的地点,被调用函数的地点,近年来的函数是由什么的程序语言写成的、函数参数地址及值、局地变量的地址等等。如:
(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 打印出如今的函数中的很是处理新闻。

gdb 跟踪远程调节和测试命令交互进程
“set debug remote 壹” 将突显gdb 远程调节和测试的历程。

gdb 内部存款和储蓄器断点设置。
rwatch, watch, awatch 分别代表读,写,读写内存断点,用的是硬件断点。


gdbtui gdb 图形化接口。方便调试
先导gdb, 按ctrl-x cta-a 也可进入tui 方式


help layout
layout src
layout asm
layout split

help winheight
winheight src +5
winheight src -4

help focus
focus cmd
focus src
focus next
简记为
fs next
fs src
fs cmd


help info
Generic command for showing things about the program being debugged.
至于被调节和测试程序的局地新闻
help show
Generic command for showing things about the debugger
有关debugger状态的1部分消息


常用命令:

set args

file

source

set logging overwrite on
set logging on
set print pretty
show logging
set pagination off // 不要出现 Type <return> to continue
的提醒消息
info functions
info variables

list

list [函数名称]

与调节控制相关的授命

continue 继续运转程序直到下2个断点(类似于VS里的F5)
next 逐进程步进,不会进去子函数(类似VS里的F拾)
step 逐语句步进,会进入子函数(类似VS里的F1一)
until 运维至当下语句块停止
finish 运维至函数甘休并跳出,并打字与印刷函数的重返值(类似VS的Shift+F1一)

s : step in

fin: step out, 跳出函数

until 行号。 可用来跳出循环,加速了调节速度。


gdb 调节和测试跟踪多进度程序

gdb只好跟踪八个进度(暗中同意是跟踪父进程),而不能够同时跟踪五个经过,
能够安装gdb跟踪父进度照旧子进程, 命令如下:
set follow-fork-mode parent 跟踪父进程, 暗中同意
set follow-fork-mode child 跟踪子进度

相关文章