一.对于GDB理论的介绍:
1.定义:UNIX及UNIX-like下的调试工具。
2.功能:
1、启动你的程序,可以按照你的自定义的要求随心所欲的运行程序。
2、可让被调试的程序在你所指定的调置的断点处停住。(断点可以是条件表达式)
3、当程序被停住时,可以检查此时你的程序中所发生的事。
4、你可以改变你的程序,将一个BUG产生的影响修正从而测试其他BUG。
3.文件清单:
List
(gdb) list line1,line2
查看源代码
list lineNum 在lineNum的前后源代码显示出来
list + 列出当前行的后面代码行
list - 列出当前行的前面代码行
list function
set listsize count
设置显示代码的行数
show listsize
显示打印代码的行数
list first,last
显示从first到last的源代码行
4.执行程序:
要想运行准备调试的程序,可使用run命令,在它后面可以跟随发给该程序的任何参数,包括标准输入和标准输出说明符(<;和>;)和shell通配符(*、?、[、])在内。如果你使用不带参数的run命令,gdb就再次使用你给予前一条run命令的参数,这是很有用的。利用set args 命令就可以修改发送给程序的参数,而使用show args 命令就可以查看其缺省参数的列表。
(gdb) file a.out //加载被调试的可执行程序文件。
(gdb)set args –b –x
(gdb) show args
(gdb)r //执行程序
backtrace命令为堆栈提供向后跟踪功能。
Backtrace 命令产生一张列表,包含着从最近的过程开始的所有有效过程和调用这些过程的参数。
5.显示数据:
利用print 命令可以检查各个变量的值。
(gdb) print p (p为变量名)
print 是gdb的一个功能很强的命令,利用它可以显示被调试的语言中任何有效的表达式。表达式除了包含你程序中的变量外,还可以包含以下内容:
对程序中函数的调用
(gdb) print find_entry(1,0)
数据结构和其他复杂对象
(gdb) print *table_start
={e=reference=’\000’,location=0x0,next=0x0}
值的历史成分
(gdb)print (为历史记录变量,在以后可以直接引用的值)
人为数组
人为数组提供了一种去显示存储器块(数组节或动态分配的存储区)内容的方法。早期的调试程序没有很好的方法将任意的指针换成一个数组。就像对待参数一样,让我们查看内存中在变量h后面的10个整数,一个动态数组的语法如下所示:
base@length
因此,要想显示在h后面的10个元素,可以使用h@10:
(gdb)print h@10
=(-1,345,23,-234,0,0,0,98,345,10)
whatis命令可以显示某个变量的类型
(gdb) whatis p
type = int *
6.断点
break命令(可以简写为b)可以用来在调试的程序中设置断点,该命令有如下四种形式:
break line-number 使程序恰好在执行给定行之前停止。
break function-name 使程序恰好在进入指定的函数之前停止。
break line-or-function if condition 如果condition(条件)是真,程序到达指定行或函数时停止。
break routine-name 在指定例程的入口处设置断点
如果该程序是由很多原文件构成的,你可以在各个原文件中设置断点,而不是在当前的原文件中设置断点,其方法如下:
(gdb) break filename:line-number
(gdb) break filename:function-name
要想设置一个条件断点,可以利用break if命令,如下所示:
(gdb) break line-or-function if expr
例:
(gdb) break 46 if testsize==100
从断点继续运行:continue 命令
7.断点管理

1.显示当前gdb的断点信息:
(gdb) info break
他会以如下的形式显示所有的断点信息:
Num Type Disp Enb Address What
1 breakpoint keep y 0x000028bc in init_random at qsort2.c:155
2 breakpoint keep y 0x0000291c in init_organ at qsort2.c:168
删除指定的某个断点:
(gdb) delete breakpoint 1
该命令将会删除编号为1的断点,如果不带编号参数,将删除所有的断点
(gdb) delete breakpoint
禁止使用某个断点
(gdb) disable breakpoint 1
该命令将禁止断点1,同时断点信息的 (Enb)域将变为 n
允许使用某个断点
(gdb) enable breakpoint 1
该命令将允许断点1,同时断点信息的 (Enb)域将变为 y
清除源文件中某一代码行上的所有断点
(gdb)clear number
注:number 为源文件的某个代码行的行号
2.设置条件断点
例子: [1]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <stdio.h>

int main(void)
{
int i = 0;
int sum = 0;

   for (i = 1; i <= 200; i++){sum += i;}printf("%d\n", sum);return 0;

}
gdb可以设置条件断点,也就是只有在条件满足时,断点才会被触发,命令是“break … if cond”。以上面程序为例: [2]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
(gdb) start
Temporary breakpoint 1 at 0x4004cc: file a.c, line 5.
Starting program: /data2/home/nanxiao/a

Temporary breakpoint 1, main () at a.c:5
5 int i = 0;
(gdb) b 10 if i==101
Breakpoint 2 at 0x4004e3: file a.c, line 10.
(gdb) r
Starting program: /data2/home/nanxiao/a

Breakpoint 2, main () at a.c:10
10 sum += i;
(gdb) p sum
$1 = 5050
可以看到设定断点只在i的值为101时触发,此时打印sum的为5050。
8.变量检查赋值:
whatis:识别数组或变量的类型
ptype:比whatis的功能更强,他可以提供一个结构的定义
set variable = value:将值赋予变量
print variable = value or p variable = value : 除了显示一个变量的值外,还可以用来赋值
9.单步执行:
next 不进入的单步执行
step 进入的单步执行如果已经进入了某函数,而想退出该函数返回到它的调用函数中,可使用命令finish
10.函数调用:
call name 调用和执行一个函数
(gdb) call gen_and_sork(1234,1,0)
(gdb) call printf(“abcd”)
=4
finish 结束执行当前函数,显示其返回值(如果有的话)
11.
有一组专用的gdb变量可以用来检查和修改计算机的通用寄存器,gdb提供了目 前每一台计算机中实际使用的4个寄存器的标准名字:
$pc :程序计数器
$fp :帧指针(当前堆栈帧)
$sp :栈指针
$ps :处理器状态
12.信号:机器语言工具
gdb通常可以捕捉到发送给它的大多数信号,通过捕捉信号,它就可决定对于正在运行的进程要做些什么工作。例如,按CTRL-C将中断信号发送给gdb,通常就会终止gdb。但是你或许不想中断gdb,真正的目的是要中断gdb正在运行的程序,因此,gdb要抓住该信号并停止它正在运行的程序,这样就可以执行某些调试操作。
Handle命令可控制信号的处理,他有两个参数,一个是信号名,另一个是接受到信号时该作什么。几种可能的参数是:
nostop 接收到信号时,不要将它发送给程序,也不要停止程序。
stop 接受到信号时停止程序的执行,从而允许程序调试;显示一条表示已接受到信号的消息(禁止使用消息除外)
print 接受到信号时显示一条消息
noprint 接受到信号时不要显示消息(而且隐含着不停止程序运行)
pass 将信号发送给程序,从而允许你的程序去处理它、停止运行或采取别的动作。
nopass 停止程序运行,但不要将信号发送给程序。
例如,假定你截获SIGPIPE信号,以防止正在调试的程序接受到该信号,而且只要该信号一到达,就要求该程序停止,并通知你。要完成这一任务,可利用如下命令:
(gdb) handle SIGPIPE stop print
请注意,UNⅨ的信号名总是采用大写字母!你可以用信号编号替代信号名如果你的程序要执行任何信号处理操作,就需要能够测试其信号处理程序,为此,就需要一种能将信号发送给程序的简便方法,这就是signal命令的任务。该命令的参数是一个数字或者一个名字,如SIGINT。假定你的程序已将一个专用的SIGINT(键盘输入,或CTRL-C;信号2)信号处理程序设置成采取某个清理动作,要想测试该信号处理程序,你可以设置一个断点并使用如下命令:
(gdb) signal 2
continuing with signal SIGINT⑵
该程序继续执行,但是立即传输该信号,而且处理程序开始运行。
13.GDB的使用
GDB是一个强大的命令行调试工具。大家知道命令行的强大就是在于,其可以形成执行序列,形成脚本。UNⅨ下的软件全是命令行的,这给程序开发提代供了极大的便利,命令行软件的优势在于,它们可以非常容易的集成在一起,使用几个简单的已有工具的命令,就可以做出一个非常强大的功能。
于是UNⅨ下的软件比Windows下的软件更能有机地结合,各自发挥各自的长处,组合成更为强劲的功能。而Windows下的图形软件基本上是各自为营,互相不能调用,很不利于各种软件的相互集成。在这里并不是要和Windows做个什么比较,所谓“寸有所长,尺有所短”,图形化工具还有时不如命令行的地方。
二.LINUX下对于GDB的使用
1.对于最初的源文件.c文件使用使用命令: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)
然后你就会看到出现好多信息在屏幕上,大致说的是gdb的一些版本信息说明之类的,但是它对你调试程序没用呀,所以,你可以加上-q选项,不输出它们。
即是:gdb -q gdb_example

//gdb 还支持字符串查找,search str,从当前行开始,向前查找含str的字符串;

reverse-search str,从当前行开始,向后查找含str的字符串。
执行许多命令后:
现在你的屏幕应该被占满了吧?想清空屏幕,可是还在gdb里面呀,怎么办?其实,gdb也支持运行linux命令的,可以在gdb的提示符中,输入shell,然后在输入你需要的命令就可以了

(gdb) shell clear
这样也能达到清屏的效果。
1、list命令
在gdb中运行list命令(缩写l)可以列出代码,list的具体形式包括:

list   显示程序第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
复制代码
list   显示函数名为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] =
复制代码
list    显示当前行后面的源程序。

list -   显示当前行前面的源程序。

下面演示了使用gdb中的run(缩写r)、break(缩写b)、next(缩写n)命令控制程序的运行,并使用print(缩写p)命令打印程序中的变量sum的过程:

复制代码
(gdb) break add
Breakpoint 1 at 0x80482f7: file gdb_example.c, line 3.
(gdb) run
Starting program: /driver_study/gdb_example

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

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}
复制代码
2、run命令
在gdb中,运行程序使用run命令。在程序运行前,我们可以设置如下4方面的工作环境:

程序运行参数

set args 可指定运行时参数,如:set args 10 20 30 40 50;

show args 命令可以查看设置好的运行参数。

运行环境

path

可设定程序的运行路径;

how paths可查看程序的运行路径;

set environment varname [=value]用于设置环境变量,如set env USER=baohua;

show environment [varname]则用于查看环境变量。

工作目录

cd

相当于shell的cd命令;

pwd 显示当前所在的目录。

程序的输入输出

info terminal 用于显示程序用到的终端的模式;

gdb中也可以使用重定向控制程序输出,如run > outfile;

tty命令可以指定输入输出的终端设备,如:tty /dev/ttyS1。

3、break命令
在gdb中用break命令来设置断点,设置断点的方法包括:

break

在进入指定函数时停住,C++中可以使用class::function或function(type, type)格式来指定函数名。

break

在指定行号停住。

break +offset / break -offset

在当前行号的前面或后面的offset行停住,offiset为自然数。

break filename:linenum

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

break filename:function

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

break *address

在程序运行的内存地址处停住。

break

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

break … if

“…”可以是上述的break 、break +offset / break –offset中的参数,condition表示条件,在条件成立时停住。比如在循环体中,可以设置break if i=100,表示当i为100时停住程序。
info

查看断点时,可使用info命令,如info breakpoints [n]、info break [n](n表示断点号)。
  断点的进一步介绍//看了程序的代码,感觉第6行代码可能有点问题,现在就需要我就需要设置一个断点,让程序停在第6行之前。

(gdb) break 6
Breakpoint 1 at 0x80484c8: file test.c, line 6.
(gdb)
下面一行的 信息,1说明我设置的这个断点是第一个断点,断点所在内存地址为0x80484c8,它在文件test.c的第6行。

gdb还可以以条件表达式设置断点。

(gdb) break 7 if n==6
Breakpoint 2 at 0x80484d1: file test.c, line 7.
(gdb)
这个断点的含义是,如果n的值为6,则程序运行到第7行停止。

当然,还可以直接在某个函数处设置断点;直接break 函数名就可以了,

然后我们想看下设置的断点信息,可以使用info breakpoints命令。

复制代码
(gdb) info breakpoints
Num Type Disp Enb Address What
1 breakpoint keep y 0x080484c8 in func at test.c:6
2 breakpoint keep y 0x080484d1 in func at test.c:7
stop only if n==6
4 breakpoint keep y 0x080484c1 in func at test.c:5
(gdb)
复制代码
Num表示断点的编号;Type表示断点的断点的类型,第二个断点类型还加上了条件;Disp表示中断点在执行一次之后是否失去作用,dis为是,keep为不是;Enb表示当前中断点是否有效,y为是,n为否;Address表示中断点所处的内存地址;What指出断点所处的位置。

如果不需要程序在该断点暂停时,有两种方法,一种是使该断点失效,一种是直接删除该断点。

复制代码
(gdb) disable 1
(gdb) info breakpoints
Num Type Disp Enb Address What
1 breakpoint keep n 0x080484c8 in func at test.c:6
2 breakpoint keep y 0x080484d1 in func at test.c:7
stop only if n==6
3 breakpoint keep y 0x080484c1 in func at test.c:5
(gdb)
复制代码
可以看到,第一个断点的Enb变为n了,表示该断点已经无效了,如果需要恢复,可以使用enable命令。这里需要注意的是,disable后面的参数为断点的编号。而不是行号。

直接删除该断点,可以使用clear命令和delete命令。

(gdb) clear 6
已删除的断点 1
(gdb)
clear命令后面的参数为设置断点的行号,clear后面参数还可以加设置断点的函数名。

delete命令后面的参数为断点的编号;可以一次删除多个断点,断点编号之间用空格隔开;如果delete后没有参数,默认删除所以断点,会给出提示选择是否操作。

(gdb) delete
删除所有断点吗? (y or n)
断点设置好了,现在就可以调试了//

4、单步命令
在调试过程中,next命令用于单步执行,类似VC++中的step over。next的单步不会进入函数的内部,与next对应的step(缩写s)命令则在单步执行一个函数时,会进入其内部,类似VC++中的step into。下面演示了step命令的执行情况,在23行的add()函数调用处执行step会进入其内部的“return a+b;”语句:

复制代码
(gdb) break 25
Breakpoint 1 at 0x8048362: file gdb_example.c, line 25.
(gdb) run
Starting program: /driver_study/gdb_example

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;
复制代码
单步执行的更复杂用法包括:

step

单步跟踪,如果有函数调用,则进入该函数(进入函数的前提是,此函数被编译有debug信息)。step后面不加count表示一条条地执行,加表示执行后面的count条指令,然后再停住。

next

单步跟踪,如果有函数调用,它不会进入该函数。同样地,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
print /
是表达式,是被调试的程序中的表达式,

是输出的格式,比如,如果要把表达式按16进制的格式输出,那么就是/x。在表达式中,有几种GDB所支持的操作符,它们可以用在任何一种语言中,“@”是一个和数组有关的操作符,“::”指定一个在文件或是函数中的变量,“{} ”表示一个指向内存地址的类型为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一般来观察某个表达式(变量也是一种表达式)的值是否有变化了,如果有变化,马上停住程序。

我们有下面的几种方法来设置观察点:

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

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

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

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>
表示一个内存地址。“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)的内存。 ==
譬如下面的例子:

main()
{
char *c = “hello world”;
printf("%s\n", c);
}
我们在

char *c = “hello world”;
下一行设置断点后:

复制代码
(gdb) l
1 main()
2 {
3 char *c = “hello world”;
4 printf("%s\n", c);
5 }
(gdb) b 4
Breakpoint 1 at 0x100000f17: file main.c, line 4.
(gdb) r
Starting program: /Users/songbarry/main
Reading symbols for shared libraries +. done

Breakpoint 1, main () at main.c:4
4 printf("%s\n", c);
复制代码
可以通过多种方式看C指向的字符串:

方法1:
(gdb) p c
$1 = 0x100000f2e “hello world”
方法2:

(gdb) x/s 0x100000f2e
0x100000f2e: “hello world”
方法3:

(gdb) p (char *)0x100000f2e
$3 = 0x100000f2e “hello world”
将第一个字符改为大写:

(gdb) p *(char *)0x100000f2e=‘H’
$4 = 72 ‘H’
再看看C:

(gdb) p c
$5 = 0x100000f2e “Hello world”
9、set命令
修改寄存器:

(gdb) set $v0 = 0x004000000
(gdb) set $epc = 0xbfc00000
修改内存:

(gdb) set {unsigned int}0x8048a51=0x0
譬如对于第8节的例子:

(gdb) set {unsigned int}0x100000f2e=0x0
(gdb) x/10cb 0x100000f2e
0x100000f2e: 0 ‘\0’ 0 ‘\0’ 0 ‘\0’ 0 ‘\0’ 111 ‘o’ 32 ’ ’ 119 ‘w’ 111 ‘o’
0x100000f36: 114 ‘r’ 108 ‘l’
(gdb) p c
$10 = 0x100000f2e “”
10、jump命令
一般来说,被调试程序会按照程序代码的运行顺序依次执行,但是GDB也提供了乱序执行的功能,也就是说,GDB可以修改程序的执行顺序,从而让程序随意跳跃。这个功能可以由GDB的jump命令:jump 来指定下一条语句的运行点。可以是文件的行号,可以是file:line格式,也可以是+num这种偏移量格式,表示下一条运行语句从哪里开始。jump

这里的

是代码行的内存地址。 注意,jump命令不会改变当前的程序栈中的内容,所以,如果使用jump从一个函数跳转到另一个函数,当跳转到的函数运行完返回,进行出栈操作时必然会发生错误,这可能导致意想不到的结果,所以最好只用jump在同一个函数中进行跳转。

11、signal命令
使用singal命令,可以产生一个信号量给被调试的程序,如中断信号“Ctrl+C”。这非常方便于程序的调试,可以在程序运行的任意位置设置断点,并在该断点用GDB产生一个信号量,这种精确地在某处产生信号的方法非常有利于程序的调试。 signal命令的语法是:signal ,UNIX的系统信号量通常从1到15,所以取值也在这个范围。

12、return命令
如果在函数中设置了调试断点,在断点后还有语句没有执行完,这时候我们可以使用return命令强制函数忽略还没有执行的语句并返回。
return
return
上述return命令用于取消当前函数的执行,并立即返回,如果指定了,那么该表达式的值会被作为函数的返回值。

13、call命令
call命令用于强制调用某函数: call 表达式中可以一是函数,以此达到强制调用函数的目的,它会显示函数的返回值(如果函数返回值不是void)。 其实,前面介绍的print命令也可以完成强制调用函数的功能。

14、info命令
info命令可以在调试时用来查看寄存器、断点、观察点和信号等信息。

要查看寄存器的值,可以使用如下命令:

info registers (查看除了浮点寄存器以外的寄存器)

info all-registers (查看所有寄存器,包括浮点寄存器)

info registers <regname …> (查看所指定的寄存器)

info break 查看断点信息

info watchpoints 列出当前所设置的所有观察点,

info signals info handle 查看有哪些信号正在被GDB检测,

info line命令来查看源代码在内存中的地址。

info threads可以看多线程。

info line后面可以跟行号、函数名、文件名:行号、文件名:函数名等多种形式,例如下面的命令会打印出所指定的源码在运行时的内存地址:

info line tst.c:func
15、set scheduler-locking off|on|step
off 不锁定任何线程,也就是所有线程都执行,这是默认值。
on 只有当前被调试程序会执行。
step 在单步的时候,除了next过一个函数的情况以外,只有当前线程会执行。

与多线程调试相关的命令还包括:

thread ID
  切换当前调试的线程为指定ID的线程。
break thread_test.c:123 thread all
  在所有线程中相应的行上设置断点
thread apply ID1 ID2 command
  让一个或者多个线程执行GDB命令command。
thread apply all command
  让所有被调试线程执行GDB命令command。
16、disassemble
disassemble命令用于反汇编,它可被用来查看当前执行时的源代码的机器码,其实际上只是把目前内存中的指令dump出来。下面的示例用于查看函数func的汇编代码:

复制代码
(gdb) disassemble func
Dump of assembler code for function func:
0x8048450 : 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.
今天先写这些命令,还有其他的命令之后在更新。

linux--gdb调试相关推荐

  1. linux子系统gdp调试,Linux GDB调试 详述

    今天来分享下gdb的简单调试,我这里写了个例子 三个.c文件 func1.c func2.c main.c 首先生成可调试的执行文件 gcc -g func1.c func2.c main.c -o ...

  2. Linux GDB调试

    Linux 段错误调试 core 文件调试 编译时 加上 -g 使编译出的文件带 调试信息 gcc -g main.c -o main 使编译出的可执行文件带调试信息gdb main //对 main ...

  3. [Linux]gdb调试多进程多线程例程

    gdb相信学linux的同学已经比较熟悉了吧,它是linux下代码调试工具.我们在写c语言,c++的代码时经常会用到,它有一些常用的调试命令: run(r):运行程序,如果有断点在下一个断点处停止 s ...

  4. Linux gdb调试(4):多进程与多线程调试

    一,gdb的基础知识 1>介绍: gdb是Linux环境下的代码调试工具. 2>使用:需要在源代码生成的时候加上 -g 选项. 3>开始使用: gdb binFile 4>退出 ...

  5. Linux GDB调试死锁问题

    1. 死锁介绍 1.1 锁的简介 由于多线程的模式下,各个线程并发运行(注意"并发和"并行"的区别),为了保证各个线程对公共资源的访问时出现数据不一致性的问题,出现了锁的 ...

  6. Linux GDB调试完全教程

    转自 http://blog.csdn.net/gatieme 本文将主要介绍linux下的强大调试工具是怎么完成这些工作的. 之所以要调试程序,是因为程序的运行结果和预期结果不一致,或者程序出现运行 ...

  7. Linux gdb调试器

    gdb的启动 --gdb 程序名 [corefile] --corefile是可选的,但能增强gdb的调试能力 --强调:启动gdb必须在编译命里加上"-g"参数,"-g ...

  8. linux gdb检查函数栈,Linux - gdb调试

    调试 调试工具:gdb的使用 编译后版本 编译后的成果分为两个版本: debug版本:调试版本 -->程序员使用 release版本:最终发行版本 -->最终用户使用 gcc默认生成的是r ...

  9. Linux——gdb调试时多进程切换方法(attach/follow-fork-mode)

    对于程序中创建子进程的情况,进行gdb调试时会默认选择父进程进行调试,假如需要对子进程进行调试就需要使用特殊方法. 共有两种方法可供选择: 目录 一.attach子进程PID ①.运行进程 ②获取进程 ...

  10. linux gdb调试问题汇总

    1. 宏调试 在GDB下,我们无法print宏定义,因为宏是预编译的.但是我们还是有办法来调试宏,这个需要GCC的配合. 在GCC编译程序的时候,加上-ggdb3参数,这样,你就可以调试宏了. 另外, ...

最新文章

  1. 【HDU】1237 简单计算器 (stack)
  2. Apache Flink 漫谈系列(12) - Time Interval(Time-windowed) JOIN...
  3. Winform中简单使用MD5加密用户登录密码
  4. C# log4net 不输出日志
  5. (String)、toString、String.valueOf的区别
  6. linux dns resolver,如何解决Linux in-kernel dns_resolver问题
  7. CheckstyleException: cannot initialize module TreeWalker - TreeWalker is not allowed as a
  8. Jsp+Servlet+Mysql实现的在线鲜花商城源码
  9. 基于react的简单TODOList
  10. Atitit 项目管理优化体系图 第4章 项目整合管理 开始 计划 执行 监控 变更 结束 第5章 项目范围管理  SOW工作说明书 成员通讯录 wbs大概模块级别 第6章 项目时间
  11. r-cnn 行人检测_了解用于对象检测的快速R-CNN和快速R-CNN。
  12. 网络通信基础知识—网络通信的发展历程
  13. 实景三维的基石-osgb
  14. 【小米商城首页简单设计】
  15. android webview 视频黑屏,webview 播放H5视频问题 黑屏 只有声音没有画面
  16. 用python做乘法口诀表_如何用python编写乘法口诀表
  17. Speedoffice(excel)如何利用SUMIF函数求和
  18. 非局部相似性 matlab,非局部均值滤波(NLM)和MATLAB程序详解视频教程保持图像细节...
  19. linux 第二十天 linuxprobe
  20. Python(十一) 原生爬虫

热门文章

  1. Facebook推出Pythia 开源 可用于图像及语言分析
  2. MVC把表格导出到Excel
  3. 实现Java集合迭代的高性能
  4. 基于httpd建立私有CA实现https加密连接
  5. ES6 import代码智能转换Babel插件: babel-plugin-imports-transform
  6. 编写Dockerfiles的最佳做法
  7. VMware Ubuntu 共享文件夹
  8. 修复cocos2dx的Label,WP8下不能换行的问题
  9. 关于Android Listview的问题
  10. 解决PHPCMS 安装问题 Can not connect to MySQL server