文档库 最新最全的文档下载
当前位置:文档库 › GDB 概述

GDB 概述

GDB 概述
GDB 概述

————

GDB是GNU开源组织发布的一个强大的UNIX下的程序调试工具。或许,各位比较喜欢那种图形界面方式的,像VC、BCB等IDE的调试,但如果你是在UNIX平台下做软件,你会发现GDB这个调试工具有比VC、BCB的图形化调试器更强大的功能。所谓“寸有所长,尺有所短”就是这个道理。

一般来说,GDB主要帮忙你完成下面四个方面的功能:

1、启动你的程序,可以按照你的自定义的要求随心所欲的运行程序。

2、可让被调试的程序在你所指定的调置的断点处停住。(断点可以是条件表达式)

3、当程序被停住时,可以检查此时你的程序中所发生的事。

4、动态的改变你程序的执行环境。

从上面看来,GDB和一般的调试工具没有什么两样,基本上也是完成这些功能,不过在细节上,你会发现GDB这个调试工具的强大,大家可能比较习惯了图形化的调试工具,但有时候,命令行的调试工具却有着图形化工具所不能完成的功能。让我们一一看来。

一个调试示例

——————

源程序:tst.c

1 #include

2

3 int func(int n)

4 {

5 int sum=0,i;

6 for(i=0; 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 }

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

2

3 int func(int n)

4 {

5 int sum=0,i;

6 for(i=0; 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 16 <-------------------- 设置断点,在源程序第16行处。 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:17 <---------- 在断点处停住。

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 027. <--------程序退出,调试结束。

(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

如果没有-g,你将看不见程序的函数名、变量名,所代替的全是运行时的内存地址。当你用-g把调试信息加入之后,并成功编译目标代码以后,让我们来看看如何用gdb来调试他。

启动GDB的方法有以下几种:

1、gdb

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

2、gdb core

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

3、gdb

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

GDB启动时,可以加上一些GDB的启动开关,详细的开关可以用gdb -help查看。我在下面只例举一些比较常用的参数:

-symbols

-s

从指定文件中读取符号表。

-se file

从指定文件中读取符号表信息,并把他用在可执行文件中。

-core

-c

调试时core dump的core文件。

-directory

-d

加入一个源文件的搜索路径。默认搜索路径是环境变量中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 命令,如: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就行了。

GDB中运行UNIX的shell程序

————————————

在gdb环境中,你可以执行UNIX的shell的命令,使用gdb的shell命令来完成:

shell

调用UNIX的shell来执行,环境变量SHELL中定义的UNIX的shell将会被用来执行,如果SHELL没有定义,那就使用UNIX的标准shell:/bin/sh。(在Windows 中使用https://www.wendangku.net/doc/1610357752.html,或cmd.exe)

还有一个gdb命令是make:

make

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

在GDB中运行程序

————————

当以gdb 方式启动gdb后,gdb会在PATH路径和当前目录中搜索的源文件。如要确认gdb是否读到源文件,可使用l或list命令,看看gdb是否能列出源代码。

在gdb中,运行程序使用r或是run命令。程序的运行,你有可能需要设置下面四方面的事。

1、程序运行参数。

set args 可指定运行时参数。(如:set args 10 20 30 40 50)

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

2、运行环境。

path

可设定程序的运行路径。

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

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

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

3、工作目录。

cd

相当于shell的cd命令。

pwd 显示当前的所在目录。

4、程序的输入输出。

info terminal 显示你程序用到的终端的模式。

使用重定向控制程序输出。如:run > outfile

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

调试已运行的程序

————————

两种方法:

1、在UNIX下用ps查看正在运行的程序的PID(进程ID),然后用gdb PID格式挂接正在运行的程序。

2、先用gdb 关联上源代码,并进行gdb,在gdb中用attach命令来挂接进程的PID。并用detach来取消挂接的进程。

暂停 / 恢复程序运行

—————————

调试程序中,暂停程序运行是必须的,GDB可以方便地暂停程序的运行。你可以设置程序的在哪行停住,在什么条件下停住,在收到什么信号时停往等等。以便于你查看运行时的变量,以及运行时的流程。

当进程被gdb停住时,你可以使用info program 来查看程序的是否在运行,进程号,被暂停的原因。

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

一、设置断点(BreakPoint)

我们用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

...可以是上述的参数,condition表示条件,在条件成立时停住。比如在循环境体中,可以设置break if i=100,表示当i为100时停住程序。

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

info breakpoints [n]

info break [n]

二、设置观察点(WatchPoint)

观察点一般来观察某个表达式(变量也是一种表达式)的值是否有变化了,如果有变化,马上停住程序。我们有下面的几种方法来设置观察点:

watch

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

rwatch

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

awatch

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

info watchpoints

列出当前所设置了的所有观察点。

三、设置捕捉点(CatchPoint)

你可设置捕捉点来补捉程序运行时的一些事件。如:载入共享库(动态链接库)或是C++的异常。设置捕捉点的格式为:

catch

当event发生时,停住程序。event可以是下面的内容:

1、throw 一个C++抛出的异常。(throw为关键字)

2、catch 一个C++捕捉到的异常。(catch为关键字)

3、exec 调用系统调用exec时。(exec为关键字,目前此功能只在HP-UX下有用)

4、fork 调用系统调用fork时。(fork为关键字,目前此功能只在HP-UX下有用)

5、vfork 调用系统调用vfork时。(vfork为关键字,目前此功能只在HP-UX下有用)

6、load 或 load 载入共享库(动态链接库)时。(load为关键字,目前此功能只在

HP-UX下有用)

7、unload 或 unload 卸载共享库(动态链接库)时。(unload为关键字,目前此功能只在HP-UX下有用)

tcatch

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

四、维护停止点

上面说了如何设置程序的停止点,GDB中的停止点也就是上述的三类。在GDB中,如果你觉得已定义好的停止点没有用了,你可以使用delete、clear、disable、enable这几个命令来进行维护。

clear

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

clear

clear

清除所有设置在函数上的停止点。

clear

clear

清除所有设置在指定行上的停止点。

delete [breakpoints] [range...]

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

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

disable [breakpoints] [range...]

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

enable [breakpoints] [range...]

enable所指定的停止点,breakpoints为停止点号。

enable [breakpoints] once range...

enable所指定的停止点一次,当程序停止后,该停止点马上被GDB自动disable。

enable [breakpoints] delete range...

enable所指定的停止点一次,当程序停止后,该停止点马上被GDB自动删除。

五、停止条件维护

前面在说到设置断点时,我们提到过可以设置一个条件,当条件成立时,程序自动停止,这是一个非常强大的功能,这里,我想专门说说这个条件的相关维护命令。一般来说,为断点设置一个条件,我们使用if关键词,后面跟其断点条件。并且,条件设置好后,我们可以用condition命令来修改断点的条件。(只有break 和watch命令支持if,catch目前暂不支持if)

condition

修改断点号为bnum的停止条件为expression。

condition

清除断点号为bnum的停止条件。

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

ignore

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

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

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

commands [bnum]

... command-list ...

end

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

例如:

break foo if x>0

commands

printf "x is %d\n",x

continue

end

断点设置在函数foo中,断点条件是x>0,如果程序被断住后,也就是,一旦x的值在foo函数中大于0,GDB会自动打印出x的值,并继续运行程序。

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

七、断点菜单

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

(gdb) b String::after

[0] cancel

[1] all

[2] file:https://www.wendangku.net/doc/1610357752.html,; line number:867

[3] file:https://www.wendangku.net/doc/1610357752.html,; line number:860

[4] file:https://www.wendangku.net/doc/1610357752.html,; line number:875

[5] file:https://www.wendangku.net/doc/1610357752.html,; line number:853

[6] file:https://www.wendangku.net/doc/1610357752.html,; line number:846

[7] file:https://www.wendangku.net/doc/1610357752.html,; line number:735

> 2 4 6

Breakpoint 1 at 0xb26c: file https://www.wendangku.net/doc/1610357752.html,, line 867.

Breakpoint 2 at 0xb344: file https://www.wendangku.net/doc/1610357752.html,, line 875.

Breakpoint 3 at 0xafcc: file https://www.wendangku.net/doc/1610357752.html,, 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

单步跟踪,如果有函数调用,他会进入该函数。进入函数的前提是,此函数被编译有debug信息。很像VC等工具中的step in。后面可以加count也可以不加,不加表示一条条地执行,加表示执行后面的count条指令,然后再停住。

next

同样单步跟踪,如果有函数调用,他不会进入该函数。很像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)

信号是一种软中断,是一种处理异步事件的方法。一般来说,操作系统都支持许多信号。尤其是UNIX,比较重要应用程序一般都会处理信号。UNIX定义了许多信号,比如SIGINT表示中断字符信号,也就是Ctrl+C 的信号,SIGBUS表示硬件故障的信号;SIGCHLD表示子进程状态改变信号;SIGKILL表示终止程序运行的信号,等等。信号量编程是UNIX下非常重要的一种技术。

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

handle

在GDB中定义一个信号处理。信号可以以SIG开头或不以SIG开头,可以用定义一个要处理信号的范围(如:SIGIO-SIGKILL,表示处理从SIGIO信号到SIGKILL的信号,其中包括SIGIO,SIGIOT,SIGKILL三个信号),也可以使用关键字all来标明要处理所有的信号。一旦被调试的程序接收到信号,运行程序马上会被GDB停住,以供调试。其可以是以下几种关键字的一个或多个。

nostop

当被调试的程序收到信号时,GDB不会停住程序的运行,但会打出消息告诉你收到这种信号。

stop

当被调试的程序收到信号时,GDB会停住你的程序。

print

当被调试的程序收到信号时,GDB会显示出一条信息。

noprint

当被调试的程序收到信号时,GDB不会告诉你收到信号的信息。

pass

noignore

当被调试的程序收到信号时,GDB不处理信号。这表示,GDB会把这个信号交给被调试程序会处理。

nopass

ignore

当被调试的程序收到信号时,GDB不会让被调试程序来处理这个信号。

info signals

info handle

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

十、线程(Thread Stops)

如果你程序是多线程的话,你可以定义你的断点是否在所有的线程上,或是在某个特定的线程。GDB很容易帮你完成这一工作。

break thread

break thread if ...

linespec指定了断点设置在的源程序的行号。threadno指定了线程的ID,注意,这个ID是GDB 分配的,你可以通过“info threads”命令来查看正在运行程序中的线程信息。如果你不指定thread 则表示你的断点设在所有线程上面。你还可以为某线程指定断点条件。如:

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

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

查看栈信息

—————

当程序被停住了,你需要做的第一件事就是查看程序是在哪里停住的。当你的程序调用了一个函数,函数的地址,函数参数,函数内的局部变量都会被压入“栈”(Stack)中。你可以用GDB命令来查看当前的栈中的信息。

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

backtrace

bt

打印当前的函数调用栈的所有信息。如:

(gdb) bt

#0 func (n=250) at tst.c:6

#1 0x08048524 in main (argc=1, argv=0xbffff674) at tst.c:30

#2 0x400409ed in __libc_start_main () from /lib/libc.so.6

从上可以看出函数的调用栈信息:__libc_start_main --> main() --> func()

backtrace

bt

n是一个正整数,表示只打印栈顶上n层的栈信息。

backtrace <-n>

bt <-n>

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

如果你要查看某一层的信息,你需要在切换当前的栈,一般来说,程序停止时,最顶层的栈就是当前栈,如果你要查看栈下面层的详细信息,首先要做的是切换当前栈。

frame

f

n是一个从0开始的整数,是栈中的层编号。比如:frame 0,表示栈顶,frame 1,表示栈的第二层。

up

表示向栈的上面移动n层,可以不打n,表示向上移动一层。

down

表示向栈的下面移动n层,可以不打n,表示向下移动一层。

上面的命令,都会打印出移动到的栈层的信息。如果你不想让其打出信息。你可以使用这三个命令:

select-frame 对应于 frame 命令。

up-silently 对应于 up 命令。

down-silently 对应于 down 命令。

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

frame 或 f

会打印出这些信息:栈的层编号,当前的函数名,函数参数值,函数所在文件及行号,函数执行到的语句。

info frame

info f

这个命令会打印出更为详细的当前栈层的信息,只不过,大多数都是运行时的内内地址。比如:函数地址,调用函数的地址,被调用函数的地址,目前的函数是由什么样的程序语言写成的、函数参数地址及值、局部变量的地址等等。如:

(gdb) info f

Stack level 0, frame at 0xbffff5d4:

eip = 0x804845d in func (tst.c:6); saved eip 0x8048524

called by frame at 0xbffff60c

source language c.

Arglist at 0xbffff5d4, args: n=250

Locals at 0xbffff5d4, Previous frame's sp is 0x0

Saved registers:

ebp at 0xbffff5d4, eip at 0xbffff5d8

info args

打印出当前函数的参数名及其值。

info locals

打印出当前函数中所有局部变量及其值。

info catch

打印出当前的函数中的异常处理信息。

查看源程序

—————

一、显示源代码

GDB 可以打印出所调试程序的源代码,当然,在程序编译时一定要加上-g的参数,把源程序信息编译到执行文件中。不然就看不到源程序了。当程序停下来以后,GDB会报告程序停在了那个文件的第几行上。你可以用list命令来打印程序的源代码。还是来看一看查看源代码的GDB命令吧。

list

显示程序第linenum行的周围的源程序。

list

显示函数名为function的函数的源程序。

list

显示当前行后面的源程序。

list -

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

一般是打印当前行的上5行和下5行,如果显示函数是是上2行下8行,默认是10行,当然,你也可以定制显示的范围,使用下面命令可以设置一次显示源程序的行数。

set listsize

设置一次显示源代码的行数。

show listsize

查看当前listsize的设置。

list命令还有下面的用法:

list ,

显示从first行到last行之间的源代码。

list ,

显示从当前行到last行之间的源代码。

list +

往后显示源代码。

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

行号。

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

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

哪个文件的哪一行。

函数名。

哪个文件中的哪个函数。

<*address> 程序运行时的语句在内存中的地址。

二、搜索源代码

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

forward-search

search

向前面搜索。

reverse-search

全部搜索。

其中,就是正则表达式,也主一个字符串的匹配模式,关于正则表达式,我就不在这里讲了,还请各位查看相关资料。

三、指定源文件的路径

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

directory

dir

加一个源文件路径到当前路径的前面。如果你要指定多个路径,UNIX下你可以使用“:”,Windows 下你可以使用“;”。

directory

清除所有的自定义的源文件搜索路径信息。

show directories

显示定义了的源文件搜索路径。

四、源代码的内存

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

(gdb) info line tst.c:func

Line 5 of "tst.c" starts at address 0x8048456 and ends at 0x804845d .

还有一个命令(disassemble)你可以查看源程序的当前执行时的机器码,这个命令会把目前内存中的指令dump出来。如下面的示例表示查看函数func的汇编代码。

(gdb) disassemble func

Dump of assembler code for function func:

0x8048450 : push %ebp

0x8048451 : mov %esp,%ebp

0x8048453 : sub $0x18,%esp

0x8048456 : movl $0x0,0xfffffffc(%ebp)

0x804845d : movl $0x1,0xfffffff8(%ebp)

0x8048464 : mov 0xfffffff8(%ebp),%eax

0x8048467 : cmp 0x8(%ebp),%eax

0x804846a : jle 0x8048470

0x804846c : jmp 0x8048480

0x804846e : mov %esi,%esi

0x8048470 : mov 0xfffffff8(%ebp),%eax

0x8048473 : add %eax,0xfffffffc(%ebp)

0x8048476 : incl 0xfffffff8(%ebp)

0x8048479 : jmp 0x8048464

0x804847b : nop

0x804847c : lea 0x0(%esi,1),%esi

0x8048480 : mov 0xfffffffc(%ebp),%edx

0x8048483 : mov %edx,%eax

0x8048485 : jmp 0x8048487

0x8048487 : mov %ebp,%esp

0x8048489 : pop %ebp

0x804848a : ret

End of assembler dump.

查看运行时数据

———————

在你调试程序时,当程序被停住时,你可以使用print命令(简写命令为p),或是同义命令inspect 来查看当前程序的运行数据。print命令的格式是:

print

print /

是表达式,是你所调试的程序的语言的表达式(GDB可以调试多种编程语言),是输出的格式,比如,如果要把表达式按16进制的格式输出,那么就是/x。

一、表达式

print和许多GDB的命令一样,可以接受一个表达式,GDB会根据当前的程序运行的数据来计算这个表达式,既然是表达式,那么就可以是当前程序运行中的const常量、变量、函数等内容。可惜的是GDB 不能使用你在程序中所定义的宏。

表达式的语法应该是当前所调试的语言的语法,由于C/C++是一种大众型的语言,所以,本文中的例子都是关于C/C++的。(而关于用GDB调试其它语言的章节,我将在后面介绍)

在表达式中,有几种GDB所支持的操作符,它们可以用在任何一种语言中。

@

是一个和数组有关的操作符,在后面会有更详细的说明。

::

指定一个在文件或是一个函数中的变量。

{}

表示一个指向内存地址的类型为type的一个对象。

二、程序变量

在GDB中,你可以随时查看以下三种变量的值:

1、全局变量(所有文件可见的)

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

3、局部变量(当前Scope可见的)

如果你的局部变量和全局变量发生冲突(也就是重名),一般情况下是局部变量会隐藏全局变量,也就是说,如果一个全局变量和一个函数中的局部变量同名时,如果当前停止点在函数中,用print显示出的变量的值会是函数中的局部变量的值。如果此时你想查看全局变量的值时,你可以使用“::”操作符:

file::variable

function::variable

可以通过这种形式指定你所想查看的变量,是哪个文件中的或是哪个函数中的。例如,查看文件f2.c 中的全局变量x的值:

gdb) p 'f2.c'::x

当然,“::”操作符会和C++中的发生冲突,GDB能自动识别“::” 是否C++的操作符,所以你不必担心在调试C++程序时会出现异常。

另外,需要注意的是,如果你的程序编译时开启了优化选项,那么在用GDB调试被优化过的程序时,可能会发生某些变量不能访问,或是取值错误码的情况。这个是很正常的,因为优化程序会删改你的程序,整理你程序的语句顺序,剔除一些无意义的变量等,所以在GDB调试这种程序时,运行时的指令和你所编写指令就有不一样,也就会出现你所想象不到的结果。对付这种情况时,需要在编译程序时关闭编译优化。一般来说,几乎所有的编译器都支持编译优化的开关,例如,GNU的C/C++编译器GCC,你可以使用“-gstabs”选项来解决这个问题。关于编译器的参数,还请查看编译器的使用说明文档。

三、数组

有时候,你需要查看一段连续的内存空间的值。比如数组的一段,或是动态分配的数据的大小。你可以使用GDB的“@”操作符,“@”的左边是第一个内存的地址的值,“@”的右边则你你想查看内存的长度。例如,你的程序中有这样的语句:

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

GDB基本使用方法

GDB基本使用方法 GDB是用来调试用户态程序的一款工具,可以追踪程序运行轨迹,打出调用栈,寄存器内容,查看内存等等 首先在编译时,我们必须要把调试信息加到可执行文件中。使用编译器(cc/gcc/g++)的-g 参数可以做到这一点。如果没有-g,你将看不见程序的函数名、变量名,所代替的全是运行时的内存地址。 启动GDB 直接找到gdb的路径执行就ok,进入GDB后可以输入help命令查看帮助信息 加载可执行文件启动 gdb executable-file set args 参数列表 以上两步等同于 gdb –args executable-file 参数列表 run或者start都可以启动调试 多用于调试启动阶段就异常的程序 调试正在运行的程序 以下三种形式都可以attach到正在运行的程序上调试 ps -ef | grep http www-data 24470 1 0 Jan17 ? 00:00:14 /usr/sbin/lighttpd gdb attach 24470 gdb --pid 24470 gdb -p 24470 设置断点 break -- Set breakpoint at specified line or function b func1 break func1 设置在func1处 b file:line 设置在文件的第几行处 b *0x指令地址设置在具体的某条汇编指令处 设置断点后,代码执行到func1处会被断住,方便我们查看当时的信息 打印调用栈 backtrace bt 如果你要查看栈下面层的详细信息 frame 栈中的层编号 查看所有断点 info break 删除断点 delete 断点号 如果不加断点号为删除全部断点 禁用断点 disable 断点号 启用断点

如何高效使用GDB断点

在gdb中,断点通常有三种形式 断点(BreakPoint): 在代码的指定位置中断,这个是我们用得最多的一种。设置断点的命令是break,它通常有如下方式: 可以通过info breakpoints [n]命令查看当前断点信息。此外,还有如下几个配套的常用命令: 观察点(WatchPoint): 在变量读、写或变化时中断,这类方式常用来定位bug。

捕捉点(CatchPoint): 捕捉点用来补捉程序运行时的一些事件。如:载入共享库(动态链接库)、C++的异常等。通常也是用来定位bug。 捕捉点的命令格式是:catch ,event可以是下面的内容 自动删除。 捕捉点信息的查看方式和代码断点的命令是一样的,这里就不多介绍了。 在特定线程中中断 你可以定义你的断点是否在所有的线程上,或是在某个特定的线程。GDB很容易帮你完成这一工作。

break thread break thread if ... linespec指定了断点设置在的源程序的行号。threadno指定了线程的ID,注意,这个ID是GDB分配的,你可以通过"info threads"命令来查看正在运行程序中的线程信息。如果你不指定thread 则表示你的断点设在所有线程上面。你还可以为某线程指定断点条件。如: (gdb) break frik.c:13 thread 28 if bartab > lim 当你的程序被GDB停住时,所有的运行线程都会被停住。这方便你你查看运行程序的总体情况。而在你恢复程序运行时,所有的线程也会被恢复运行。那怕是主进程在被单步调试时。 在特定条件下中断 条件断点的一种特殊场景是在断点命中指定次数后停下来。事实上每个断点都有一个 ignore count, 他是一个正整数。通常情况下它的值为0,所以看不出来它的存在。但是如果它是一个非0值, 那么它将在每次命中后都将 count 减 1,直到它为 0. ignore bnum count 恢复程序运行和单步调试 在gdb中,和调试步进相关的命令主要有如下几条: 参考资料

实例—使用gdb调试器

2.4 实例—使用gdb调试器 1.编写实例程序gcctest.c,见2.2小节的开头部分 2.编译 3.启动GDB,执行程序 启动gdb,进入gdb调试环境,可以使用gdb的命令对程序进行调试。 [root@localhost gdbtest txt]# gdb //启动gdb GNU gdb Fedora (6.8-27.el5) Copyright (C) 2008 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later 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 "i386-redhat-linux-gnu". (gdb) run gcctest //在gdb中,运行程序使用r或是run命令,注意,gcctest没有调试信息Starting program: gcctest No executable file specified. Use the "file" or "exec-file" command. //要使用file或exec-file命令指出要运行的程序 (gdb) file gcctest //使用file命令指出要运行的程序gcctest,注意,对gdb命令也可以使用Tab gcctest gcctest.c gcctestg (gdb) file gcctest //使用file命令指出要运行的程序gcctest Reading symbols from /root/Desktop/gdbtest txt/gcctest...(no debugging symbols found)...done. (gdb) r //在gdb中,运行程序使用r或是run命令 Starting program: /root/Desktop/gdbtest txt/gcctest gcctest (no debugging symbols found) (no debugging symbols found) (no debugging symbols found) hello in main hello 1 hello 2 sum=54125560035401396161080590579269632.000000 Program exited with code 057. (gdb) file gcctestg //使用file命令指出要运行的程序gcctestg Reading symbols from /root/Desktop/gdbtest txt/gcctestg...done. (gdb) r //在gdb中,运行程序使用r或是run命令 Starting program: /root/Desktop/gdbtest txt/gcctestg gcctest hello in main hello 1 hello 2 sum=54125560035401396161080590579269632.000000 Program exited with code 057. (gdb) q //使用q或是quit命令退出gdb [root@localhost gdbtest txt]# 4.GDB命令简介

实验一LinuxC编程工具GCC和GDB

淮海工学院计算机工程学 实验报告书 评语: 成绩:指导教师: 批阅时间:年月

实验目的与要求 1. 掌握Linux C 开发过程中的基本概念; 2. 掌握如GCC GDB等开发工具的使用。 二、实验内容 1. 将参考代码录入到文件中,编译执行后发现结果与预期不一致,请使用GDE调试, 完成字符串反序输出功能。 三、参考源代码 #include <> #include <> #include <> int reverse_str(char *string); int main (void) { char string[] = "Linux C Tools : GCC and GDB"; printf ("The original string is %s \n", string); reverse_str (string); } int reverse_str (char *str) { char *new_str; int i, size; size = strlen (str); if((new_str = (char *) malloc (size + 1)) == NULL) { return -1; } for (i = 0; i < size; i++) new_str[size - i] = str[i]; new_str[size+1] = ' '; printf("The reversed string is %s\n",new_str); free(new_str); return 0 ; } 四、实验步骤 步骤1. 编辑源代码 mkdir test1 cd test1 gedit (1) 使用gedit 编辑器,建议课外学习vim; (2) 分析代码中语句功能。 步骤 2. 编译源代码

Ubuntu下Vim GCC GDB安装及使用

Ubuntu下Vim+GCC+GDB安装及使用 一)安装 vim)打开命令行运行sudo apt-get install vim,并按提示输入管理员密码。 gcc+gdb)输入命令行运行 sudo apt-get install build-essential build-essential包含gcc和gdb等工具,是C语言的开发包。 安装完了可以执行 gcc --version 的命令来查看版本,输出如下: gcc (Ubuntu 4.8.2-19ubuntu1) 4.8.2 Copyright (C) 2013 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 则表明安装好了。 二)常用编译命令选项 假设源程序文件名为test.c。 1. 无选项编译链接 用法:#gcc test.c 作用:将test.c预处理、汇编、编译并链接形成可执行文件。这里未指定输出文件,默认输出为a.out。 2. 选项 -o 用法:#gcc test.c -o test 作用:将test.c预处理、汇编、编译并链接形成可执行文件test。-o选项用来指定输出文件的文件名。 3. 选项 -E 用法:#gcc -E test.c -o test.i 作用:将test.c预处理输出test.i文件。 4. 选项 -S 用法:#gcc -S test.i 作用:将预处理输出文件test.i汇编成test.s文件。 5. 选项 -c 用法:#gcc -c test.s 作用:将汇编输出文件test.s编译输出test.o文件。 6. 无选项链接 用法:#gcc test.o -o test

GDB常用命令

附录A:GDB使用 1.基本命令 1)进入GDB #gdb test test是要调试的程序,由gcctest.c -g -o test生成。进入后提示符变为(gdb) 。 2)查看源码(gdb) l 源码会进行行号提示。 如果需要查看在其他文件中定义的函数,在l后加上函数名即可定位到这个函数的定义及查看附近的其他源码。或者:使用断点或单步运行,到某个函数处使用s进入这个函数。 3)设置断点(gdb) b 6 这样会在运行到源码第6行时停止,可以查看变量的值、堆栈情况等;这个行号是gdb的行号。 4)查看断点处情况(gdb) info b 可以键入"info b"来查看断点处情况,可以设置多个断点; 5)运行代码(gdb) r 6)显示变量值(gdb) p n 在程序暂停时,键入"p 变量名"(print)即可; GDB在显示变量值时都会在对应值之前加上"$N"标记,它是当前变量值的引用标记,以后若想再次引用此变量,就可以直接写作"$N",而无需写冗长的变量名; 7)观察变量(gdb) watch n 在某一循环处,往往希望能够观察一个变量的变化情况,这时就可以键入命令"watch"来观察变量的变化情况,GDB在"n"设置了观察点; 8)单步运行(gdb) n 9)程序继续运行(gdb) c 使程序继续往下运行,直到再次遇到断点或程序结束; 10)退出GDB (gdb) q 2.断点调试 break+设置断点的行号,break n,在n行处设置断点; tbreak+行号或函数名,tbreak n/func,设置临时断点,到达后被自动删除; break+filename+行号, break main.c:10,用于在指定文件对应行设置断

GDB命令大全

GDB命令大全 GDB的使用 当程序出错并产生core 时 快速定位出错函数的办法 gdb 程序名 core文件名(一般是core,也可能是core.xxxx) 调试程序使用的键 r run 运行.程序还没有运行前使用 c cuntinue 继续运行。运行中断后继续运行 q 退出 kill 终止调试的程序 h help 帮助 命令补全功能 step 跟入函数 next 不跟入函数

b breakpoint 设置断点。 用法: b 函数名对此函数进行中断 b 文件名:行号对此文件中指定行中断.如果是当前文件,那么文件名与:号可以省略 看当前断点数使用info break.禁止断点disable 断点号.删除delete 断点号. l list 列出代码行。一次列10 行。连接使用list将会滚动显示. 也可以在list 后面跟上文件名:行号 watch 观察一个变量的值。每次中断时都会显示这个变量的值 p print 打印一个变量的值。与watch不同的是print只显示一次 这里在顺便说说如何改变一个 value. 当你下指令 p 的时候,例如你用 p b, 这时候你会看到 b 的 value, 也就是上面的 $1 = 15. 你也同样可以用 p 来改变一个 value, 例如下指令 p b = 100 试试看,

这时候你会发现, b 的 value 就变成 100 了:$1 = 100. 网上抄录 基本的使用方法简介 前言 程序代码中的错误可分为数类,除了最容易除错的语法错误,编译程序会告诉你错误所在外,大部分的错误都可以归类为执行时错误。GDB 的功能便是寻找执行时错误。如果没有除错程序,我们只能在程序中加入输出变量值的指令来了解程序执行的状态。有了 GDB 除错程序,我们可以设定在任何地方停止程序的执行,然后可以随意检视变量值及更动变量,并逐行执行程序。 一个除错程序执行的流程通常是这样的: 1. 进入除错程序并指定可执行文件。 2. 指定程序代码所在目录。 3. 设定断点后执行程序。 4. 程序于断点中断后,可以 (1)检视程序执行状态;检视变量值或变更变量值 (2) 逐步执行程序,或是全速执行程序到下一个断点或是到程序结束为止。 5. 离开除错程序。 以下将分为下列数项分别介绍:

ARM汇编指令调试方法

ARM汇编指令调试方法 学习ARM 汇编时,少不了对ARM 汇编指令的调试。作为支持多语言的 调试器,gdb 自然是较好的选择。调试器工作时,一般通过修改代码段的内容 构造trap 软中断指令,实现程序的暂停和程序执行状态的监控。为了在x86 平 台上执行ARM 指令,可以使用qemu 模拟器执行ARM 汇编指令。一、准备ARM 汇编程序首先,我们构造一段简单的ARM 汇编程序作为测试代码 main.s。 .globl _start_start:mov R0,#0swi0x00901 以上汇编指令完成了0 号系统调用exit 的调用。mov 指令将系统调用号传入寄存器R0,然后使用0x00901 软中断 陷入系统调用。 为了运行ARM 汇编代码,需要使用交叉编译器arm-linux-gcc 对ARM 汇编 代码进行编译。下载交叉编译器安装完毕后,对ARM 汇编代码进行编译。 arm-linux-gcc main.s -o main -nostdlib 编译选项-nostdlib 表示不使用任何运行时库文件,编译生成的可执行文件main 只能在ARM 体系结构的系统上运行。二、编译安装qemu 模拟器为了x86 的Linux 系统内运行ARM 体系结构的可 执行程序,需要安装qemu 模拟器。 首先下载qemu 源码,然后保证系统已经安装了flex 和bison。 编译安装qemu。 ./configure --prefix=/usrsudo make && make install 然后使用qemu 的ARM 模拟器执行ARM 程序。 qemu ./main 三、编译安装arm-gdb 为了调试ARM 程序,需要使用gdb 的源码编译生成arm-gdb。 首先下载gdb 源代码,编译安装。

linux环境下的调试命令

Linux下GDB调试命令_1 2008-11-21 18:39 GDB是GNU开源组织发布的一个强大的UNIX下的程序调试工具,不过现在在Linux下也可以用了。它使你能在程序运行时观察程和内存的使用情况。Linux不比Windows,没有那么多方便的图形界面方式的,像.Net、Eclipse等IDE的调试器。但上天逼着我在Li 软件,用了一段时间,你会发现GDB这个调试工具一点不比其它的差,所谓“寸有所长,尺有所短”就是这个道理。 一般来说,我可以用GDB来: ?加载程序 ?设置监视点、断点、入口条件等 ?动态的改变你程序的执行环境 ?单步调试、追踪 一、加载文件 启动GDB的方法有以下几种: 1、>gdb [exe] 2、>gdb pid [pid] GDB启动时,可以加上一些GDB的启动开关,详细的开关可以用gdb -help查看。我在下面只例举一些比较常用的参数: -symbols -s 从指定文件中读取符号表。 -se file 从指定文件中读取符号表信息,并把他用在可执行文件中。 -core -c 调试时core dump的core文件。 -directory -d 加入一个源文件的搜索路径。默认搜索路径是环境变量中PATH所定义的路径。 二、运行命令 当以gdb 方式启动gdb后,gdb会在PATH路径和当前目录中搜索的源文件。 在gdb中,运行程序使用r或是run命令。程序的运行,你有可能需要设置下面四方面的事。 1、程序运行参数。 set args 可指定运行时参数。(如:set args 10 20 30 40 50) show args 命令可以查看设置好的运行参数。 2、运行环境。 path 可设定程序的运行路径。 show paths 查看程序的运行路径。 set environment varname [=value] 设置环境变量。如:set env USER=hchen show environment [varname] 查看环境变量。 3、工作目录。 cd 相当于shell的cd命令。 pwd 显示当前的所在目录。 4、程序的输入输出。

GDB调试及实例

GDB调试及实例 一:列文件清单 1.List (gdb) list line1,line2 二:执行程序 要想运行准备调试的程序,可使用run命令,在它后面可以跟随发给该程序的任何参数,包括标准输入和标准输出说明符(<和>)和外壳通配符(*、?、[、])在内。 如果你使用不带参数的run命令,gdb就再次使用你给予前一条run命令的参数,这是很有用的。 利用set args 命令就可以修改发送给程序的参数,而使用show args 命令就可以查看其缺省参数的列表。 (gdb)set args –b –x (gdb) show args backtrace命令为堆栈提供向后跟踪功能。 Backtrace 命令产生一张列表,包含着从最近的过程开始的所以有效过程和调用这些过程的参数。 三:显示数据 利用print 命令可以检查各个变量的值。 (gdb) print p (p为变量名) whatis 命令可以显示某个变量的类型 (gdb) whatis p type = int * print 是gdb的一个功能很强的命令,利用它可以显示被调试的语言中任何有效的表达式。表达式除了包含你程序中的变量外,还可以包含以下内容: l 对程序中函数的调用 (gdb) print find_entry(1,0) l 数据结构和其他复杂对象 (gdb) print *table_start $8={e=reference=’\000’,location=0x0,next=0x0} l 值的历史成分 (gdb)print $1 ($1为历史记录变量,在以后可以直接引用$1 的值) l 人为数组 人为数组提供了一种去显示存储器块(数组节或动态分配的存储区)内容的方法。早期的调试程序没有很好的方法将任意的指针换成一个数组。就像对待参数一样,让我们查看内存中在变量h后面的10个整数,一个动态数组的语法如下所示: base@length 因此,要想显示在h后面的10个元素,可以使用h@10: (gdb)print h@10 $13=(-1,345,23,-234,0,0,0,98,345,10)

GDB基本命令

1. 本文介绍使用gdb调试程序的常用命令。 主要内容: [简介] [举例] [其他] [简介] ============= GDB是GNU开源组织发布的一个强大的UNIX下的程序调试工具。如果你是在UNIX平台下做软件,你会发现GDB这个调试工具有比VC、BCB的图形化调试器更强大的功能。同时GDB也具有例如ddd这样的图形化的调试端。 一般来说,GDB主要完成下面四个方面的功能: (1)启动你的程序,可以按照你的自定义的要求随心所欲的运行程序。 (2)可让被调试的程序在你所指定的调置的断点处停住。(断点可以是条件表达式) (3)当程序被停住时,可以检查此时你的程序中所发生的事。 (4)动态的改变你程序的执行环境。 [举例] ============= *启动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通配符(*、?、[、])在内。

LINUX gdb调试命令手册

常用的gdb命令 backtrace 显示程序中的当前位置和表示如何到达当前位置的栈跟踪(同义词:where)breakpoint 在程序中设置一个断点 cd 改变当前工作目录 clear 删除刚才停止处的断点 commands 命中断点时,列出将要执行的命令 continue 从断点开始继续执行 delete 删除一个断点或监测点;也可与其他命令一起使用 display 程序停止时显示变量和表达时 down 下移栈帧,使得另一个函数成为当前函数 frame 选择下一条continue命令的帧 info 显示与该程序有关的各种信息 jump 在源程序中的另一点开始运行 kill 异常终止在gdb 控制下运行的程序 list 列出相应于正在执行的程序的原文件内容 next 执行下一个源程序行,从而执行其整体中的一个函数 print 显示变量或表达式的值 pwd 显示当前工作目录 pype 显示一个数据结构(如一个结构或C++类)的内容 quit 退出gdb reverse-search 在源文件中反向搜索正规表达式 run 执行该程序 search 在源文件中搜索正规表达式 set variable 给变量赋值 signal 将一个信号发送到正在运行的进程 step 执行下一个源程序行,必要时进入下一个函数 undisplay display命令的反命令,不要显示表达式 until 结束当前循环 up 上移栈帧,使另一函数成为当前函数 watch 在程序中设置一个监测点(即数据断点) whatis 显示变量或函数类型

GDB命令分类详解 一:列文件清单 (2) 二:执行程序 (2) 三:显示数据 (2) 四:断点(breakpoint) (3) 五.断点的管理 (3) 六.变量的检查和赋值 (4) 七.单步执行 (4) 八.函数的调用 (4) 九.机器语言工具 (4) 十.信号 (4) 十一.原文件的搜索 (5) 十二. UNIX接口 (5) 十三. 命令的历史 (5) 十四. GDB帮助 (5) 十五. GDB多线程 (6) 十六. GDB使用范例 (7) 一:列文件清单 1.List (gdb) list line1,line2 二:执行程序 要想运行准备调试的程序,可使用run命令,在它后面可以跟随发给该程序的任何参数,包括标准输入和标准输出说明符(<和>)和外壳通配符(*、?、[、])在内。 如果你使用不带参数的run命令,gdb就再次使用你给予前一条run命令的参数,这是很有用的。 利用set args 命令就可以修改发送给程序的参数,而使用show args 命令就可以查看其缺省参数的列表。 (gdb)set args –b –x (gdb) show args backtrace命令为堆栈提供向后跟踪功能。 Backtrace 命令产生一张列表,包含着从最近的过程开始的所以有效过程和调用这些过程的参数。 三:显示数据 利用print 命令可以检查各个变量的值。 (gdb) print p (p为变量名) whatis命令可以显示某个变量的类型 (gdb) whatis p type = int * print 是gdb的一个功能很强的命令,利用它可以显示被调试的语言中任何有效的表达式。表达式除了包含你程序中的变量外,还可以包含以下内容:

用GDB调试程序--调试器GDB常用功能

一,GDB调试器简介 GDB是Linux下的常用调试器,主要用于调试源代码、调试运行中的进程和查看core dump文件。Linux下的调试器主要有gdb、cgdb、ddd、eclipse。GDB调试器的运行速度快、能够进行源代码同步显示。 使用-tui 选项开启gdb命令输入和源代码的分屏显示,tui即Terminal User Interface。 二,GDB常用调试命令 a)调试可执行文件 以源代码为/home/zebra/目录下的test.c文件产生的可执行文件test为例(可执行文件使用gcc进行编译,并使用-g选项以产生调试信息),进行命令的说明(详细源代码参见第三部分:三,调试实例分析 )。 gdb调试源代码流程: 1,开启gdb程序,即运行如下命令:gdb -q (-q用以使得gdb不输出gdb程序的版本等信息)2,指定调试的二进制文件:file test 3,list查看源代码 4,设定断点breakpoint main breakpoint sub 上述分别在main函数和sub函数处设定了断点。 断点可以设置在任意已知源代码文件的某一行,某一个函数,同时可以指定是设置在哪个/哪些线程上(见下边描述)。 5,运行可执行文件: run 6,这样程序会运行到断点处停止下来,gdb会打印当前断点的信息。 7,使用s 或者n进行单步调试。 s即step,n即next都是执行一条语句,然后停下来。 如果想执行一条汇编语句,则可以使用si ,ni,即step instruction,next instruction。 8,bt命令查看当前的调用栈,bt即backtrace。 9,info frame查看函数帧信息。 10,frame n 进入某个函数帧(编号为n) 11,info 命令可以对当前的函数帧的寄存器、局部变量、函数的参数进行查看。 info register;info local;info args。 12,disassemble对当前函数对应的二进制进行反汇编。 13,x/nfu address 查看内存其中address是内存开始的地址,从该地址向高地址增加, x是examinate的缩写,n表示重复次数,f表示输出格式,u表示内存大小的单位(默认是字,即4个字节)。 一般我都用x/nx address,即打印n个从address开始的内存,每个是4字节,以十六进制打印。14,continue,执行至该函数退出 15,info threads,显示当前可调试的所有线程 16,thread ,切换当前调试的线程为指定ID的线程break File:LineNumber thread if x==y。 17,thread apply command让一个/多个/所有线程执行GDB的命令command。

linux软件开发之GCC,GDB用法篇

(转贴)linux 下的软件开发之GCC,GDB用法篇 -|tinylee 发表于 2005-8-22 1:02:00 在为Linux开发应用程序时,绝大多数情况下使用的都是C语言,因此几乎每一位Linux程序员面临的首要问题都是如何灵活运用C编译器。目前Linux下最常用的C语言编译器是GCC(GNU Compiler Collection),它是GNU项目中符合ANSI C标准的编译系统,能够编译用C、C++和Object C等语言编写的程序。GCC不仅功能非常强大,结构也异常灵活。最值得称道的一点就是它可以通过不同的前端模块来支持各种语言,如Java、Fortran、Pascal、Modula-3和Ada等。 开放、自由和灵活是Linux的魅力所在,而这一点在GCC上的体现就是程序员通过它能够更好地控制整个编译过程。在使用GCC编译程序时,编译过程可以被细分为四个阶段: ◆ 预处理(Pre-Processing) ◆ 编译(Compiling) ◆ 汇编(Assembling) ◆ 链接(Linking) Linux程序员可以根据自己的需要让GCC在编译的任何阶段结束,以便检查或使用编译器在该阶段的输出信息,或者对最后生成的二进制文件进行控制,以便通过加入不同数量和种类的调试代码来为今后的调试做好准备。和其它常用的编译器一样,GCC也提供了灵活而强大的代码优化功能,利用它可以生成执行效率更高的代码。 GCC提供了30多条警告信息和三个警告级别,使用它们有助于增强程序的稳定性和可移植性。此外,GCC 还对标准的C和C++语言进行了大量的扩展,提高程序的执行效率,有助于编译器进行代码优化,能够减轻编程的工作量。 GCC起步 在学习使用GCC之前,下面的这个例子能够帮助用户迅速理解GCC的工作原理,并将其立即运用到实际的项目开发中去。首先用熟悉的编辑器输入清单1所示的代码: 清单1:hello.c #i nclude int main(void) { printf ("Hello world, Linux programming!n"); return 0; } 然后执行下面的命令编译和运行这段程序: # gcc hello.c -o hello # ./hello Hello world, Linux programming! 从程序员的角度看,只需简单地执行一条GCC命令就可以了,但从编译器的角度来看,却需要完成一系列非常繁杂的工作。首先,GCC需要调用预处理程序cpp,由它负责展开在源文件中定义的宏,并向其中插入“#i nclude”语句所包含的内容;接着,GCC会调用ccl和as将处理后的源代码编译成目标代码;最后,GCC会调用链接程序ld,把生成的目标代码链接成一个可执行程序。 为了更好地理解GCC的工作过程,可以把上述编译过程分成几个步骤单独进行,并观察每步的运行结果。第一步是进行预编译,使用-E参数可以让GCC在预处理结束后停止编译过程:# gcc -E hello.c -o hello.i 此时若查看hello.cpp文件中的内容,会发现stdio.h的内容确实都插到文件里去了,而其它应当被预处理的宏定义也都做了相应的处理。下一步是将hello.i编译为目标代码,这可以通过使用-c参数来完成:

linux、GCC、GDB学习总结

1 虚拟机VMware6.5、RedHat安装及Linux基本命令 1.1 GCC、GDB的安装 虚拟将上安装RedHat后,在Linux环境下编辑和编译C\C++需要GCC、GDB编译,调试,Linux环境下输入gcc -v于gdb –v可以查看所装系统是否装有gcc与gdb。如果没有显示其所装版本,可以在Redhat 的RPMs包中找到相应版本的gcc与gdb的rmp安装文件。具体方法是vm->Removable Devices->CD\DVD->Connect. 把RedHat的镜像文件添加到use iso image file:下,点击OK,在VMware界面上出现以个光盘的标志双击后RedHat->RAMPS,选择要安装的GCC、与GDB文件。 注:不能直接用GCC变异C++文件,最好使用G++编译。

1.2 Linux基本命令 Linux常用命令全集:https://www.wendangku.net/doc/1610357752.html,/special/linuxcom/ 2 GCC、GDB的使用及基本指令 2.1 Linux环境下vi编辑器的基本使用方法 VMware界面上右键->open terminal 界面中输入vi 回车([jkl@localhost ~]$ vi) 在vi编辑器下输入要编辑的程序: #include int wib(int no1, int no2) { int result, diff; diff = no1 - no2; result = no1 / diff; return result; } int main(int argc, char *argv[]) { int value, div, result, i, total; value = 10; div = 6; total = 0; for(i = 0; i < 10; i++) { result = wib(value, div); total += result; div++; value--; } printf("%d wibed by %d equals %d\n", value, div, total); return 0; vi环境下输入模式与指令模式的切换键是Esc,当左下角出现--INSERT--时可以对程序进行编辑。按下Esc后,可以输入vi指令,会在窗口最下一行显示,

gdb基本命令

3.5.2 Gdb基本命令 Gdb的命令可以通过查看help进行查找,由于Gdb的命令很多,因此Gdb的he lp将其分成了很多种类(class),用户可以通过进一步查看相关class找到相应命令。如下所示: (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 … 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) help data Examining data. List of commands: call -- Call a function in the program delete display -- Cancel some expressions to be displayed when program stops delete mem -- Delete memory region

GDB使用说明书

GDB 是GNU开源组织发布的一个强大的UNIX下的程序调试工 具。或许 ,各位比较喜欢那种图形界面方式的,像VC、BCB等IDE的调试,但如 果你是在 UNIX平台下做软件,你会发现GDB这个调试工具有比VC、 BCB的图形化调试器更强大的功能。所谓“寸有所长,尺有所短” 就 是这个道理。 一般来说,GDB主要帮忙你完成下面四个方面的功能: 1、启动你的程序,可以按照你的自定义的要求随心所欲的运行程序。 2、可让被调试的程序在你所指定的调置的断点处停住。(断点可以是条件表达式) 3、当程序被停住时,可以检查此时你的程序中所发生的事。 4、动态的改变你程序的执行环境。 从上面看来,GDB和一般的调试工具没有什么两样,基本上也是完成 这些功能,不过在细节上,你会发现GDB这个调试工具的强大, 大家 可能比较习惯了图形化的调试工具,但有时候,命令行的调试工具却 有着图形化工具所不能完成的功能。让我们一一看来。

源程序:tst.c 1 #include 2 3 int func(int n) 4 { 5 int sum=0,i; 6 for(i=0; i 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

GDB调试

GDB是GNU开源组织发布的一个强大的UNIX下的程序调试工具。如果你是在 UNIX平台下做软件,你会发现GDB这个调试工具有比VC、 BCB的图形化调试器更强大的功能。同时GDB也具有例如ddd这样的图 形化的调试端。 一般来说,GDB主要完成下面四个方面的功能: (1)启动你的程序,可以按照你的自定义的要求随心所欲的运行程序。 (2)可让被调试的程序在你所指定的调置的断点处停住。(断点可以是条 件表达式) (3)当程序被停住时,可以检查此时你的程序中所发生的事。 (4)动态的改变你程序的执行环境。 兴趣是最好的老师,这里先整理总结一下在调试的过程中经常遇到的问题。带着这些问题进行学习和实践可以有助于加深印象 (1)如何打印变量的值?(print var) (2)如何打印变量的地址?(print &var) (3)如何打印地址的数据值?(print *address) (4)如何查看当前运行的文件和行?(backtrace) (5)如何查看指定文件的代码?(list file:N) (6)如何立即执行完当前的函数,但是并不是执行完整个应用程序?(finish) (7)如果程序是多文件的,怎样定位到指定文件的指定行或者函数?(list file:N) (8)如果循环次数很多,如何执行完当前的循环?(until) (9)多线程如何调试?(???)

[举例] ============= *启动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.如果你的程序是一个服务程序,那么你可以指定这个服务程序运行时的进程

相关文档