GDB调节和测量试验器用法,调节和测量检验工具gdb

环境:gcc (OpenWrt/Linaro GCC 4.8)

1.1 gdb符号调节和测量试验器简单介绍

  gdb是四个用来调节和测验C和C++程序的功用强盛的调节和测量检验器,它能在程序运行时考查程序的内部结交涉内部存款和储蓄器的应用处境。

  gdb首要提供以下三种成效:

  • 蹲点程序中变量值的变迁
  • 安装断点,使程序在钦赐的代码行上暂停实践,便于阅览
  • 单步实施代码
  • 剖析崩溃程序产生的core文件

    gdb filename

    编写翻译时需加上-g 或 -ggdb3 选项

转自:http://21cnbao.blog.51cto.com/109393/223565

以如下的简约代码为例,表明gdb的行使。

1.2 gdb效用详整及其使用

  1.2.1调解步骤

    1.调用gdb

      gdb filename

    2.安装断点并调整

      break
functionname/linenumer

      run 实践顺序

      step 单步追踪程序代码

    print命令:

      print 表达式

      print 变量=表达式

      print
起头表明式@要打字与印刷一连内部存款和储蓄器空间的轻重

    display命令:

      display 表达式

      在动用display命令时,每一遍调节和测验器中断程序,挂起指令都要呈现变量的值

    next命令:

      不进去函数内部

    quit命令:

      退出gdb

  1.2.2 呈现数据命令

    1. print命令与display命令

    finish 实行完当前函数

    2. 内部存储器检查命令

      x /format address

        format指呈现单元的个数以至突显的格式

      例如:x/2c 0x120100fa0

    3.printf 类似于c里的printf()函数

      例如:printf”%2.2s\n”,0x120100fa0

    4.使用set命令

      set variable 变量=表明式 设置变量值

  1.2.3 使用断点

    continue命令和cont命令(cont 数字 表示施行数字次两次三番卡塔 尔(阿拉伯语:قطر‎

    break 行号

    break 函数名

    条件断点:

      condition 断点编号 表达式 程序在表明式为真时中断

    tbreak 行号  一时断点

    (break 行号

     enable delete 断点号卡塔 尔(英语:State of Qatar)等效于有时上贰个断点

    enable  断点编号 复苏失效断点

    disable  断点编号     使断点失效

    delete   断点编号或表明式        灭绝断点

    clear   要湮灭的断点所在行号      消弭断点

  1.2.4 使用观看窗口

    watch  表明式
假诺表明式中某些变量的取值超越了限制,就不能够再对表达式取值了。那一点与标准断点设置不一样,因为它只在代码的定势地点取值。

  1.2.5 查看栈消息

    backtrace

    bt

    bt n  栈顶上n层栈新闻

    bt -n  栈顶下n层栈新闻

    frame n

    f n n是四个从0最初的整数,是栈中的层编号。比方:frame
0表示栈顶,frame 1表示栈的第二层

    up n  表示向栈之处移动n层,不输入n表示移动风华正茂层

    down n  表示向栈的底下移动n层

    以下为不带提醒音信的运动栈层音讯:

      select-frame n

      up-silently n

      down-silently n

      —————

      frame 或 f
查看当前栈层消息(包涵栈层编号,当前函数名,函数参数值,函数所在文件及行号,函数实行到的语句卡塔 尔(阿拉伯语:قطر‎

      info frame 或 info f
  该命令会突显尤其详细的当下栈层的新闻,只不过大超多都是运维时的内地址。

      info args  显示出当下函数的参数名及值

      info locals  展现出当下函数中具有片段变量的值

      info catch  呈现当前函数中的分外管理新闻      

  1.2.6 查看源程序

    1. 显得源代码 

      list
<linenum>    呈现程序第linenum行的相近的源程序。

      list
<function>    展现函数名称叫function的函数的源程序

      list          突显当前行后边的源程序

      list -         展现当前进后面包车型大巴源程序

      set listsize <count>  设置一回突显源代码的行数

      show listsize  查看当前listsize的装置

      list
<first>,<last>  呈现从first行到last行之间的源代码

      list ,<last>  显示当前进到last行之间的源代码

      list +  向后显得源代码

      日常的话,在list前边能够跟以下这么些参数。

      <linenum>:行号。

      <+offset>:当前进号的正偏移量

      <-offset>:当前进号的负偏移量

      <filename:linenumber>:哪个文件的哪生龙活虎行

      <function>:函数名

      <filename:function>:哪个文件的哪位函数

      <*address>:程序运营时的言语在内部存款和储蓄器中的地址

    2.找寻源代码

      forward-search <regexp>

      search <regexp>  向前寻觅

      reverse-search <regexp>  全体招来

    3.钦定源文件的不二秘技

      directory <dirname …>

      dir <dirname …>

      directory  消弭全数自定义源文件寻觅路径消息

      show directories  显示定义了源文件找出路线

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

      info line 行号/函数名

      info line 文件名:行号/文件名:函数名

      disassemble func  查看func的汇编代码

      disassemble address

  1.2.7 查看运转时数据

    1.表达式

      @  三个和数组有关的操作符

      ::  内定叁个在文书可能多个函数中的变量

      {<type>} <addr>  
表示二个针对性内部存款和储蓄器地址<addr>的类型为type的叁个对象

    2.程序变量

      全局变量

      静态全局变量

      局部变量(当前Scope可以知道的卡塔尔国

      示例:

        file::variable

        function::variable

        p ‘f2.c’::x

    3.数组

      比如:程序中犹如下语句

        int *array = malloc(len * sizeof;

      p *array@len

      假若是静态数组的话,直接用”print
数组名”就足以显得数组中负有数据的剧情了。

    4.输出格式

      x  按十四进制格式彰显变量

      d  按是明确命令禁绝格式展现变量

      u  按十三进制格式显示无符号整形

      o  按八进制格式呈现变量

      t  按二进制格式呈现变量

      a  按十五进制格式显示变量

      c  按字符格式彰显变量

      f  按符点数格式显示变量

    5.查看内部存款和储蓄器

      x/<n/f/u> <addr>  nfu是可选参数。

                n表示展现内存的尺寸,

                f表示突显的格式,

                u表示从脚下地点今后倡议的字节数,若是不钦赐的话,gdb暗中认可是4个bytes。

                u可用以下字符来替代:b表示单字节,h双字节,w四字节,g八字节。

                addr表示二个内部存款和储蓄器地址。

      示例:

      x/3uh
0x54320    以无符号整形双字节为单位展现从地址0x54320伊始的3个长度的内存中的内容

    6.自动显示

      可以设置某些机动彰显的变量,当程序停住时,或是在单步追踪时,那些变量会自动的显得。

      display <expr>

      display/<fmt> <expr>

      display/<fmt> <addr>

      格式i和s相仿被display扶植,二个不行又用的一声令下是:

      display /i $pc 
$pc是gdb的景况变量,表示指令的地点,/i则意味着输出格式为机械指令码,也便是汇编。与是当程序停下后,就能忍俊不禁源代码和机器码相对应的情形。

      undisplay <dnums…>

      delete display <dnums…>

        删除自动展现,dnums意为设置好了的机关突显的编号。假诺要同不时间删除多少个号码,能够用空格分隔;假设要删减多少个范围内的号子,能够用减号表示。

      disable display <dnums…>

      enable display <dnums…>

        不删除自动呈现的设置,而只是让其失效和死灰复燃,而只是让其失效和恢复生机。

      info diaplay

        查看display设置的机动突显的消息。gdb会展现出一张表格,报告中安装了稍微个活动彰显设置,当中囊括安装的号码,表明式以致是不是enable。

    7.设置显示选项

      set print address on/off  彰显函数参数地址 系统暗许展开

      show print address    查看当前地点展现选项是或不是展开

      set print array on/off  
展开/关闭数组展现,展开后数组展现时每一个成分占意气风发行;关闭时每一种成分以逗号分隔。这一个选项默许时关闭的。

      show print array

      set print elements
<number-of-elements>  这么些选项首要时设置数组的,假诺数组太大了,就可以钦点三个<number-of-elements>来钦定数量展示的最大尺寸,当达到那个长度时,gdb就不再往下显得了。假使设置为0,则表示不节制。

      show print elements

      set print null-stop
<on/off>  假诺展开了那一个选项,那么当呈现字符串时,碰着截止符则截至展现。那些选项默觉得off。

      set print pretty
on/off  选项张开时,当gdb呈现结构体时会相比较不错。

      show print pretty

      set print sevenbit-stirngs
<on/off>  设置字符展现,是或不是按“\nnn”的格式显示。假设展开,则字符串或字符数据按\nnn显示,如“\065”

      show print sevenbit-stirngs

      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  查看虚函数字展现示格式的选料

    8.历史记录

      每种print命令都会被gdb记录下来。gdb会以$1,$2,$3……那样的方法为每三个print命令编上号。于是,可以使用这些号码访谈早先的表达式,如$1。

    9.gdb意况变量

      能够在gdb调试意况中定义自身的变量,用来保存一些调节和测验程序中的运转数据。

      情况变量没有项目,能够给景况变量定义任性的连串,包罗结构体和数组。

      set $foo = *object_ptr

      show convenience  查看当前所设置的持有的碰着变量

      (set i = 0

      print
bar[$i++]->contents)  那么些贰个比较强硬的效率,景况变量与程序变量的相互作用使用使得程序调节和测量试验更为灵活方便。输入那样的吩咐后,按下Enter键,重复实施上一条语句,景况变量会自行扩充,进而成就各种出口的效能。  

    10.翻看寄放器

      info registers  查看贮存器的图景

      info all-registers  查看全部存放器的意况

      info registers <regname…>  查看钦点存放器的事态

  1.2.8 改动程序的实行

    1.改良变量值

      print x=4

      whatis width  

      set var width=47

    2.跳转实践

      jump
<linespec>  <linespec>能够是文件的行号,能够是file:line格式,能够是+num这种偏移量格式。表示下一条语句从哪个地方起首。

      jump
<address>  这里的<address>是代码行的内存地址。

      建议在同叁个函数内调转

      明白汇编的人都清楚,程序运营时有一个贮存器用于保存当前代码所在的内存地址。所以,jump命令也等于改进了那些寄放器中的值。能够动用set
$pc来改正调转实施的地址。如:

      set $pc=0x485

    3.发出确定性信号量

      使用signal命令能够生出一个实信号量给被调护医疗的顺序。如中断非确定性信号Ctrl+C。这不行便于与程序的调节和测量检验,能够在程序运维的人身自由地方设置断点,并在该断点用gdb发生叁个时限信号量。准确地在某处产生能量信号特别有益程序的调整。其语法是:

      signal <signal>

        Linux的系统信号量平时从1-15,所以<signal>也在此个范围。

    4.强制函数重回

      如若调节和测验断点在有些函数中,还会有语句未有进行完,能够使用return命令强制函数忽视尚未曾实施的言辞并赶回。

      return

      return expression

      使用return命令撤消当前函数的推行,并即刻回到。借使钦赐了<expression>,那么该表达式的值会被当做函数的重回值。

    5.强制调用函数

      call <expr>    表明式中也能够是函数

      另贰个貌似的授命也足以变成这豆蔻梢头效果与利益–print。print前面能够跟表达式,所以也得以用它来调用函数。print和call不相同之处是,如果函数重返void,call则不出示,print则浮现函数的再次来到值,并把该值存入历史数据中。

    6.在不相同语言中利用gdb

      show language  查看当前语言景况

      info frame  查看当前函数的程序语言

      info source  查看当前文件的程序语言

      set language  假使set
language前边什么也不跟,能够查阅gdb所援救的语言类别。能够在set language
前面加上被列出的言语名,来安装当前的语言情形。

  1.2.9 core dump分析

    在进展程序开辟时,平时由于各样原因引致程序崩溃。那时候能够使用Linux下的core
dump效能。在前后相继崩溃时,Linux会创造四个core文件,在程序结束后,利用这一个文件中的消息,在接受gdb,就会辅导程序崩溃时在做些什么。但core
dump成效而不是装有的程序员都得以行使的,那是因为有的发行版和大器晚成部分系统的协会者在暗中同意时防止选取core
dump。可以选取ulimit -c unlimited

    那样就能够运用core文件剖判了。

    编写翻译生成可推行文件test,然后运维./test生成core文件

    gdb test core

    bt(即backtrace卡塔 尔(阿拉伯语:قطر‎命令用来打字与印刷stack
frame指针,能够精通当前景序运营进度中的函数之间的调用关系。

    使用frame命令:

      frame命令是用来打字与印刷栈桢的,它应用如下格式。

      frame
要打字与印刷的栈桢的编号  若无一些名栈桢时,gdb会打字与印刷当前甄选的栈桢

      能够使用info
frame命令查看当前所接受的栈桢,它将交由栈桢的详细新闻。

 

 1 void func1(int a, int b)
 2 {
 3     int c;
 4     c = a + b;
 5 }
 6 
 7 int main(void)
 8 {
 9 
10     func1(11,22);
11     return 100;
12 }

1.3 其余调节和测验工具

  xxgdb  是X-Windows系统的调解工具,实际上它图形化的gdb,保留了gdb全数的特色。

gdb调试器用法

 

1.4 小结

  在软件开辟中现身错误在所无免,所以程序的调治将养就改为软件开荒中十分关键的四个环节,gdb就是Linux系统下C程序调节和测量检验工具中最常用的少年老成种。本章首先介绍了gdb的程序调试步骤,进而深切地解说了它的功效和局地高级调用方法。最终简短介绍了另风流浪漫种调节和测量试验工具。

GDB是GNU开源公司颁发的二个强盛的UNIX下的程序调节和测量检验工具,GDB首要可补助程序猿实现下边4个地点的作用:
启航程序,能够坚决守护程序员自定义的渴求自由的运维程序。
让被调治将养的顺序在程序猿钦点的断点处停住,断点能够是条件表明式。
当程序被停住时,能够检查那时候程序中所发生的事,并追回上文。
动态地修正程序的实行情形。

  1. gdb 下一步的一声令下

无论是是调节和测量检验Linux内核空间的驱动还是调试客户空间的应用程序,驾驭gdb的用法都以必得。何况,调节和测验内核和调节应用程序时利用的gdb命令是完全相近的,上边以代码清单22.2的应用程序为例演示gdb调节和测量试验器的用法。

a.实践下大器晚成行语句(语句等第)
  next(或n)
实行下意气风发行语句,若是是函数调用则一直将函数试行完;相当于visual
studio调节和测量检验器中的”Step Over (单步追踪)”
  step(或s)
履行下黄金时代行语句,假诺是函数调用则跻身函数中。即常说的单步调节和测量检验,相当于visual
studio调节和测验器中的”Step Into (单步追踪进入)”
  那多少个指令必需在有源代码调节和测量试验新闻的图景下才足以利用(GCC编写翻译时使用“-g”参数卡塔尔国
b.施行下一条指令(指令级)
  si 类似于s;
  ni 类似于n;
  那多少个指令(si/ni)所针没有错是汇编指令

 

  1. disassemble

1  int add(int
a, int b)
2  {
3    return a + b;
4  }
5  
6  main()
7  {
8    int sum[10] =
9    {
10     0,
0, 0, 0,
0, 0, 0,
0, 0, 0    
11   }  ;
12   int i;
13  
14   int array1[10] =
15   {
16     48,
56, 77, 33,
33, 11, 226,
544, 78, 90
17   };
18   int array2[10] =
19   {
20     85,
99, 66, 0x199,
393, 11, 1,
2, 3, 4
21   };
22
23   for (i = 0; i
< 10;
i++)
24   {
25     sum[i] = add(array1[i], array2[i]);
26   }
27 }
利用命令gcc –g gdb_example.c –o
gdb_example编写翻译上述顺序,拿到包蕴调节和测验音讯的二进制文件example,推行gdb
gdb_example命令步向调弄收拾意况:
[root@localhost driver_study]# gdb gdb_example
GNU gdb Red Hat Linux (5.3post-0.20021129.18rh)
Copyright 2003 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-redhat-linux-gnu”…
(gdb)

能够反汇编当前函数恐怕钦点的函数,
单独用disassemble命令是反汇编当前函数,
比如disassemble命令前面跟函数名或地点,则反汇编钦定的函数.

 

(gdb) disassemble
Dump of assembler code for function main:
   0x00008440 <+0>:     push    {r11, lr}
   0x00008444 <+4>:     add     r11, sp, #4
=> 0x00008448 <+8>:     mov     r0, #11
   0x0000844c <+12>:    mov     r1, #22
   0x00008450 <+16>:    bl      0x8410 <func1>
   0x00008454 <+20>:    mov     r3, #100        ; 0x64
   0x00008458 <+24>:    mov     r0, r3
   0x0000845c <+28>:    pop     {r11, pc}
End of assembler dump.

(gdb) disassemble
Dump of assembler code for function func1:
   0x00008410 <+0>:     push    {r11}           ; (str r11, [sp, #-4]!)
   0x00008414 <+4>:     add     r11, sp, #0
   0x00008418 <+8>:     sub     sp, sp, #20
   0x0000841c <+12>:    str     r0, [r11, #-16]
   0x00008420 <+16>:    str     r1, [r11, #-20]
=> 0x00008424 <+20>:    ldr     r2, [r11, #-16]
   0x00008428 <+24>:    ldr     r3, [r11, #-20]
   0x0000842c <+28>:    add     r3, r2, r3
   0x00008430 <+32>:    str     r3, [r11, #-8]
   0x00008434 <+36>:    sub     sp, r11, #0
   0x00008438 <+40>:    pop     {r11}           ; (ldr r11, [sp], #4)
   0x0000843c <+44>:    bx      lr
End of assembler dump.

1、list命令
在gdb中运维list命令(缩写l卡塔 尔(阿拉伯语:قطر‎能够列出代码,list的现实性方式满含:

  1. 展现存放器的音讯

list <linenum> ,展现程序第linenum行周边的源程序,如:(gdb) list 15
10        
11        int array1[10] =
12        {
13        
 48, 56, 77,
33, 33, 11,
226, 544, 78,
90
14        };
15        int array2[10] =
16        {
17        
 85, 99, 66,
0x199, 393, 11,
1, 2, 3,
4
18        };
19

info registers能够来得全部贮存器的近日值(不包涵浮点寄放器)

 

info all-registers(富含浮点寄放器)
简写: i r

list <function> ,突显函数名称为function的函数的源程序,如:
(gdb) list main
2       {
3         return a + b;
4       }
5
6      
main()
7       {
8         int sum[10];
9         int i;
10        
11        int array1[10] =

 1 (gdb) info registers
 2 r0             0xb      11
 3 r1             0x16     22
 4 r2             0xbefffe2c       3204447788
 5 r3             0x8440   33856
 6 r4             0xbeffff14       3204448020
 7 r5             0x8304   33540
 8 r6             0xbefffc80       3204447360
 9 r7             0x8      8
10 r8             0x0      0
11 r9             0x0      0
12 r10            0xb6ffef7c       3070226300
13 r11            0xbefffc64       3204447332
14 r12            0xbefffd68       3204447592
15 sp             0xbefffc50       0xbefffc50
16 lr             0x8454   33876
17 pc             0x8424   0x8424 <func1+20>
18 cpsr           0x60000010       1610612752
19 (gdb) i r
20 r0             0xb      11
21 r1             0x16     22
22 r2             0xbefffe2c       3204447788
23 r3             0x8440   33856
24 r4             0xbeffff14       3204448020
25 r5             0x8304   33540
26 r6             0xbefffc80       3204447360
27 r7             0x8      8
28 r8             0x0      0
29 r9             0x0      0
30 r10            0xb6ffef7c       3070226300
31 r11            0xbefffc64       3204447332
32 r12            0xbefffd68       3204447592
33 sp             0xbefffc50       0xbefffc50
34 lr             0x8454   33876
35 pc             0x8424   0x8424 <func1+20>
36 cpsr           0x60000010       1610612752

list – ,展现当前进前面包车型客车源程序。
下边演示了使用gdb中的run(缩写r卡塔尔国、break(缩写b卡塔尔、next(缩写n卡塔 尔(阿拉伯语:قطر‎命令调整造进程序的运维,并行使print(缩写p卡塔尔命令打字与印刷程序中的变量sum的进度:
(gdb) break add
Breakpoint
1 at 0x80482f7:
file gdb_example.c, line

4.翻看内部存款和储蓄器的值:

  1. (gdb) run  
    Starting
    program: /driver_study/gdb_example

gdb中动用”x”命令来打字与印刷内部存款和储蓄器的值,格式为”x/nfu
addr”。含义为以f格式打字与印刷从addr初步的n个长度单元为u的内部存款和储蓄器值。参数具体意思如下:

Breakpoint
1, add (a=48,
b=85) at gdb_example.c:3
warning: Source file is more recent than
executable.

a)n:输出单元的个数。
b)f:是出口格式。举例x是以16进制方式出口,o是以8进制格局出口,等等。
  x(hex) 按十八进制格式展现变量。
  d(decimal) 按十进制格式展现变量。
  u(unsigned decimal) 按十进制格式显示无符号整型。
  o(octal) 按八进制格式显示变量。
  t(binary) 按二进制格式展现变量。
  a(address) 按十七进制格式展现变量。
  c(char) 按字符格式展现变量。
  f(float) 按浮点数格式展现变量
c)u:标宾博(Karicare卡塔 尔(英语:State of Qatar)个单元的长度。b是叁个byte,h是三个byte(halfword卡塔尔国,w是三个byte(word卡塔 尔(阿拉伯语:قطر‎,g是多少个byte(giant
word卡塔尔国

3         return a + b;
(gdb) next
4       }
(gdb) next
main () at
gdb_example.c:23
23        for (i = 0; i
< 10;
i++)
(gdb) next
25        
 sum[i] = add(array1[i], array2[i]);
(gdb) print sum
$1 = {133, 0,
0, 0, 0,
0, 0, 0,
0, 0}

1 举例:
2 以16进制格式打印从add开始的16个byte的值:
3 (gdb) x/16xb $r11
4 0xbefffc64:     0x6c    0xfc    0xff    0xbe    0x00    0x00    0x00    0x00
5 0xbefffc6c:     0xc4    0xcc    0xfc    0xb6    0x00    0x90    0xfd    0xb6

 

5.打字与印刷栈帧音讯:

2、run命令
在gdb中,运路程序行使run命令。在程序运营前,咱们可以安装如下4方面的办事条件:
程序运转参数
set args 可钦定运行时参数,如:set args 10 20 30 40 50;show args
命令可以查阅设置好的运作参数。

frame 打字与印刷当前栈帧的简易新闻。

运行条件
path <dir> 可设定程序的运作路径;how
paths可查阅程序的周转路径;set environment varname
[=value]用于安装景况变量,如set env USEOdyssey=baohua;show environment
[varname]则用于查看情形变量。

1 (gdb) frame
2 #0  func1 (a=11, b=22) at hello.c:17
3 17      in hello.c

做事目录
cd <dir> 也正是shell的cd命令;pwd 显示当前所在的目录。

6.info frame 打字与印刷当前栈帧的详细消息。

程序的输入输出
info terminal
用于彰显程序用到的终端的方式;gdb中也能够选取重定向调节造进程序输出,如run
> outfile;tty命令能够钦赐输入输出的尖峰设备,如:tty /dev/ttyS1。

1 (gdb) info frame
2 Stack level 0, frame at 0xbefffc68:
3  pc = 0x8434 in func1 (hello.c:17); saved pc 0x8454
4  called by frame at 0xbefffc70
5  source language c.
6  Arglist at 0xbefffc64, args: a=11, b=22
7  Locals at 0xbefffc64, Previous frame's sp is 0xbefffc68
8  Saved registers:
9   r11 at 0xbefffc64

 

7.info frame args 打字与印刷钦点栈帧的详细音信

3、break命令
在gdb中用break命令来设置断点,设置断点的措施包罗:
break <function>
在步向钦命函数时停住,C++中得以选取class::function或function(type,
type)格式来钦命函数名。

1 (gdb) i f 1
2 Stack frame at 0xbefffc70:
3  pc = 0x8454 in main (hello.c:22); saved pc 0xb6fcccc4
4  caller of frame at 0xbefffc68
5  source language c.
6  Arglist at 0xbefffc6c, args:
7  Locals at 0xbefffc6c, Previous frame's sp is 0xbefffc70
8  Saved registers:
9   r11 at 0xbefffc68, lr at 0xbefffc6c

break <linenum>
在内定行号停住。

8.info args 打字与印刷函数参数信息

break +offset / break -offset
在当下行号的前面或前面包车型大巴offset行停住,offiset为自然数。

1 (gdb) info args
2 a = 11
3 b = 22

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

9.info locals 打字与印刷当前可访谈的某个变量的新闻。

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

1 (gdb) info locals
2 c = 0

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

10.如何精通叁个栈帧的尺寸?

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

fp和sp之间的区域正是一个函数的栈帧的分寸。
fp通常是指r11寄放器。
sp日常是指r13寄放器。

break … if <condition>
“…”能够是上述的break <linenum>、break +offset / break
–offset中的参数,condition表示原则,在基准建即刻停住。比方在循环体中,可以安装break
if i=100,表示当i为100时停住程序。 查看断点时,可选用info命令,如info
breakpoints [n]、info break [n](n表示断点号卡塔尔。

 1 (gdb) i r
 2 r0             0xb      11
 3 r1             0x16     22
 4 r2             0xb      11
 5 r3             0x8440   33856
 6 r4             0xbeffff14       3204448020
 7 r5             0x8304   33540
 8 r6             0xbefffc80       3204447360
 9 r7             0x8      8
10 r8             0x0      0
11 r9             0x0      0
12 r10            0xb6ffef7c       3070226300
13 r11            0xbefffc64       3204447332
14 r12            0xbefffd68       3204447592
15 sp             0xbefffc50       0xbefffc50
16 lr             0x8454   33876
17 pc             0x8428   0x8428 <func1+24>
18 cpsr           0x60000010       1610612752
19 
20 (gdb) disassemble
21 Dump of assembler code for function func1:
22    0x00008410 <+0>:     push    {r11}           ; (str r11, [sp, #-4]!)
23 => 0x00008414 <+4>:     add     r11, sp, #0        ;将sp中的内存地址放入r11,即设置fp
24    0x00008418 <+8>:     sub     sp, sp, #20        ;将sp中的内存地址减小20,即设置func1的栈顶指针,如上两条指令执行完后,该函数的栈帧的大小就确定了,20 bytes
25    0x0000841c <+12>:    str     r0, [r11, #-16]    ;函数参数赋值,将r0中的值存入[r11, #-16]内存地址,即函数实参入栈
26    0x00008420 <+16>:    str     r1, [r11, #-20]    ;函数参数赋值,将r1中的值存入[r11, #-16]内存地址
27    0x00008424 <+20>:    ldr     r2, [r11, #-16]
28    0x00008428 <+24>:    ldr     r3, [r11, #-20]
29    0x0000842c <+28>:    add     r3, r2, r3
30    0x00008430 <+32>:    str     r3, [r11, #-8]
31    0x00008434 <+36>:    sub     sp, r11, #0
32    0x00008438 <+40>:    pop     {r11}           ; (ldr r11, [sp], #4)
33    0x0000843c <+44>:    bx      lr
34 End of assembler dump.

 

 

4、单步命令
在调节和测量试验进度中,next命令用于单步试行,雷同VC++中的step
over。next的单步不会进来函数的中间,与next对应的step(缩写s卡塔 尔(英语:State of Qatar)命令则在单步实施八个函数时,会跻身其内部,肖似VC++中的step
into。下边演示了step命令的实增势况,在23行的add()函数调用场实践step会踏入其里面的“return
a+b;”语句:
(gdb) break 25
Breakpoint
1 at 0x8048362:
file gdb_example.c, line

不经常在调整进度中,想记录下来操作的进程及有关音讯,那么 实施set logging
on就可以打卡记录,默许存在gdb.txt。

  1. (gdb) run
    Starting
    program: /driver_study/gdb_example

理所必然也能够和煦钦点log文件,set logging file logname

Breakpoint
1, main ()
at gdb_example.c:25
25        
 sum[i] = add(array1[i], array2[i]);
(gdb) step
add (a=48, b=85) at gdb_example.c:3
3         return a + b;

set logging overwrite on命令可以让输出覆盖从前的日记文件;而
set logging redirect on”命令会让gdb的日志不会打字与印刷在终端

单步试行的更头晕目眩用法包涵:
step <count>
单步追踪,如若有函数调用,则走入该函数(步入函数的前提是,此函数被编写翻译有debug音信卡塔 尔(阿拉伯语:قطر‎。step后边不加count表示一条条地实行,加表示实行前面包车型大巴count条指令,然后再停住。
next <count>
单步追踪,假使有函数调用,它不会进去该函数。同样地,next后边不加count表示一条条地奉行,加表示推行后边的count条指令,然后再停住。

set step-mode
set step-mode
on用于张开step-mode情势,那样,在实行单步跟踪时,程序不会因为还未debug消息而不停住,这些参数的设置可实惠查看机器码。set
step-mod off用于关闭step-mode情势。

finish
运行程序,直到当前函数达成重回,并打字与印刷函数再次回到时的货仓地址和重返值及参数值等新闻。

until (缩写u)
直接在循环体内实践单步,退不出去是大器晚成件令人忧虑的政工,until命令能够运作程序直到退出循环体。

stepi(缩写si)和nexti(缩写ni)
stepi和nexti用于单步追踪一条机器指令,一条程序代码有超级大只怕由数条机器指令实现,stepi和nexti能够单步实施机器指令。
此外,运转“display/i
$pc”命令后,单步追踪会在打出程序代码的同期打出机器指令,即汇编代码。

 

5、continue命令
当程序被停住后,能够应用continue命令(缩写c,fg命令同continue命令卡塔 尔(阿拉伯语:قطر‎苏醒程序的运作直到程序停止,或到达下多少个断点,命令格式为:
continue [ignore-count]
c [ignore-count]
fg [ignore-count]

ignore-count表示忽视其后有一些次断点。
如若咱们设置了函数断点add(),并watch
i,则在continue进程中,每一趟遇到add()函数或i产生变化,程序就能够停住,如:
(gdb) continue
Continuing.
Hardware watchpoint
3: i

Old value = 2
New value = 3
0x0804838d
in main () at gdb_example.c:23
23        for (i = 0; i
< 10;
i++)
(gdb) continue
Continuing.

Breakpoint
1, main ()
at gdb_example.c:25
25        
 sum[i] = add(array1[i], array2[i]);
(gdb) continue
Continuing.
Hardware watchpoint
3: i

Old value = 3
New value = 4
0x0804838d
in main () at gdb_example.c:23
23        for (i = 0; i
< 10;
i++)

 

6、print命令
在调节和测量检验程序时,当程序被停住时,可以选择print命令(缩写为p卡塔尔,或是同义命令inspect来查看当前前后相继的运营数据。print命令的格式是:
 print <expr>

print /<f> <expr>
<expr>是表明式,是被调理的前后相继中的表达式,<f>是出口的格式,比如,尽管要把表明式按16进制的格式输出,那么正是/x。在表明式中,有二种GDB所支撑的操作符,它们得以用在别的后生可畏种语言中,“@”是叁个和数组有关的操作符,“::”内定一个在文书大概函数中的变量,“{<type>}
<addr>”表示一个针对性内部存款和储蓄器地址<addr>的品类为type的贰个对象。
上边演示了翻看sum[]数组的值的经过:
(gdb) print sum
$2 = {133, 155,
0, 0, 0,
0, 0, 0,
0, 0}
(gdb) next

Breakpoint
1, main ()
at gdb_example.c:25
25        
 sum[i] = add(array1[i], array2[i]);
(gdb) next
23        for (i = 0; i
< 10;
i++)
(gdb) print sum
$3 = {133, 155,
143, 0, 0,
0, 0, 0,
0, 0}

当供给查阅生龙活虎段连接内部存款和储蓄器空间的值的年华,能够动用GDB的“@”操作符,“@”的左边手是率先个内部存款和储蓄器地址,“@”的侧边则是想查看内部存款和储蓄器的长短。举例如下动态申请的内部存储器:
int *array = (int *) malloc (len * sizeof (int));
在GDB调节和测量检验进度中如此呈现出那些动态数组的值:
p *array@len
print的输出格式富含:
x 按十二进制格式展现变量。
d 按十进制格式显示变量。
u 按十四进制格式展现无符号整型。
o 按八进制格式显示变量。
t 按二进制格式呈现变量。
a 按十九进制格式显示变量。
c 按字符格式呈现变量。
f 按浮点数格式呈现变量。
小编们可用display命令设置某些电动展现的变量,当程序停住时,或是单步追踪时,这个变量会活动显示。
要是要修改变量,如x的值,可利用如下命令:

print x=4
当用GDB的print查看程序启动时的数目时,每二个print都会被GDB记录下来。GDB会以$1,$2,$3
…那样的主意为每三个print命令编号。大家得以应用那些编号访谈早前的表达式,如$1。

7、watch命令
watch经常来考查有些表明式(变量也是风流浪漫种表明式卡塔 尔(英语:State of Qatar)的值是或不是有变化了,借使有变化,立刻停住程序。大家有下边包车型地铁两种办法来安装观望点:
watch
<expr>:为表明式(变量卡塔 尔(阿拉伯语:قطر‎expr设置四个观望点。生机勃勃量表述式值有浮动时,立刻停住程序。
rwatch <expr>:当表明式(变量卡塔 尔(英语:State of Qatar)expr被读时,停住程序。 awatch
<expr>:当表达式(变量卡塔尔的值被读或被写时,停住程序。 info
watchpoints:列出当前所设置了的有所观看点。
上面演示了观察i并在接二连三运营next时假使发掘i变化,i值就能来得出来的进度:
(gdb) watch i
Hardware watchpoint
3: i
(gdb) next
23        for (i = 0; i
< 10;
i++)
(gdb) next
Hardware watchpoint
3: i

Old value = 0
New value = 1
0x0804838d
in main () at gdb_example.c:23
23        for (i = 0; i
< 10;
i++)
(gdb) next

Breakpoint
1, main ()
at gdb_example.c:25
25        
 sum[i] = add(array1[i], array2[i]);
(gdb) next
23        for (i = 0; i
< 10;
i++)
(gdb) next
Hardware watchpoint
3: i

Old value = 1
New value = 2
0x0804838d
in main () at gdb_example.c:23
23        for (i = 0; i
< 10;
i++)

 

8、examine命令
大家能够使用examine命令(缩写为x卡塔 尔(阿拉伯语:قطر‎来查看内存地址中的值。examine命令的语法如下所示:
x/<n/f/u> <addr>
<addr>表示一个内部存款和储蓄器地址。“x/”后的n、f、u都是可选的参数,n
是叁个正整数,表示呈现内部存款和储蓄器的长度,也正是说从日前地方向后显得多少个地方的开始和结果;f
表示突显的格式,借使位置所指的是字符串,那么格式能够是s,假设地点是命令地址,那么格式能够是i;u
表示从此现在时此刻地点将来呼吁的字节数,若是不点名的话,GDB暗中认可是4字节。u参数能够被某些字符代替:b表示单字节,h表示双字节,w表示四字节,g表示八字节。当我们钦命了字节长度后,GDB会从钦命的内部存款和储蓄器地址开头,读写钦命字节,并把其看作一个值抽出来。n、f、u那3个参数能够联手行使,比方命令“x/3uh
0x54320”表示从内部存款和储蓄器地址0x54320最初以双字节为1个单位(h卡塔尔、16进制格局(u卡塔尔展现3个单位(3卡塔尔的内存。

9、jump命令
日常的话,被调护医疗程序会遵照程序代码的周转顺序依次推行,然则GDB也提供了乱序施行的效劳,也正是说,GDB能够修正程序的实施各类,进而让程序随便跳跃。那一个意义能够由GDB的jump命令:
jump <linespec>
来钦定下一条语句的运转点。<linespec>能够是文件的行号,能够是file:line格式,也足以是+num这种偏移量格式,表示下一条运维语句从什么地方开头。
jump <address> 这里的<address>是代码行的内部存款和储蓄器地址。
注意,jump命令不会改动这段日子的顺序栈中的内容,所以,假使运用jump从一个函数跳转到另多个函数,当跳转到的函数运维完回到,进行出栈操作时必然会生出错误,那大概以致敬外的结果,所以最佳只用jump在同三个函数中张开跳转。

10、signal命令
应用singal命令,能够生出一个非非确定性信号量给被调弄整理的程序,如中断功率信号“Ctrl+C”。那拾贰分方便于程序的调和,能够在程序运营的自由地方设置断点,并在该断点用GDB发生叁个连续信号量,这种准确地在某处爆发信号的章程十一分有助于程序的疗养。
signal命令的语法是:signal
<signal>,UNIX的连串频域信号量平常从1到15,所以<signal>取值也在这里个界定。

 
11、return命令
假若在函数中安装了调整断点,在断点后还恐怕有语句没有进行完,这个时候我们得以应用return命令强制函数忽视还没曾实行的话语并重回。
returnreturn <expression>
上述return命令用于撤销当前函数的推行,并立刻重临,如若内定了<expression>,那么该表达式的值会被当做函数的重临值。

 
12、call命令
call命令用于强制调用某函数: call <expr>
表达式中能够一是函数,以此达到强制调用函数的目标,它会显得函数的再次来到值(假诺函数重返值不是void卡塔尔。
其实,前边介绍的print命令也足以做到强制调用函数的职能。

13、info命令
info命令能够在调节和测验时用来查阅贮存器、断点、观看点和功率信号等音讯。要翻开存放器的值,能够选择如下命令:
info registers (查看除了浮点存放器以外的存放器卡塔 尔(阿拉伯语:قطر‎ info all-registers
(查看全数存放器,富含浮点寄放器卡塔尔 info registers <regname …>
(查看所钦定的贮存器卡塔 尔(阿拉伯语:قطر‎ 要翻开断点消息,能够选择如下命令: info break
列出方今所设置的享有观望点,使用如下命令: info watchpoints
查看有哪些信号正在被GDB检验,使用如下命令: info signals info handle
也可以动用info line命令来查看源代码在内部存储器中的地址。info
line前边能够跟行号、函数名、文件名:行号、文件名:函数名等二种格局,举个例子下边的命令会打字与印刷出所指定的源码在运维时的内存地址:
info line tst.c:func

14、disassemble
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)

End of assembler
dump.

 

完!

 

相关文章