你会发现GDB这个调试工具的强大普京网址,程序运行参数

找寻源代码

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

forward-search <regexp>
search <regexp>

向前边搜索。

reverse-search <regexp>

不论什么事查找。

中间,正是正则表达式,也主两个字符串的相称格局,关王丽萍则表达式,笔者就不在那讲了,还请各位查占卜关资料。

    15.2
跳转实践

强迫函数重临

只要您的调治断点在有些函数中,并还会有语句未有推行完。你可以应用return命令压迫函数忽视还不曾推行的言语并赶回。

return
return <expression>

动用return命令裁撤当前函数的实行,并当即回到,固然钦点了<expression>,那么该说明式的值会被认作函数的重临值。

22
钦赐源文件的门道

护卫结束点

前方说了怎么设置程序的告一段落点,gdb中的结束点也是上述的三类。

在gdb中,假诺你感觉已定义好的甘休点并未有用了,能够采用delete、clear、disable、enable命令来进展保障。

(1)clear

免去全数的已定义的告一段落点。

用法:

clear <function>
clear <filename:function>

裁撤全数安装在函数function上的安息点。

clear <linenum>
clear <filename:linenum>

免除全体安装在钦定行上的截止点。

(2)delete

去除内定的停下点。

用法:

delete [breakpoints] [range...]

删除钦命的断点,breakpoint为断点号。要是不钦点断点号,则象征删除全体的断点。range表示断点号的范围。其简写命令为d。

(3)disable/enable

比删除越来越好的一种艺术是disable甘休点,disable了的停下点,gdb不会去除,当您还须求时,enable就能够,就恍如回笼站同样(删除与回复的过程)。

用法:

disable [breakpoints] [range...]

disable所钦点的甘休点,breakpoint为休憩点号。假如什么都不点名,表示disable全部的终止点。简写命令为dis。

enable [breakpoints] [range...]

enable所内定的结束点,breakpoint为截止点号。

enable [breakpoints] once [range...]

enable所内定的停下点二遍,当程序停住后,该截至点及时被gdb自动disable。

enable [breakpoints] delete [range...]

enable所钦点的安歇点三遍,当程序停住后,该截至点立马被gdb删除。

    15.4
强逼函数重临

翻看运转时数据

当你调节和测量试验程序时,当程序被停住时,你能够采取print命令(简写命令为p),大概联合命令inspect来查看当前前后相继的运维数据。

print命令的格式是:

print <expr>
print /<f> <expr>

<expr>是表明式,是您所调程序的语言的表明式(GDB能够调度多种编制程序语言),是出口的格式,比方,假若要把表明式按16进制的格式输出,那么正是/x。

18 线程

要是您程序是十二线程的话,你能够定义你的断点是还是不是在具有的线程上,或是在某个特定的线程。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停住时,全体的周转线程都会被停住。那便于你你查看运路程序的一体化处境。而在你复苏程序运转时,全数的线程也会被还原运转。那怕是主进度在被单步调节和测量检验时。

安装彰显选项

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

开采数组展现,张开后当数组展现时,各个元素占一行,假设不展开的话,每种成分则以逗号分隔。这一个选项私下认可是停业的。与之相关的八个指令如下,笔者就不再多说了。

set print array off
show print array
set print 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凸显构造体时会相比不错。如:

$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 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

翻开虚函数字呈现示格式的选项。

4 程序运营上下文

查看源程序

10
调节和测量试验代码

次第变量

在GDB中,你能够任何时候查阅以下三种变量的值:

  1. 全局变量(全部文件可以预知的)
  2. 静态全局变量(当前文件可知的)
  3. 有个别变量(当前Scope可知的)

设若你的有个别变量和全局变量发生冲突(也正是重名),日常景况下是有的变量会掩盖全局变量,约等于说,假若三个全局变量和多少个函数中的局部变量同名时,假使当前结束点在函数中,用print突显出的变量的值会是函数中的局地变量的值。

万一这时您想查看全局变量的值时,你能够采纳“::”操作符:

file::variable
function::variable

能够透过这种样式内定你所想查看的变量,无论是哪个文件中的或是哪个函数中的。

比方,查看文件test2.c中的全局变量x的值:

gdb) p 'test2.c'::x

本来,“::”操作符会和C++中的类产生冲突,GDB能自动识别“::”
是还是不是C++的操作符,所以你不用怀恋在调度C++程序时会现身相当。

除此以外,须要注意的是,假设您的顺序编写翻译时张开了优化增选,那么在用GDB调节和测量试验被优化过的前后相继时,恐怕会发生一些变量无法访谈,或是取值错误码的状态。那几个是很经常的,因为优化程序会删改你的次第,收拾你程序的言辞顺序,剔除一些虚无的变量等,所以在GDB调试这种程序时,运转时的通令和你所编纂指令就有不相近,也就能产出你所想像不到的结果。对付这种处境时,需求在编写翻译程序时关闭编写翻译优化。

貌似的话,差不离全体的编写翻译器都援助理编辑译优化的开关,举例,GNU的C/C++编写翻译器GCC,你可以选用“-gstabs”选项来解决那一个题目。关于编写翻译器的参数,还请查看编写翻译器的运用表达文书档案。

15.2 跳转施行

相近的话,被调弄整理程序会遵照程序代码的运转顺序依次实行。GDB提供了乱序实施的魔法,也正是说,GDB能够校订程序的推行种种,能够让程序实施随便跳跃。这些效应可以由GDB的jump命令来完:

jump linespec

点名下一条语句的运转点。能够是文本的行号,能够是file:line格式,能够是+num这种偏移量格式。表示下一条运维语句从哪儿最早。

jump *address

此处的是代码行的内部存款和储蓄器地址。

潜心,jump命令不会变动近期的次第栈中的内容,所以,当你从三个函数跳到另三个函数时,当函数运行完回届时举办弹栈操作时肯定会生出错误,恐怕结果依旧不行想获得的,以至于发生程序Core
Dump。所以最棒是同二个函数中进行跳转。

熟知汇编的人都清楚,程序运维时,eip寄放器用于保存当前代码所在的内存地址。所以,jump命令约等于退换了那么些存放器中的值。于是,你能够行使“set
$pc”来改造跳转推行的地址。如:

set $pc = 0×485

使用GDB

平常的话,GDB首要调试的是C/C++程序。要调治C/C++的前后相继,首先在编写翻译时,大家一定要把调节和测量检验音信加到可推行文件中。使用编写翻译器(cc/gcc/g++)的
-g 参数能够变成那一点。如:

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

要是没有-g,你将看不见程序的函数名、变量名,所代替的全部是运作时的内部存款和储蓄器地址。当您用-g把调节和测量检验音讯插手之后,并成功编写翻译目的代码今后,让我们来看看哪些用gdb来调治它。

开行GDB的办法有以下三种:

  1. gdb <program>
    program也正是您的施行文书,平常在当前目录下。
  2. gdb <program> core
    用gdb同时调节和测量试验一个运路程序和core文件,core是程序违法实行后core
    dump后发出的公文。
  3. gdb <program> <PID>
    假如你的次第是一个服务程序,那么您能够钦赐那几个服务程序运转时的长河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所定义的路子。

6 观察点

watch
为表明式(变量)expr设置三个观看点。当表明式值有转换时,立时停住程序。

rwatch 表明式(变量)expr被读时,停住程序。

awatch 表明式(变量)的值被读或被写时,停住程序。

info watchpoints 列出当下所设置了的享有观看点。

钦点源文件的门径

或多或少时候,用-g编写翻译过后的实行顺序中只是归纳了源文件的名字,未有路线名。GDB提供了能够令你钦定源文件的路径的一声令下,以便GDB进行搜寻。

directory <dirname ... >
dir <dirname ... >

加二个源文件路径到当前路径的前边。假如您要内定四个门路,UNIX下您能够使用“:”,Windows下你可以应用“;”。

directory

消灭全体的自定义的源文件寻觅路线消息。

show directories

体现定义了的源文件寻觅路线。

1
简介

活动突显

您能够设置有个别电动展现的变量,当程序停住时,或是在您单步追踪时,这一个变量会活动呈现。

相关的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。

5.1 轻巧断点

break 设置断点,可以简写为b

b 10 设置断点,在源程序第10行

b func 设置断点,在func函数入口处

在GDB中运作程序

当以gdb
格局运行gdb后,gdb会在PATH路线和当前目录中搜寻的源文件。如要确认gdb是还是不是读到源文件,可使用l或list命令,看看gdb是还是不是能列出源代码。

在gdb中,运营程序使用r或是run命令。

程序的运营,你有希望须求设置下边四地方的事。

  • 程序运营参数

set args 可钦点运维时参数(如:set args 10 20 30 40 50)。

show args 命令能够查看设置好的运作参数。

  • 运转情况

path <dir> 可设定程序的运作路径(如:path ./demo/app)。

show paths 查看程序的运营路径。

set environment varname [=value] 设置情形变量。如:set env USE本田CR-V=hchen

show environment [varname] 查看意况变量。

  • 工作目录

cd <dir> 相当于shell的cd命令(如:cd ./demo 等价于 shell cd ./demo)。

pwd 彰显当前的四方目录。

  • 程序的输入输出

info terminal 展现你程序用到的终端的方式。

使用重定向调节程序输出。如:run > outfile

tty命令可以指写输入输出的终极设备。如:tty /dev/ttyb

7 尺度断点

诚如的话,为断点设置三个尺度,大家使用if关键词,前边跟其断点条件。而且,条件设置好后,我们得以用condition命令来改革断点的条件。
何况,条件设置好后,大家得以用condition命令来矫正断点的尺度。(唯有break
和 watch命令帮助if,catch前段时间暂不扶持if)。

安装三个规范化断点

b test.c:8 if intValue == 5

condition 与break if相通,只是condition只好用在已存在的断点上

改进断点号为bnum的截至条件为expression

condition bnum expression

明白断点号为bnum的停下条件

condition bnum

ignore 忽视截止条件五次

表示忽视断点号为bnum的小憩条件count次

Ignore bnum count

在GDB中运行UNIX的Shell程序

在gdb境遇中,你能够奉行UNIX的shell的命令,使用gdb的shell命令来形成:

(gdb) shell <command string>

调用UNIX的shell来实行,意况变量SHELL中定义的UNIX的shell将会被用来实践,假如SHELL未有概念,那就利用UNIX的正规shell:/bin/sh。(在Windows中运用Command.com或cmd.exe)

再有叁个gdb命令是make:

(gdb) make <make-args>

可以在gdb中实施make命令来重新build本人的顺序。这么些命令等价于“shell make
”。

19 查看栈新闻

当程序被停住了,你必要做的首先件事正是查看程序是在哪儿停住的。当您的次第调用了二个函数,函数的地点,函数参数,函数内的一些变量都会被压入“栈”(Stack)中。你能够用GDB命令来查阅当前的栈中的新闻。

上边是有的查看函数调用栈音信的GDB命令:

breacktrace,简称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

n是贰个从0开首的子弹头,是栈中的层编号。例如:frame 0,表示栈顶,frame
1,表示栈的第二层。

frame addr

f addr Select the frame at address addr. This is useful mainly if the
chaining of stack frames has been damaged by a bug, making it impossible
for gdb to assign

numbers properly to all frames. In addition, this can be useful when
your program has multiple stacks and switches between them.

up n

意味着向栈的地点移动n层,能够不打n,表示发展移动一层。

down n

表示向栈的上边移动n层,能够不打n,表示向下移动一层。

上边的授命,都会打字与印刷出活动到的栈层的消息。就算您不想让其打出信息。你能够使用那多个指令:

select-frame 对应于 frame 命令。

up-silently n 对应于 up 命令。

down-silently n 对应于 down 命令。

翻看当前栈层的新闻,你能够用以下GDB命令:

frame 或 f

会打字与印刷出这么些音讯:栈的层编号,当前的函数名,函数参数值,函数所在文书及行号,函数实践到的说话。

info frame

info f

叁个调治示例

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int func(int n) {
    int sum = 0;
    int i = 0;

    for(i = 0; i < n; i++)
        sum += i;

    return sum;
}

int main() {
    int i;
    long result = 0;

    for(i = 0; i <= 100; i++)
        result += i;

    printf("result[1-100] = %ld\n", result);

    printf("result[1-250] = %ld\n", func(250));

    return 0;
}

编写翻译生成施行文书(Linux下):

root@iZ2813hasr2Z:~/test/csdnBBS/gdb# gcc test1.c -g -o test1

使用GDB调试:

root@iZ2813hasr2Z:~/test/csdnBBS/gdb# gdb test1
GNU gdb (Ubuntu 7.7.1-0ubuntu5~14.04.2) 7.7.1
Copyright (C) 2014 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from test1...done.
(gdb) l
15   
16        for(i = 0; i < n; i++)
17            sum += i;
18   
19        return sum;
20    }
21   
22    int main() {
23        int i;
24        long result = 0;
(gdb)
25   
26        for(i = 0; i <= 100; i++)
27            result += i;
28   
29        printf("result[1-100] = %ld\n", result);
30   
31        printf("result[1-250] = %ld\n", func(250));
32   
33        return 0;
34    }
(gdb) break 23
Breakpoint 1 at 0x40057a: file test1.c, line 23.
(gdb) break func
Breakpoint 2 at 0x400544: file test1.c, line 13.
(gdb) info break
Num     Type           Disp Enb Address            What
1       breakpoint     keep y   0x000000000040057a in main at test1.c:23
2       breakpoint     keep y   0x0000000000400544 in func at test1.c:13
(gdb) r
Starting program: /root/test/csdnBBS/gdb/test1

Breakpoint 1, main () at test1.c:24
24        long result = 0;
(gdb) n
26        for(i = 0; i <= 100; i++)
(gdb)
27            result += i;
(gdb)
26        for(i = 0; i <= 100; i++)
(gdb)
27            result += i;
(gdb) c
Continuing.
result[1-100] = 5050

Breakpoint 2, func (n=250) at test1.c:13
13        int sum = 0;
(gdb) n
14        int i = 0;
(gdb)
16        for(i = 0; i < n; i++)
(gdb)
17            sum += i;
(gdb)
16        for(i = 0; i < n; i++)
(gdb)
17            sum += i;
(gdb)
16        for(i = 0; i < n; i++)
(gdb) p sum
$1 = 1
(gdb)
$2 = 1
(gdb) p i
$3 = 1
(gdb) n
17            sum += i;
(gdb)
16        for(i = 0; i < n; i++)
(gdb)
17            sum += i;
(gdb)
16        for(i = 0; i < n; i++)
(gdb)
17            sum += i;
(gdb) p sum
$4 = 6
(gdb) p i
$5 = 4
(gdb) bt
#0  func (n=250) at test1.c:17
#1  0x00000000004005be in main () at test1.c:31
(gdb) finish
Run till exit from #0  func (n=250) at test1.c:17
0x00000000004005be in main () at test1.c:31
31        printf("result[1-250] = %ld\n", func(250));
Value returned is $6 = 31125
(gdb) c
Continuing.
result[1-250] = 31125
[Inferior 1 (process 8494) exited normally]
(gdb) q

    4.2
职业目录

停住/恢复程序运转

调节和测量试验程序中,停住程序运营是必需的,GDB能够渔人之利地停住程序的周转。你可以设置程序在哪行停住,在如何标准下停住,在抽出什么信号时停住等等,以便于查看运营时的变量,以致运行时的流水生产线。

当进度被gdb停住时,你可以动用info program来查看程序是或不是在运营、进度号、被停住的开始和结果等等。

在gdb中,有以下三种停住方式:

断点(breakpoint)
观察点(watchpoint)
捕捉点(catchpoint)
信号(signal)
线程停止(thread stops)

若是恢复生机程序运营,能够使用c或continue命令。

5.3 查询全部断点

info b

GDB命令概述

起首gdb后,你就被带入gdb的调理意况中,就能够使用gdb的吩咐最早调节和测量试验程序了,gdb的一声令下能够应用help命令来查看,如下所示:

zjl@zjl-virtual-machine:~/projects/GdbStudy$ gdb
GNU gdb (Ubuntu/Linaro 7.4-2012.04-0ubuntu2.1) 7.4-2012.04
Copyright (C) 2012 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
For bug reporting instructions, please see:
<http://bugs.launchpad.net/gdb-linaro/>.
(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 all" for the list of all commands.
Type "help" followed by command name for full documentation.
Type "apropos word" to search for commands related to "word".
Command name abbreviations are allowed if unambiguous.

gdb的授命非常多,gdb把之分成超级多少个等级次序。help命令只是例出gdb的一声令下体系,如若要看项目中的命令,能够应用help
命令,如:help breakpoints,查看设置断点的全体命令。也足以一直help
来查看命令的增加援救。

gdb中,输入指令时,能够毫不打全命令,只用打命令的前多少个字符就足以了。当然,命令的前多少个字符应该要注明着三个独一地下令,在Linux下,你可以打击两回TAB键来补齐命令的完善,借使有再次的,那么gdb会把其列出来。

示例一:在进入函数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)

示例三:只记得函数的前缀,可以这样:
(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开头的函数全部例出来给你查看

示例四:调试C++的程序时,有可能函数名一样(重载函数),如:
(gdb) b 'bubble( M-?
bubble(double,double)  bubble(int,int)
(gdb) b 'bubble(
你可以查看到C++中的所有的重载函数及参数(注:M-?和“按两次TAB键”是一个意思)

要退出gdb,只需采纳quit或指令简单称谓q就能够了。

4.1 程序运维参数

set args 可钦点运营时参数。(如:set args 10 20 30 40 50 )

show args 命令能够查看设置好的周转参数。

run (r卡塔尔国 运维程序

不钦点运转参数 r

钦命运营参数r 10 20 30 40 50

GDB情况变量

您能够在GDB的调护医疗意况中定义自身的变量,用来保存一些调节和测验程序中的运行数据。要定义叁个GDB的变量非常轻巧只需。使用GDB的set命令。

GDB的情形变量和UNIX同样,也是以$领头。如:

set $foo = *object_ptr

利用遭受变量时,GDB会在你首先次接受时创设那个变量,而在之后的施用中,则直接对其賦值。情形变量未有项目,你能够给意况变量定义任一的品类。富含布局体和数组。

show convenience

该命令查看当前所设置的装有的景况变量。

这是二个相比较强硬的成效,意况变量和程序变量的竞相使用,将使得程序调节和测验更为灵活方便。举个例子:

set $i = 0
print bar[$i++]->contents

于是乎,当你就不要,print bar[0]->contents, print
bar[1]->contents地输入指令了。输入那样的一声令下后,只用敲回车,重复实施上一条语句,情形变量会自动抬高,从而完结每一个出口的功效。

11
查看运维时数据

设置阅览点(watchpoint)

观望点经常用来调查某些表明式(变量也是一种表明式)的值是不是爆发变化。如果有转移,就随时终止程序。

大家得以行使下面两种艺术设置观望点:

(1)watch <expr>

为表明式(变量)expr设置三个观察点。一旦表明式值有变化时,就马上停住程序。

(2)rwatch <expr>

当表明式(变量)被读时,停住程序。

(3)awatch <expr>

当表明式(变量)的值被读或被写时,停住程序。

(4)info watchpoints

列出了当下所设置的具有寓目点。

演示test1.c的调节和测验进度:

zjl@zjl-virtual-machine:~/projects/GdbStudy$ gdb test1
GNU gdb (Ubuntu/Linaro 7.4-2012.04-0ubuntu2.1) 7.4-2012.04
Copyright (C) 2012 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
For bug reporting instructions, please see:
<http://bugs.launchpad.net/gdb-linaro/>...
Reading symbols from /home/zjl/projects/GdbStudy/test1...done.
(gdb) l
10            sum += i;
11        }
12   
13        return sum;
14    }
15   
16    int main()
17    {
18        int i;
19        long result = 0;
(gdb) break 20
Breakpoint 1 at 0x400532: file test1.c, line 20.
(gdb) r
Starting program: /home/zjl/projects/GdbStudy/test1
warning: no loadable sections found in added symbol-file system-supplied DSO at 0x7ffff7ffa000
Breakpoint 1, main () at test1.c:21
21        for (i=1; i<=100; i++)
(gdb) watch i
Hardware watchpoint 2: i
(gdb) c
Continuing.
Hardware watchpoint 2: i
Old value = 0
New value = 2
0x0000000000400548 in main () at test1.c:21
21        for (i=1; i<=100; i++)
(gdb) c
Continuing.
Hardware watchpoint 2: i
Old value = 2
New value = 3
0x0000000000400548 in main () at test1.c:21
21        for (i=1; i<=100; i++)

看得出,使用watch的步骤如下:

  • 利用break在察看的变量所在处设置断点;
  • 行使run实施顺序,直到断点处;
  • 选择watch设置观望点;
  • 应用continue观望设置的观望点是还是不是爆发变化。

疑问: 直接设置观望点为啥不行?

==>> 测验对于指针设置观望点,观察值为指针的值,依然指针所在半空。

例如:

root@iZ2813hasr2Z:~/share/gdbTest# gdb a.out
GNU gdb (Ubuntu 7.7.1-0ubuntu5~14.04.2) 7.7.1
Copyright (C) 2014 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from a.out...done.
(gdb) l 33
28       
29        int i;
30        long result = 0;
31       
32        for (i=1; i<=100; i++) {
33            result += i;
34        }
35   
36        printf ("result [1-100] = %ld \n", result);
37        printf ("result [1-250] = %d \n", func(250));
(gdb) b 33
Breakpoint 1 at 0x400764: file general.cpp, line 33.
(gdb) watch result
No symbol "result" in current context.
(gdb) watch i
No symbol "i" in current context.
(gdb) r
Starting program: /root/share/gdbTest/a.out

Breakpoint 1, main () at general.cpp:33
33            result += i;
(gdb) watch result
Hardware watchpoint 2: result

No symbol “result” in current context.

也正是说,即使程序尚未run,系统就不会对其开展内部存款和储蓄器分配,因而,result在系统中也未有对应的内部存款和储蓄器地址,那样,直接开展watch操作会引致认为系统中从不result这些标志。

11 查看运维时数据

print 打字与印刷变量、字符串、表明式等的值,可简写为p
p count 打印count的值
p cou1+cou2+cou3 打字与印刷表明式值

print接纳三个表明式,GDB会依照当前的程序运转的数目来计量那么些表明式,表明式能够是当前程序运营中的const常量、变量、函数等内容。不过GDB不可能选取程序中定义的宏。

产生功率信号量

选择singal命令,能够发生三个功率信号量给被调护医治的程序。如:中断连续信号Ctrl+C。那不行方便于程序的调和,可以在程序运行的放肆地方设置断点,并在该断点用GDB发生一个复信号量,这种准确地在某处产生时域信号特别常有益程序的调护医治。

语法是:signal <singal>,UNIX的系统时限信号量平日从1到15。所以<singal>取值也在此个范围。

signal命令和shell的kill命令分化,系统的kill命令发时域信号给被调节和测量检验程序时,是由GDB截获的,而signal命令所发生一复信号则是直接发放被调节和测量检验程序的。

9
为停歇点设定运转命令

查看栈消息

当程序被停住了,你需求做的首先件事便是翻开程序是在哪儿停住的。

当你的程序调用了五个函数,函数的地点、函数的参数、函数内的一些变量都会被压入“栈”(stack)中。你能够应用gdb命令来查看当前的栈中的音信。

下边是局部翻看函数调用栈的gdb命令:

(1)backtrace/bt

打字与印刷当前的函数调用栈的具有音信。如:

(gdb) backtrace
#0  Student::setStudentInfo (this=0x602010, score=98.5) at test2.cpp:30
#1  0x00000000004007e3 in main () at test2.cpp:48

从上得以看看函数的调用栈音讯:main(卡塔尔—>>>Student::setStudentInfo(double卡塔尔国

backtrace <n>
bt <n>

n是一个正整数,表示只打字与印刷栈顶上n层的栈新闻。

backtrace <-n>
bt <-n>

-n表示一个负整数,表示只打字与印刷栈底下n层的栈消息。

(gdb) bt 1
#0  Student::setStudentInfo (this=0x602010, score=98.5) at test2.cpp:30
(More stack frames follow...)
(gdb) bt -1
#1  0x00000000004007e3 in main () at test2.cpp:48

设若您要翻看某一层的音讯,你须求切换当前的栈,日常的话,程序结束时,最顶层的栈就是现阶段栈,若是你要翻开栈上边层的详细音信,首先要做的就是切换当前栈。

(2)frame/f/up/down

frame <n>
f <n>

n是多个从0开始的卡尺头,是栈中的层编号。举个例子,frame 0表示栈顶;frame
1表示栈的第二层。

up <n>

表示向栈的上面移动n层,能够不加n,表示发展移动1层

down <n>

代表向栈的上面移动n层,能够不加n,表示向下移动1层

==>> 上边的指令,都会打字与印刷出活动到的栈层的消息。

倘诺不打字与印刷消息,可以采用上边八个指令:

select-frame <n>对应于 frame 命令;
up-silently <n> 对应于 up 命令;
down-silently <n> 对应于 down 命令。

翻开当前栈层的音讯,你能够利用上面的gdb命令:

frame / f

该命令会打字与印刷出这个栈新闻:栈的层编号,当前的函数名,函数的参数值,函数所在文件及行号,函数施行到的言辞。

info frame
info f

该命令会打字与印刷出更为详细的最近栈层的新闻,只可是,大许多都以运作时的内部存款和储蓄器地址。比方:函数地址,调用函数的地点,被调用函数的地点,近来的函数是由哪些的程序语言写成的、函数参数地址及值、局地变量的地址等等。如:

(gdb) f
 #1  0x00000000004007e3 in main () at test2.cpp:48
 48        st->setStudentInfo(s);
(gdb) info f
Stack level 1, frame at 0x7fffffffe5a0:
rip = 0x4007e3 in main (test2.cpp:48); saved rip 0x7ffff773d76d
caller of frame at 0x7fffffffe560
source language c++.
Arglist at 0x7fffffffe590, args:
Locals at 0x7fffffffe590, Previous frame's sp is 0x7fffffffe5a0
Saved registers:
  rbx at 0x7fffffffe588, rbp at 0x7fffffffe590, rip at 0x7fffffffe598
(gdb) down
 #0  Student::setStudentInfo (this=0x602010, score=98.5) at test2.cpp:30
 30        this->score = score;
(gdb) info f
Stack level 0, frame at 0x7fffffffe560:
rip = 0x400725 in Student::setStudentInfo (test2.cpp:30); saved rip 0x4007e3
called by frame at 0x7fffffffe5a0
source language c++.
Arglist at 0x7fffffffe550, args: this=0x602010, score=98.5
Locals at 0x7fffffffe550, Previous frame's sp is 0x7fffffffe560
Saved registers:
  rbp at 0x7fffffffe550, rip at 0x7fffffffe558

打字与印刷消息命令:

info args

打字与印刷出前段时间函数的参数名及其值。

info locals

打字与印刷出近期函数中存有片段变量及其值。

info catch
打字与印刷出如今函数中的极度管理音信。

1 简介

GDB(GNU Debugger)是GCC的调理工具。其成效强大,现描述如下:
GDB重要支持你做到上边三个方面包车型大巴职能:
1.开首你的次第,能够根据你的自定义的需要自由的运维程序。
2.可让被调和的次序在你所钦命的调置的断点处停住。(断点能够是规范表明式)
3.当程序被停住时,能够检查这时候您的主次中所产生的事。
4.动态的改造你程序的实践境遇。

信号(signal)

能量信号是一种软中断,是一种管理异步事件的艺术。经常的话,操作系统都辅助广大实信号。越发是UNIX,相比较关键应用程序经常都会管理非确定性信号。UNIX定义了过多复信号,譬喻SIGINT表示暂停字符模拟信号,也正是Ctrl+C的功率信号;SIGBUS表示硬件故障的随机信号;SIGCHLD表示子进度景况改过非确定性信号;SIGKILL表示终止程序运营的随机信号,等等。实信号量编制程序是UNIX下充足首要的一种技巧。

gdb有力量在您调节和测验程序的时候管理任何一种随机信号,你能够告诉gdb要求管理哪种非复信号。你可以须要gdb收到你所钦定的频域信号时,立即停住正在运维的顺序,以供您实行调弄收拾。你能够用gdb的handle命令来成功这一功力。

`handle <signal> <keywords...>`

在gdb中定义二个信号管理。时域信号能够以SIG开首或不以SIG伊始,可以用定义叁个要处理时限信号的限量(如:SIGIO-SIGKILL,表示管理从SIGIO功率信号到SIGKILL的时限信号,此中富含SIGIO,SIGIOT,SIGKILL四个功率信号),也能够应用首要字all来证明要拍卖全体的能量信号。一旦被调理的主次选取到数字信号,运路程序及时会被gdb停住,以供调节和测量试验。其<keywords>能够是以下两种主要字的三个或五个。

nostop
当被调治将养的顺序收到时限信号时,GDB不会停住程序的运维,但会打出新闻告诉你接到这种模拟信号

stop
当被调护医治的程序收届期限信号时,GDB会停住你的程序

print
当被调治将养的主次收到信号时,GDB会呈现出一条音讯

noprint
当被调和的顺序收到数字信号时,GDB不会告诉您接到非确定性信号的音讯

pass
noignore
当被调理的次第收到能量信号时,GDB不管理数字信号,那象征,GDB会把那些信号交给被调节和测量检验程序会管理

nopass
ignore
当被调弄收拾的次序收到非数字信号时,GDB不会让被调节和测验程序来处理那一个频域信号

nostop
当被调理的先后收到随机信号时,GDB不会停住程序的周转,但会打出音讯告诉你收到这种随机信号

stop
当被调和的顺序收到信号时,GDB会停住你的前后相继

print
当被调护医治的次第收到非数字信号时,GDB会呈现出一条消息

noprint
当被调护治疗的前后相继收到实信号时,GDB不会报告您接到实信号的新闻

pass
noignore
当被调护治疗的程序收到连续信号时,GDB不管理实信号,那象征,GDB会把这些随机信号交给被调节和测验程序会处理

nopass
ignore
当被调弄整理的次第收到复信号时,GDB不会让被调节和测验程序来拍卖那一个连续信号

消息展现命令:

info signals
info handle

查看有啥时限信号正在被gdb检验中。

2 生成调节和测量试验消息

诚如的话GDB重要调节和测量试验的是C/C++的次第。要调解C/C++的程序,首先在编写翻译时,大家必需要把调试信息加到可执行文件中。使用编写翻译器(cc/gcc/g++)的
-g 参数可以形成那一点。如:

gcc -g hello.c -o hello

g++ -g hello.cpp -o hello

假如未有-g,你将看不见程序的函数名、变量名,所庖代的全都是运作时的内部存款和储蓄器地址。当您用-g把调节和测量检验信息参与之后,并成功编写翻译指标代码今后,让大家来看看哪些用gdb来调度他。

改造程序的实行

设若选拔GDB挂上被调试程序,当程序运营起来后,你能够依照本人的调解思路来动态地在GDB中改换当前被调节和测验程序的运作路径或是其变量的值,那些强盛的功力能够让您更加好的调度你的程序,比方,你能够在前后相继的一遍运转中走遍程序的有着支行。

18
线程

跳转实践

近似的话,被调理程序会遵照程序代码的运维顺序依次实施。GDB提供了乱序履行的功用,也正是说,GDB可以改正程序的实施种种,能够让程序实施随便跳跃。这些效用能够由GDB的jump命令来完:

jump <linespec>

内定下一条语句的运营点。<linespce>能够是文本的行号,能够是file:line格式,能够是+num这种偏移量格式。表示下一条运营语句从何地领头。

jump <address>

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

留心,jump命令不会改动方今的次第栈中的内容,所以,当您从多个函数跳到另二个函数时,当函数运营完回届期举办弹栈操作时一定会时有爆发错误,大概结果如故要命古怪的,以至于产生程序Core
Dump。所以最佳是同一个函数中举办跳转。

深谙汇编的人都驾驭,程序运营时,有二个存放器用于保存当前代码所在的内部存款和储蓄器地址。所以,jump命令也正是改动了这么些存放器中的值。于是,你能够选取“set
$pc”来改换跳转实践的地址。如:

set $pc = 0x485

    4.1
程序运营参数

为休憩点设定运营命令

我们得以行使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函数中大于0,GDB会自动打字与印刷出x的值,并继续运路程序。

一经你要排除断点上的下令类别,那么只要简单的实践一下commands命令,并间接再打个end就能够了。

break foo if x>0
commands
end

    5.2
多文本设置断点

线程

假使您程序是十二线程的话,你能够定义你的断点是不是在颇有的线程上,或是在有些特定的线程。GDB非常轻易帮您成功这一干活。

break <linespec> thread <threadno>
break <linespec> thread <threadno> if ...

linespec钦赐了断点设置在的源程序的行号。threadno内定了线程的ID,注意,这一个ID是GDB分配的,你能够经过“info
threads”命令来查阅正在运作程序中的线程消息。假设您不钦点thread
则代表您的断点设在具有线程上面。你还是能为某线程钦赐断点条件。如:

(gdb) break frik.c:13 thread 28 if bartab > lim

当你的程序被GDB停住时,全数的周转线程都会被停住。那便于你查看运路程序的完全意况。而在您复苏程序运营时,全数的线程也会被苏醒运行。那怕是主进度在被单步调节和测量试验时。

2
生成调节和测验音信

悬停条件保障

前方在聊起安装断点时,大家关系过可以安装叁个尺度,当准则组建即,程序自动终止,那是一个百般有力的功用,这里,小编想特别说说那几个规格的连锁维护命令。日常的话,为断点设置三个口径,大家选择if关键词,后面跟其断点条件。而且,条件设置好后,大家能够用condition命令来改进断点的口径。(独有break和watch命令援救if,catch目前暂不扶助if)。

condition <bnum> <expression>

改过断点号为bnum的告一段落条件为expression。

condition <bnum>

撤消断点号为bnum的终止条件。

还应该有三个比较奇特的掩护命令ignore,你能够钦赐程序运转时,忽视结束条件两回。

ignore <bum> <count>

代表忽视断点号为bnum的告一段落条件count次。

3 启动GDB 的方法

1、gdb program

program 也便是你的实施文书,平时在当前目录下。

2、gdb program core

用gdb同一时间调节和测量试验三个周转程序和core文件,core是程序不合规实践后core
dump后产生的文书。

3、gdb program 1234

假如您的主次是叁个服务程序,那么你能够内定那几个服务程序运营时的经过ID。gdb会自动attach上去,并调节和测量试验他。program应该在PATH景况变量中寻觅得到。

强迫调用函数

call <expr>

表明式中能够一是函数,以此达到强逼调用函数的目标。并呈现函数的重返值,要是函数重回值是void,那么就不显得。

另一个肖似的通令也能够产生这一效果——print,print前面能够跟表明式,所以也足以用他来调用函数,print和call的不一样是,假设函数再次回到void,call则不显得,print则显得函数重回值,并把该值存入历史数据中。

12 程序变量

在GDB中,你能够随即查阅以下两种变量的值:

1、全局变量(全部文件可以见到的)

2、静态全局变量(当前文件可以预知的)

3、局地变量(当前Scope可以预知的)

一经您的有的变量和全局变量发生冲突(也正是重名),平日景观下是一些变量会暗藏全局变量,也正是说,若是叁个全局变量和叁个函数中的局部变量同名
时,要是当前终止点在函数中,用print展现出的变量的值会是函数中的局地变量的值。假使此刻您想查看全局变量的值时,你能够使用“::”操作符:

file::variable

function::variable

能够经过这种格局钦命你所想查看的变量,是哪位文件中的或是哪个函数中的。例如,查看文件f2.c中的全局变量x的值:

p ‘f2.c’::x

理之当然,“::”操作符会和C++中的产生冲突,GDB能自动识别“::”是不是C++的操作符,所以您不要忧虑在调节和测量检验C++程序时会现身十分。

4数组变量

不常,你须要查阅一段连接的内部存款和储蓄器空间的值。比如数组的一段,或是动态分配的数目标大大小小。你能够选用GDB的“@”操作符,“@”的左手是率先个内部存款和储蓄器的地点的值,“@”的左臂则你你想查看内存的长度。举个例子,你的次第中有那样的语句:

int *array = (int *) malloc (len * sizeof (int));

于是乎,在GDB调节和测量试验进程中,你可以以如下命令展现出这么些动态数组的取值:

p *array@len

@的右边手是数组的首地址的值,也便是变量array所指向的原委,右侧则是数码的长度,其保存在变量len中。

复苏程序运转和单步调节和测量试验

当程序被停住,可以运用continue命令复苏程序的运营直至程序甘休,也许下四个断点到来。同临时间,也足以动用step或next命令来落成程序单步追踪。

(1)continue/c/fg

continue [ignore-count]
c [ignore-count]
fg [ignore-count]

恢复生机程序运转,直到程序甘休,或是下二个断点到来。ignore-count表示忽视其后的断点次数。continue、c、fg多少个指令都以大同小异的意味。

(2)step/s

step <count>

单步追踪,假如有函数调用,step会步入该调用函数。步入函数的前提是,此函被编写翻译有debug音讯。此命令相符VC等工具中的step
in。前边能够加count也足以不加,不加表示逐一试行,加count表示试行前面包车型客车count条指令,然后再停住。

(3)next/n

next <count>

一致单步追踪,假若有函数调用,next不会进来该调用函数。很像VC等工具中的step
over。前面能够加count也足以不加,不加表示逐个执行,加表示推行前边的count条指令,然后再停住。

(4)finish

运作程序,直到近年来函数完成重临。并打印函数重回时的饭店地址和重临值及参数值等消息。

(5)until/u

当您恨恶了在三个循环体内单步追踪时,那么些命令能够运路程序直到退出循环体。

(6)stepi/si、nexti/ni

单步追踪一条机器指令!一条程序代码有一点都不小或然由数条机器指令完结,stepi和nexti能够单步试行机器指令。与之相符有周边效果的授命是“display/i
$pc”
,当运营完这些命令后,单步追踪会在打出程序代码的还要打出机器指令(也正是汇编代码)。

(7)set step-mode

set step-mode on

开辟step-mode方式,于是,在扩充单步追踪时,程序不会因为从没debug消息而不停住。这一个参数有很有利查看机器码。

set step-mod off

关闭step-mode模式。

16
展现源代码

历史记录

当您用GDB的print查看程序运营时的数据时,你每八个print都会被GDB记录下来。GDB会以$1, $2, $3 .....那般的点子为你每二个print命令编上号。于是,你基本上能用这几个编号访谈从前的表明式,如$1。那个功能所拉动的裨益是,若是您早先输入了多少个相比长的表达式,假设你还想查看那么些表明式的值,你能够选拔历史记录来访谈,省去了双重输入。

16 展现源代码

GDB 能够打字与印刷出所调试程序的源代码,当然,在程序编写翻译时必必要丰裕 –g
的参数,把源程序消息编写翻译到试行文书中。不然就看不到源程序了。当程序停下来之后,
GDB会报告先后停在了拾分文件的第几行上。你能够用list命令来打字与印刷程序的源代码。私下认可打字与印刷10行,依旧来看一看查看源代码的GDB命令吧。

list linenum

Print lines centered around line number linenum in the current source
file.

list function

展现函数名叫function的函数的源程序。

list

呈现当前进后边的源程序。

list –

呈现当前进前面包车型客车源程序。

诚如是打字与印刷当前行的上5行和下5行,即使展现函数是是上2行下8行,默许是10行,当然,你也能够定制彰显的限制,使用上面施命发号能够安装一回突显源程序的行数。

set listsize count

安装叁回突显源代码的行数。(unless the list argument explicitly specifies
some other numberState of Qatar

show listsize

查看当前listsize的设置。

GDB概述

GDB是GNU开源公司宣布的八个强硬的UNIX下的程序调节和测量检验工具。或然,各位相比较向往那种图形分界面格局的,像VC、BCB等IDE的调度,但假设您是在UNIX平台下做软件,你会意识GDB那几个调节和测验工具备比VC、BCB的图形化调节和测量试验器越来越强盛的功力。所谓“寸有所长,各有所短”就是其一道理。

相近的话,GDB首要扶助你完了下边三个地点的法力:

  1. 启航你的次序,能够依据你的自定义的渴求自由的运作程序。
  2. 可让被调弄收拾的主次在您所钦点的调置的断点处停住。(断点能够是规范化表明式)
  3. 当程序被停住时,能够检查当时你的前后相继中所产生的事。
  4. 动态的转移您程序的实施情形。

从上边看来,GDB和日常的调治工具未有啥两样,基本上也是马到功成那一个职能,不过在细节上,你会发觉GDB这几个调节和测量检验工具的强有力,大家只怕相比较习贯了图形化的调解工具,但不经常候,命令行的调节和测验工具却有所图形化工具所无法实现的效劳。让大家一一看来。

22 内定源文件的路径

一些时候,用-g编译过后的试行顺序中只是总结了源文件的名字,未有路线名。GDB提供了足以让您钦点源文件的路子的下令,以便GDB进行寻觅。

Directory dirname …

dir dirname …

加三个源文件路线到这段日子路径的前边。倘诺您要钦点四个门路,UNIX下你能够利用“:”,Windows下您能够选拔“;”。

directory

扫除全部的自定义的源文件寻觅路线新闻。

show directories

来得定义了的源文件寻找路线。

 

gdb基本命令 

正文介绍使用gdb调节和测量检验程序的常用命令。 

非常重要内容: 

[简介] 

[举例] 

[其他] 

 

[简介] 

============= 

GDB是GNU开源公司颁发的三个无敌的UNIX下的程序调节和测量试验工具。假若您是在
UNIX平台下做软件,你会意识GDB这么些调节和测量试验工具备比VC、BCB的图形化调节和测量检验器更刚劲的机能。相同的时候GDB也存有举例说ddd那样的图形化的调节和测量试验端。 

诚如的话,GDB首要形成下边多个方面包车型地铁职能: 

(1卡塔尔(قطر‎运转你的次序,能够根据你的自定义的渴求自由的运营程序。 

(2State of Qatar可让被调治将养的前后相继在您所钦赐的调置的断点处停住。(断点能够是基准表明式) 

(3卡塔尔当程序被停住时,能够检查这个时候你的前后相继中所产生的事。 

(4卡塔尔动态的转移您程序的奉行遭遇。 

 

兴趣是最棒的教师职员和工人,这里先整理总括一下在调整的进程中时常遇上的难点。带着这几个主题素材进行学习和实行能够推进加深圳影业公司像。
再今后是本身实行进度香港中华总商会结的大规模命令,如有啥难点只怕提出,都能够联系本身,感激!^_^ 

(1卡塔尔(قطر‎如何打字与印刷变量的值?(print var卡塔尔国 

(2卡塔尔怎样打字与印刷变量的地点?(print
&var卡塔尔国 

(3卡塔尔国如何打字与印刷地址的数据值?(print
*address) 

(4卡塔尔国怎样查看当前运维的文本和行?(backtraceState of Qatar 

(5卡塔尔国怎么着查看钦命文件的代码?(list
file:N卡塔尔 

(6State of Qatar怎么样及时实行完当前的函数,不过并非实行完全体应用程序?(finish卡塔尔(قطر‎ 

(7卡塔尔(قطر‎纵然程序是多文件的,怎么着定位到钦命文件的内定行照旧函数?(list
file:N卡塔尔国 

(8卡塔尔要是循环次数过多,怎么着实践完当前的巡回?(until卡塔尔国 

(9卡塔尔国八线程怎样调治?(???卡塔尔国 

 

作者:QuietHeart 

Email: quiet_heart000@126.com 

 

 

[举例] 

============= 

*启动gdb 

$gdb 

这么能够和gdb进行交互作用了。 

 

*启航gdb,並且分屏展现源代码: 

$gdb
-tui 

这么,使用了’-tui’选项,运营能够间接将显示器分成三个部分,上边展现源代码,比用list方便多了。那时使用前后方向键能够查看源代码,想要命令行使用上下键就用[Ctrl]n和[Ctrl]p. 

 

*开发银行gdb调节和测量检验内定程序app: 

$gdb
app 

这么就在起步gdb之后一贯载入了app可执路程序,供给注意的是,载入的app程序必得在编写翻译的时候有gdb调试选项,举个例子’gcc -g app
app.c’,注意,如若改善了先后的源代码,可是并未有编写翻译,那么在gdb中展现的会是退换后的源代码,可是运行的是改换前的次第,那样会招致追踪错乱
的。 

 

*开发银路程序之后,再用gdb调节和测量检验: 

$gdb
 

这里,是程序的可实施文件名,是要调节和测量试验程序的PID.假诺你的主次是二个服务程序,那么您能够钦点那一个服务程序运转时的经过ID。gdb会自动attach上去,并调节和测量检验他。program应该在PATH遭逢变量中寻觅获得。 

 

*早先程序之后,再开发银行gdb调节和测量检验: 

$gdb
 

此地,程序是二个服务程序,那么你能够内定这几个服务程序运维时的历程ID,是要调节和测量检验程序的PID.这样gdb就附加到程序上了,不过现在还未法查看源代码,用file命令指明可实施文件就足以来得源代码了。 

 

 

**启航gdb之后的互相命令: 

相互命令协助[Tab]补全。 

 

*显示援救新闻: 

(gdb) help 

 

*载入内定的主次: 

(gdb) file app 

如此在gdb中载入想要调节和测量检验的可推行程序app。假若刚开首运营gdb并非用gdb
app运维的话能够这么载入app程序,当然编写翻译app的时候要参预-g调节和测验选项。 

 

*重国民党的新生活运动行调解的顺序: 

(gdb) run 

要想运转计划调节和测量试验的次第,可选取run命令,在它背后能够跟随发给该程序的别的参数,包涵职业输入和规范输出表达符(<和>
卡塔尔和shell通配符(*、?、[、])在内。 

 

*纠正发送给程序的参数: 

(gdb) set args
no 

此地,若是自身利用”r
yes”设置程序运营参数为yes,那么这里的set
args会设置参数argv[1]为no。 

 

*来得缺省的参数列表: 

(gdb) show args 

 

*列出钦命区域(n1到n2之间卡塔尔的代码: 

(gdb) list n1
n2 

如此那般,list能够简写为l,将会来得n1行和n2行之间的代码,如若采纳-tui运转gdb,将会在相应的职位突显。若无n1和n2参数,那么就能够暗中同意呈现当前行和后来的10行,再施行又下滚10行。其余,list还足以接函数名。 

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

  行号。 

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

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

 哪个文件的哪一行。 

 函数名。 

哪个文件中的哪个函数。 

<*address>
 程序运营时的讲话在内存中之处。 

 

*实施下一步: 

(gdb) next 

这么,实践一行代码,假若是函数也会跳过函数。那些命令能够简化为n. 

 

*实施N次下一步: 

(gdb) next N 

 

*实行上次施行的命令: 

(gdb) [Enter] 

那边,间接输入回车就能施行上次的授命了。 

 

*单步进入: 

(gdb) step 

像这种类型,也会进行一行代码,然而假诺遭遇函数的话就能够进来函数的里边,再一行一行的实施。 

 

*进行完当前函数重返到调用它的函数: 

(gdb) finish 

那边,运行程序,直到目前函数运营实现重回再甘休。举例走入的单步试行假使已经进入了某函数,而想退出该函数重返到它的调用函数中,可使用命令finish. 

 

*点名程序直到退出当前循环体: 

(gdb) until 

或(gdb) u 

那边,发掘供给把光标结束在循环的头顶,然后输入u那样就自动实践总体的轮回了。 

 

*跳转施行顺序到第5行: 

(gdb) jump 5 

此处,能够简写为”j
5″供给注意的是,跳转到第5行试行达成之后,假如后边未有断点则继续推行,而并不是停在那里了。 

除此以外,跳转不会改造方今的旅社内容,所以跳到别的函数中就能有不测的气象,因而最棒跳转在一个函数内部开展,跳转的参数也能够是程序代码行的地址,函数名等等近似list。 

 

*免强重返当前函数: 

(gdb) return 

这么,将会忽略当前函数还不曾实行完结的言语,强迫再次回到。return前面能够接三个表达式,表明式的再次来到值就是函数的重回值。 

 

*强制调用函数: 

(gdb) call  

那边,能够是三个函数,那样就能够回到函数的重临值,就算函数的归来类型是void那么就不会打字与印刷函数的再次回到值,可是试行发掘,函数运维进度中的打字与印刷语句依旧还没被打字与印刷出来。 

 

*强逼调用函数2: 

(gdb) print  

此地,print和call的意义周围,区别的是,即便函数的再次来到值是void那么call不会打印重回值,不过print还是会打字与印刷出函数的再次来到值並且寄存到历史记录中。 

 

*在当下的公文中某一行(借使为6)设定断点: 

(gdb) break 6 

 

*安装标准断点: 

(gdb) break 46 if
testsize==100 

此处,假设testsize==100就在46行处断点。 

 

*检查测量检验表明式变化则停住: 

(gdb) watch i !=
10 

这里,i !=
10以此表明式一旦变化,则停住。watch
为表明式(变量)expr设置叁个观看点。一量宣布式值有生成时,立时停住程序(也是一种断点卡塔尔。 

 

*在时下的文书中为某一函数(若是为func卡塔尔(قطر‎处设定断点: 

(gdb) break
func 

 

*给内定文件(fileName)的某部行(N)处设置断点: 

(gdb) break
fileName:N 

此间,给某文件中的函数设置断点是同理的。 

 

*来安妥前gdb断点音信: 

(gdb) info
breakpoints 

此间,能够简写为info
break.会显示当前抱有的断点,断点号,断点地方等等。 

 

*删除N号断点: 

(gdb) delete N 

 

*去除全部断点: 

(gdb) delete 

 

*免去行N上边的享有断点: 

(gdb) clear N 

 

 

*三番七遍运路程序直接运营到下多个断点: 

(gdb) continue 

这里,若无断点就径直运维。 

 

*显示当前调用函数饭馆中的函数: 

(gdb) backtrace 

指令爆发一张列表,包罗着从近来的历程开头的具备有效进程和调用这几个进程的参数。当然,这里也交易会示出当下运作到了何地(文件,行卡塔尔。 

 

*翻看当前调节和测验程序的言语蒙受: 

(gdb) show
language 

此地,假如gdb无法识别你所调节和测验的顺序,那么暗许是c语言。 

 

*翻开当前函数的程序语言: 

(gdb) info
frame 

 

*展示当前的调节和测验源文件: 

(gdb) info
source 

那般展览会示当前所在的源代码文件消息,比方文件名称,程序语言等。 

 

*手动设置当前的程序语言为c++: 

(gdb) set language
c++ 

此地,借使gdb没有检查评定出您的程序语言,你可以那样设置。 

 

*查阅能够设置的程序语言: 

(gdb) set
language 

此间,使用未有参数的set
language能够查阅gdb中能够设置的程序语言。 

 

*悬停叁个正值调节和测验的前后相继: 

(gdb) kill 

这里,输入kill就能够停下正在调节和测量检验的次第了。 

 

*print展现变量(var卡塔尔值: 

(gdb) print var 

此地,print能够简写为p,print
是gdb的叁个效应很强的命令,利用它能够展现被调养的语言中其它有效的表明式。表明式除了包罗你程序中的变量外,还足以包含函数调用,复杂数据结商谈历史等等。 

 

*用16进制展现(varState of Qatar值: 

(gdb) print /x
var 

此间能够领略,print能够钦命突显的格式,这里用’/x’表示16进制的格式。 

能够援助的变量展现格式有: 

x  按十五进制格式展现变量。 

d  按十进制格式展现变量。 

u
 按十七进制格式显示无符号整型。 

o  按八进制格式呈现变量。 

t  按二进制格式展现变量。 

a  按十七进制格式呈现变量。 

c  按字符格式展现变量。 

f  按浮点数格式呈现变量。 

 

 

*设若a是三个数组,十二个成分,假若要呈现则: 

(gdb) print
*a@10 

那般,会来得11个因素,无论a是double可能是int的都会不错地体现十三个要素。 

 

*矫正运转时候的变量值: 

(gdb) print x=4 

这里,x=4是C/C++的语法,意为把变量x值改为4,假使您眼前调试的言语是帕斯Carl,那么您能够运用帕斯Carl的语法:x:=4。 

 

*来得叁个变量var的门类: 

(gdb) whatis
var 

 

*以更详细的不二秘技浮现变量var的花色: 

(gdb) ptype var 

那边,会打字与印刷出var的布局定义。 

**

 

[其他] 

============= 

*在Qt4.x景况中打字与印刷QString
msg;的msg变量: 

步骤如下: 

1卡塔尔定义一个宏printqstring 

define
printqstring 

   
printf “(QString)0x%x (length=%i):
\””,&$arg0,$arg0.d->size 

   
set $i=0 

   
while $i < $arg0.d->size 

   
    set $c=$arg0.d->data[$i++] 

   
    if $c < 32 || $c > 127 

   
            printf “\\u0x%04x”, $c 

   
    else 

   
            printf “%c”, (char)$c 

   
    end 

   
end 

   
printf “\”\n” 

end 

2)(gdb) printqstring
msg 

这边,这些宏能够在gdb中一直定义,听别人讲也能够写到$HOME/.gdbinit,那样每趟运维自动加载。 

 

*调整相同的时候指明生成core文件: 

$gdb
core 

用gdb同一时候调节和测验三个运营程序和core文件,core是前后相继违规推行后core
dump后产生的文本。当程序不合规崩溃的时候会时有发生一个core文件,然后接纳那个命令,会直接固定到产生程序崩溃的地点。注意:不经常须要安装系统命令
“ulimit -c unlimited”才干发出core文件。 

 

 

**尚无推行过的 

*print显示存款和储蓄块,如呈现h后边的十贰个整数: 

print h@10 

** 

 

设置捕捉点(catchpoint)

能够安装捕捉点来捕捉程序运转时的局地轩然大波,如:载入分享库(动态链接库)或是C++的极其。

安装捕捉点的格式为:

(1)catch <event>

当event发生时,停住程序。

event能够是底下的从头到尾的经过:

  • throw 三个 C++ 抛出的要命(throw为着眼字)
  • catch 多个 C++ 捕捉的不得了(catch为重中之重字)
  • exec 调用系统调用exec时(exec为重要字,近来此功效只在HP-UX下有用)
  • fork 调用系统调用fork时(fork为根本字,近日此功效只在HP-UX下有用)
  • vfork
    调用系统调用vfork时(vfork为主要字,方今此功效只在HP-UX下有用)
  • load 或 load
    载入分享库(动态链接库)时(load为重大字,近日此功用只在HP-UX下有用)
  • unload 或 unload
    卸载分享库(动态链接库)时(unload为主要字,近期此作用只在HP-UX下有用)

(2)tcatch <event>

只设置依次捕捉点,当程序停住将来,该捕捉点被活动删除。

15.1 改过变量值

改过被调节和测量检验程序运营时的变量值,在GDB中超级轻易完结,使用GDB的print命令就能够成功。如:

(gdb) print x=4

x=4那一个表明式是C/C++的语法,意为把变量x的值修正为4,假若你这段日子调节和测验的言语是帕斯Carl,那么您能够采用Pascal的语法: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命令。

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

你能够采用info line一声令下来查看源代码在内部存款和储蓄器中的地址。

info line前边能够跟“行号”,“函数名”,“文件名:行号”,“文件名:函数名”,那一个命令会打字与印刷出所钦命的源码在运维时的内部存款和储蓄器地址,如:

(gdb) info line test1.c:func

Line 4 of "test1.c" starts at address 0x4004f4 <func> and ends at 0x4004fb <func+7>.

还应该有三个指令disassemble,你能够查看源程序的当下实行时的机器码,那些命令会把当前内部存款和储蓄器中的指令dump出来。

如上面包车型地铁亲自过问表示查看函数func的汇编代码。

(gdb) disassemble func
Dump of assembler code for function func:
   0x00000000004004f4 <+0>:    push   %rbp
   0x00000000004004f5 <+1>:    mov    %rsp,%rbp
   0x00000000004004f8 <+4>:    mov    %edi,-0x14(%rbp)
   0x00000000004004fb <+7>:    movl   $0x0,-0x8(%rbp)
   0x0000000000400502 <+14>:    movl   $0x0,-0x4(%rbp)
   0x0000000000400509 <+21>:    jmp    0x400515 <func+33>
   0x000000000040050b <+23>:    mov    -0x4(%rbp),%eax
   0x000000000040050e <+26>:    add    %eax,-0x8(%rbp)
   0x0000000000400511 <+29>:    addl   $0x1,-0x4(%rbp)
   0x0000000000400515 <+33>:    mov    -0x4(%rbp),%eax
   0x0000000000400518 <+36>:    cmp    -0x14(%rbp),%eax
   0x000000000040051b <+39>:    jl     0x40050b <func+23>
   0x000000000040051d <+41>:    mov    -0x8(%rbp),%eax
   0x0000000000400520 <+44>:    pop    %rbp
   0x0000000000400521 <+45>:    retq  
End of assembler dump.

4
程序运行上下文

查看内部存款和储蓄器

您可以采用examine命令(简写是x)来查阅内部存款和储蓄器地址中的值。

x命令的语法如下所示:

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

中间,n、f、u是可选的参数。

n是叁个正整数,表示突显内部存款和储蓄器的长度,也正是说从近来地方向后显得多少个地点的剧情。

f代表展现的格式,参见上边。借使地点所指的是字符串,那么格式可以是s,即使地十是命令地址,那么格式能够是i。

u表示从近来地方未来号召的字节数,假如不钦赐的话,GDB暗中同意是4个bytes。u参数能够用下边包车型大巴字符来替代,b表示单字节,h表示双字节,w表示四字节,g表示风水节。当大家钦点了字节长度后,GDB会从指内部存款和储蓄器定的内部存款和储蓄器地址起头,读写钦点字节,并把其看成叁个值收取来。

<addr>表示一个内部存款和储蓄器地址。

n/f/u四个参数可以协作使用。举例:

命令:x /3uh 0x54320

该命令表示,从内部存款和储蓄器地址0×54320读取内容,h表示以双字节为八个单位,3意味五个单位,u表示按十一进制展现。

14
历史记录

表达式

print和非常多GDB的一声令下雷同,可以担当三个表明式,GDB会依照当前的程序运营的数目来测算这几个表明式,既然是表达式,那么就足以是当前景序运营中的const常量、变量、函数等内容。缺憾的是GDB不能够选取你在先后中所定义的宏。

表达式的语法应该是当前所调节和测量检验的语言的语法,由于C/C++是一种大众型的言语,所以,本文中的例子都以关于C/C++的。

在表明式中,有三种GDB所扶助的操作符,它们能够用在任何一种语言中。

  • @
    是叁个和数组有关的操作符,在背后会有更详细的印证。
  • ::
    钦定叁个在文件大概一个函数中的变量。
  • {<type>} <addr>
    意味着一个针对内部存款和储蓄器地址的品种为type的一个目的。

    15.3
产生能量信号量

出口格式

貌似的话,GDB会依据变量的品种输出变量的值。可是,你也得以自定义GDB的出口的格式。比方,你想出口一个整数的十九进制,或是二进制来查看那几个整型变量的中的位的事态。要产生那样,你可以动用GDB的多寡体现格式:

  • x 按十七进制格式显示变量
  • d 按十进制格式展现变量
  • u 按十五进制格式展现无符号整型
  • o 按八进制格式显示变量
  • t 按二进制格式展现变量
  • a 按十四进制格式显示变量
  • c 按字符格式呈现变量
  • f 按浮点数格式显示变量

(gdb) p i
$1 = 64
(gdb) p /a i
$2 = 0x40
(gdb) p /x i
$3 = 0x40
(gdb) p /c i
$4 = 64 '@'
(gdb) p /f i
$5 = 8.96831017e-44
(gdb) p /o i
$6 = 0100
(gdb) p /t i
$7 = 1000000

17
调节和测量检验已运营的历程

调度已运行的顺序

三种方式:

在Linux下用ps查看正在运作的程序的PID(进度ID),然后用gdb
PID格式挂接正在周转的前后相继;

gdb a.out 12963

先用gdb
关联源代码,并扩充gdb,在gdb中用attach命令来挂接进度PID,并用detach来废除挂接的经过。

例如说:我们去调治运维如下代码的次序。

#include <iostream>
#include <unistd.h>
using namespace std;

int main() {
    long long i = 0;
    while(1) {
        //sleep(1);
        i++;
        //cout << "i value = " << i << endl;
    }
    return 0;
}

编写翻译进程:

g++ -g attach_to_running_process_test.cpp

GDB调节和测验进程:

(gdb) attach 12698
Attaching to program: /root/share/gdbTest/a.out, process 12698
/root/share/gdbTest/a.out has changed; re-reading symbols.
Reading symbols from /usr/lib/x86_64-linux-gnu/libstdc++.so.6...(no debugging symbols found)...done.
Loaded symbols for /usr/lib/x86_64-linux-gnu/libstdc++.so.6
Reading symbols from /lib/x86_64-linux-gnu/libc.so.6...Reading symbols from /usr/lib/debug//lib/x86_64-linux-gnu/libc-2.19.so...done.
done.
Loaded symbols for /lib/x86_64-linux-gnu/libc.so.6
Reading symbols from /lib/x86_64-linux-gnu/libm.so.6...Reading symbols from /usr/lib/debug//lib/x86_64-linux-gnu/libm-2.19.so...done.
done.
Loaded symbols for /lib/x86_64-linux-gnu/libm.so.6
Reading symbols from /lib64/ld-linux-x86-64.so.2...Reading symbols from /usr/lib/debug//lib/x86_64-linux-gnu/ld-2.19.so...done.
done.
Loaded symbols for /lib64/ld-linux-x86-64.so.2
Reading symbols from /lib/x86_64-linux-gnu/libgcc_s.so.1...(no debugging symbols found)...done.
Loaded symbols for /lib/x86_64-linux-gnu/libgcc_s.so.1
main () at attach_to_running_process_test.cpp:19
19        return 0;
(gdb) p i
$1 = 7065833447
(gdb) p i
$2 = 7065833447
(gdb)
$3 = 7065833447
(gdb) c
Continuing.
^C
Program received signal SIGINT, Interrupt.
main () at attach_to_running_process_test.cpp:19
19        return 0;
(gdb) p i
$4 = 7439387814
(gdb) detach
Detaching from program: /root/share/gdbTest/a.out, process 12698
(gdb) q

3 启动GDB
的方法

发表评论

电子邮件地址不会被公开。 必填项已用*标注

相关文章