GDB初探

GDB概述

GDB是GNU开源组织发布的一个强大的UNIX下的程序调试工具。如果你是在UNIX平台下做软件,你会GDB这个调试工具来调试你的软件

编译时选项

一般来说GDB主要调试的是C/C++的程序。要调试C/C++的程序,在编译时,必须要把调试信息加到可执行文件中。使用编译器(cc/gcc/g++)的 -g 参数可以做到这一点。如:

> cc -g hello.c -o hello                         (C)

> g++ -g hello.cpp -o hello                     (C++)

如果没有-g,你将看不见程序的函数名、变量名,所代替的全是运行时的内存地址.

启动GDB 

1、gdb <program>

program也就是你的执行文件,可以带全路径

   2、gdb <program> core

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

3、gdb <program> <PID>

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

GDB启动时,可以加上一些GDB的启动开关

-symbols <file>

   -s <file>

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

-se file

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

   -core <file>

   -c <file>

   调试时core dump的core文件。

   -directory <directory>

   -d <directory>

   加入一个源文件的搜索路径。默认搜索路径是环境变量中PATH所定义的路径。

设置GDB到环境变量

1、设置程序运行参数

set args 可指定运行时参数。(如:set args 10 20 30 40 50)
show args 命令可以查看设置好的运行参数。

2、运行环境

path <dir> 可设定程序的运行路径。

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

set environment varname [=value] 设置环境变量。

如:set env USER=hchen

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

GDB常用命令

1、显示源代码行号: list/l

几种用法:

默认表示显示当前行号开始的程序

list <linenum>:显示程序第linenum行的周围的源程序。

list <linenum>:显示函数名为function的函数的源程序。

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

list <first>, <last>显示从first行到last行之间的源代码。
   list , <last>显示从当前行到last行之间的源代码。
   list +往后显示源代码。

(gdb) list

11      static void sub()

12      {

13          int *p=NULL;

14          int i;

15          for(i=0;i<10;i++);

16 

17          add(p);

18      }

一般默认是显示10行,使用下面命令可以设置一次显示源程序的行数。

set listsize <count>

show listsize查看当前listsize的设置。

(gdb) set listsize 15

(gdb) show listsize

Number of source lines gdb will list by default is 15.

2、设置断点:break/b <function>;b <filenam>:<line>

break <function> 

到指定函数停住

break <filenam>:<line>

到指定文件的line行停住

break <...> if <condition>

<...>可以是上述的参数: <function> or <line>,condition表示条件,在条件成立时停住。

(gdb) b sub

Breakpoint 1 at 0x80483ee: file debug_core.c, line 13.

(gdb) b debug_core.c:17

Breakpoint 2 at 0x8048408: file debug_core.c, line 17.

(gdb) b if aaa=50

Breakpoint 3 at 0x8048422: file debug_core.c, line 18.

查看断点:info b

(gdb) info b

Num     Type           Disp Enb Address    What

1       breakpoint     keep y   0x080483ee in sub at debug_core.c:13

2       breakpoint     keep y   0x08048408 in sub at debug_core.c:17

3、设置观察点:watch

watch <expr>

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

rwatch <expr>

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

    awatch <expr>

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

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

(gdb) watch aaa

Hardware watchpoint 1: aaa

4指定源文件的路径 directory/dir

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

dir <dirname>:加一个源文件路径到当前路径的前面。指定多个路径,可以使用”:”

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

(gdb) dir /opt:/usr/include/

Source directories searched: /opt:/usr/include:$cdir:$cwd

(gdb) show dir

Source directories searched: /opt:/usr/include:$cdir:$cwd

5搜索源代码

GDB还提供了源代码搜索的命令:

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

    reverse-search <regexp> 
        全部搜索。
   其中,<regexp>就是正则表达式,也主一个字符串的匹配模式

6、查看源代码内存:info line

info line后面可以跟”行号”,”函数名”,”文件名:行号”,”文件名:函数名”,这个命令会打印出所指定的源码在运行时的内存地址

(gdb) info line debug_core.c:sub

Line 12 of "debug_core.c" starts at address 0x80483e8 <sub> and ends at 0x80483ee <sub+6>.

7、查看源程序的当前执行码disassemble

这个命令会把目前内存中的指令dump出来

(gdb) disassemble sub

Dump of assembler code for function sub:

0x080483e8 <sub+0>:     push   %ebp

0x080483e9 <sub+1>:     mov    %esp,%ebp

0x080483eb <sub+3>:     sub    $0x18,%esp

0x080483ee <sub+6>:     movl   $0x0,-0x8(%ebp)

0x080483f5 <sub+13>:    movl   $0x0,-0x4(%ebp)

0x080483fc <sub+20>:    jmp    0x8048402 <sub+26>

0x080483fe <sub+22>:    addl   $0x1,-0x4(%ebp)

0x08048402 <sub+26>:    cmpl   $0x9,-0x4(%ebp)

0x08048406 <sub+30>:    jle    0x80483fe <sub+22>

0x08048408 <sub+32>:    mov    -0x8(%ebp),%eax

0x0804840b <sub+35>:    mov    %eax,(%esp)

0x0804840e <sub+38>:    call   0x8048415 <add>

0x08048413 <sub+43>:    leave

0x08048414 <sub+44>:    ret

End of assembler dump.

8、维护断点:clear、delete、disable、enable

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

clear <function>

clear <filename:function>

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

clear <linenum>

clear <filename:linenum>

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

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自动删除。

9、停止条件维护:condition和ignore

condition <bnum> <expression>

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

condition <bnum>

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

ignore <bnum> <count>

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

在GDB中运行shell命令

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

    shell <command string>
    调用UNIX的shell来执行<command string>,环境变量SHELL中定义的UNIX的shell将会被用来执行<command string>,如果SHELL没有定义,那就使用UNIX的标准shell:/bin/sh。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值