心胸决定格局,眼界决定境界...

gdb常用命令的用法

http://www.cnblogs.com/hanxi/archive/2012/06/14/2549268.html 

 今天花了几分钟来学习使用gdb调试程序,有过以前使用IDE调试程序的基础,仅仅只需要花几分钟就能够很快的学会使用gdb命令来调试程序了。这里结合实例来说明怎么使用gdb命令。首先写一个简单的程序,然后载对程序进行调试。

    用于调试的示例程序:

复制代码
 1 #include <stdio.h>
 2 
 3 int sum(int a, int b)
 4 {
 5     int result;
 6     result = a + b;
 7     return result;
 8 }
 9 
10 int main(int argc, char ** argv)
11 {
12     if (argc != 3)
13     {
14         printf("请输入2个数字参数,用空格分开");
15         return -1;
16     }
17     int a = *argv[1]-'0';
18     int b = *argv[2]-'0';
19     int re = sum(a,b);
20     printf("%d + %d = %d",a,b,re);
21     return 0;
22 }
复制代码

 

  这个程序很简单,只做了个加法运算。现在我们开始调试程序了。

  1.编译生成。     

  IDE中分Debug和Release版本,那么在Linux我们一般编译这个文件使用:

    gcc -o testgdb testgdb.c 

    这就相当于IDE中的Release版本的编译生成工作了,那么怎么编译出Debug版本呢?这样,只需要添加 -g 命令就行:

    gcc -o testgdb testgdb.c -g

  2.进入调试状态,即进入dgb。 

    进入gdb有两种方式,一种是直接输入命令gdb。另一种是在gdb后面加上第一步编译好的文件名。进入到gdb调试状态后可以看到

GNU gdb (GDB) 7.0.1-debian
Copyright (C) 2009 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 "i486-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.

(gdb)

    如果使用的是第一种方式,那么进入后得继续使用file命令来打开待调试的文件:(gdb)file testgdb

    会给出如下提示信息:

    Reading symbols from /home/hanxi/cpp/testgdb/testgdb...done.

  3.调试程序。   

    常用命令:

GDB常用命令 格式 含义 简写
list List [开始,结束] 列出文件的代码清单 l
prit Print 变量名 打印变量内容 p
break Break [行号或函数名] 设置断点 b
continue Continue [开始,结束] 继续运行 c
info Info 变量名 列出信息 i
next Next 下一行 n
step Step 进入函数(步入) S
display Display 变量名 显示参数  
file File 文件名(可以是绝对路径和相对路径) 加载文件  
run Run args 运行程序 r

 

    接下来对一个一个命令进行测试。(注:(gdb)后面是输入的命令和参数)

       (1):  (gdb)run 2 3    

    表示执行调试并传入两个参数2,3

    运行结果:

Starting program: /home/hanxi/cpp/testgdb/testgdb 2 3
2 + 3 = 5
Program exited normally. 

    这样就出现了计算结果,因为没有设置断点,所以就会执行完程序。下面就是使用设置断点的命令了。

       (2):    (gdb)b 4   

    表示在第4行设置断点,gdb给出以下提示说明设置断点成功

Breakpoint 1 at 0x80483ca: file testgdb.c, line 4.

    设置完断点后,我们再来运行程序,执行run命令。出现下面的提示信息:

Starting program: /home/hanxi/cpp/testgdb/testgdb 2 3

Breakpoint 1, sum (a=2, b=3) at testgdb.c:6
6 result = a + b;

    这样它停留在第6行了。我们怎么来继续执行了,使用c命令,相当于VS中的快捷键F5

    (3):     (gdb)c   

    继续执行程序,gdb给出以下提示信息

Continuing.
2 + 3 = 5
Program exited normally.

    这里又把程序执行完了,因为前面只设置一个断点。那么我们怎么知道设置了多少个断点呢?使用info break命令就能满足

    (4):     (gdb)info break   

    gdb给出了下面的提示信息: 

Num Type Disp Enb Address What
2 breakpoint keep y 0x080483ca in sum at testgdb.c:4
breakpoint already hit 1 time

    这信息提示我们,已经在第4行设置了一个断点,接下来就是去除断点的问题了,我们怎么把刚才的断点删除掉呢?在VS6.0是重复点工具栏的鼠型图标,在VS2010是点击每行的行首。在这里,我们也可以使用命令简单的删除或者禁用断点。删除断点的命令是delete b,禁用断点的命令是disable b。推荐使用disable b 命令。恢复禁用的断点的命令是enable b。这些命令后面可以带参数来说明第几个断点(是第几个不是第几行)。如:

    (5):     (gdb)disable b   

    然后执行run命令后就不会断点了,接着使用enable b命令后再使用run命令,这样又有了断点。有时候我们断点了就需要查看某个变量的值,那么使用什么命令查看变量的值和设置变量的值呢?答案是使用display或者是p

    (6):     (gdb)display result   

    这个效果在IDE中也有对应的:display相当于添加监听变量,每一次run后都会给出result的值。而print就对应着IDE中的鼠标停留时显示变量的值。

    (7):     (gdb)s   

    这是步入命令step,同样也有步过命令next(简写为n)。

可以通过focus命令开启,比list好用

查看运行时数据

gdb中查看变量的命令是print,一般用它的简写形式p。它的语法如下:

    print [</format>] <expr>

其中参数expr可以是一个变量,也可以是表达式。format表示输出格式,例如,可以用/x来将结果按16进制输出。如下是几个基本的例子:

    (gdb) p top
    $16 = 1
    (gdb) p &top
    $17 = (int *) 0x804a014 <top>
    (gdb) p 3+2*5
    $18 = 13
    (gdb) p /x 3+2*5
    $19 = 0xd

format的取值范围有如下几种:

  • x 按十六进制格式显示变量。
  • d 按十进制格式显示变量。
  • u 按十六进制格式显示无符号整型。
  • o 按八进制格式显示变量。
  • t 按二进制格式显示变量。
  • a 按十六进制格式显示变量。
  • c 按字符格式显示变量。
  • f 按浮点数格式显示变量。

查看函数返回值

查看函数返回值是在调试的过程中经常遇到的需求。例如,对于如下函数

    int foo()
    {
        return 100;
    }

我们可以以如下方式获取函数的返回值:

1. 通过finish命令运行至函数结束,此时会打印函数返回值。

    (gdb) finish
    Run till exit from #0 foo () at main.c:9
    main () at main.c:15
    15 }
    Value returned is $2 = 100

2. 返回值会存储在eax寄存器中,通过查看信息可以获取返回值。

    (gdb) p $eax
    $3 = 100

    (gdb) info registers 
    eax 0x64 100

查看连续内存

可以使用GDB的"@"操作符查看连续内存,"@"的左边是第一个内存的地址的值,"@"的右边则你你想查看内存的长度。

例如,对于如下代码:int arr[] = {2, 4, 6, 8, 10};,可以通过如下命令查看arr前三个单元的数据

    (gdb) p *arr@3
    $2 = {2, 4, 6}

查看内存

可以使用examine命令(简写为x)来查看内存地址中的值x命令的语法如下所示:

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

  • n 表示显示内存的长度,也就是说从当前地址向后显示几个地址的内容。
  • f 表示显示的格式,如果是字符串,则用s,如果是数字,则可以用i。
  • u 表示从当前地址往后请求的字节数,默认是4个bytes。(b单字节,h双字节,w四字节,g八字节)
  • <addr> 表示一个内存地址。

例如:以两字节为单位显示前面的那个数组的地址后32字节内存信息如下.

    (gdb) x /16uh arr
    0xbffff4cc: 2 0 4 0 6 0 8 0
    0xbffff4dc: 10 0 34032 2052 0 0 0 0

posted @ 2015-02-11 16:54  WELEN  阅读(177)  评论(0编辑  收藏  举报