Linux C编程----3(gdb调试)

本文详细介绍了Linux环境下使用gdb调试C程序的各种命令,包括设置断点、查看函数调用堆栈、单步执行、查看内存及变量值等关键操作。通过实例演示了如何使用gdb进行程序调试,帮助开发者更好地理解和调试C程序。

一、常用命令

  1. break(b):
    break func:在函数开始设置断点,进入函数时停止运行
    break num:在第num行设置断点
    b reak:没有参数表示在下一条指令停止
    delete break:删除断点
  2. breaktrace(bt):查看各级函数调用及参数
  3. call func:强制调用函数
  4. continue(c):当程序遇到断点停止后,可继续运行直至下一个断点
    continue count:忽略后面的count个断点
  5. display:
    display var:实时打印变量数值
  6. examine(x):查看内存地址中的值
  7. finish:运行程序,直到当前函数完成
  8. frame(f):选择栈桢
  9. info(i):查看寄存器、断点、观察点和信号等信息
  10. jump:
    jump num:程序跳到num运行
    jump +ofst:偏移量格式地跳转
  11. list(l):
    list num:列出第num行周围的源程序
    list func:列出函数func周围的程序
    list :可看当前行后面的程序
    list-:可看当前行前面的程序
  12. next(n):单步执行,遇到函数时,不进入函数
    next count:执行后面的count条指令
  13. print(p):
    print var:打印出var变量的值
    print *(addr)=val:修改值
  14. quit(q):退出调试
  15. return:如果在函数中设置了高度断点,在断点后还有语句未执行,可强制返回
    return expr:带参数返回,作为函数的返回值
  16. run:启动程序
  17. set:修改寄存器、内存、变量的值
  18. signal:可以产生一个信号量给被调试的程序
  19. start:开始执行程序,在main函数变量定义之后的第一行语句前面等待命令
  20. step(s):单步执行,遇到函数则进入函数执行
    step count:执行后面的count条指令后停止
  21. watch:用来观察某个表达式的值是否有变化,如果有变化则马上停止程序

二、一个例子
首先源程序如下:

test.c

#include <stdio.h>

int add_range(int low, int high)
{
    int i = 0;
    int sum = 0;

    for(i=low; i<=high, i++)
    {
        sum = sum + i;
    }

    return sum;
}

int main()
{
    int result[100];
    char* c = "hello world";

    printf("%s\n", c);
    result[0] = add_range(1, 100);

    return 0;
}
编辑完保存,并编译 gcc -g test.c -o test
-g选项是在可执行文件里加入源程序信息以供调试
接着开始进行调试 gdb test
GNU gdb (GDB) 7.1-ubuntu
Copyright (C) 2010 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/>...
Reading symbols from /home/ding/workdir/gary/test/12-14-2/test...done.
(gdb) 
这就进入了调试界面,第一部分的命令就是在这里使用:
列出第1行开始的源程序:
(gdb) list 1
warning: Source file is more recent than executable.
1       #include <stdio.h>
2
3       int add_range(int low, int high)
4       {
5           int i = 0;
6           int sum = 0;
7           
8           for(i = low; i <= high; i++)
9           {
10              sum = sum + i;
(gdb) 
11          }
12
13          return sum;
14      }
15
16      int main()
17      {
18          int result[100];
19          char* c = "hello world";
20
(gdb) 
可以看到每次列出10行,后面10行直接按回车即可
(gdb) start
Temporary breakpoint 1 at 0x8048453: file test.c, line 19.
Starting program: /home/ding/workdir/gary/test/12-14-2/test 

Temporary breakpoint 1, main () at test.c:19
19          char* c = "hello world";
(gdb) 
输入start命令后,在定义语句之后的第一个命令处停止运行,此时输入step或next可执行下一条指令
(gdb) n
21          printf("%s\n", c);
(gdb) 
如果这个时候要看main函数里的变量的值,可用info locals命令
(gdb) info locals
result = {1163338, 1228788, 0, 0, -1073744716, 1201216, 1217633, 1214780, 
  1230116, 0, 1115284, -1073744716, 1115666, -1073744684, 1114836, 2, 1114932, 
  1287844, 225011984, -1073744688, 1149478, 1312754, 134513279, 2, 134513224, 
  -1207960760, -1073807358, 1172960, 134513224, 1231840, 1228788, 1252268, 1, 
  -1073744548, 1150934, 1228788, -1073744384, 1126577, 1230116, 1231536, 0, 0, 
  0, 0, 1252788, 1214364, -1073744604, 1231848, 14, 1287844, -1207960804, 
  -163754450, 0, 3, 1231096, 0, 0, 1, 2191, -1207960760, -1207961512, 
  134513261, 1289924, 134513144, 1, 1228788, -1073744320, 1231536, -1073744364, 
  1151570, -1073744380, 134513144, -1073744392, 1231444, 0, -1207960760, 1, 0, 
  1, 1231096, 2670580, 2337193, 1429557, -1073744472, 1329653, 2670580, 
  134520820, -1073744456, 134513420, 1171584, 134520820, -1073744408, 
  134513913, 2671396, 2670580, 134513888, -1073744408, 1430069, 1171584, 
  134513899}
c = 0x8048590 "hello world"
(gdb) 
可以看到result数组的值都很奇怪,因为我们还没给它赋值,但c是“hello world”,这里能看到c的地址是0x8048590,此时可以根据这个地址给修改c的值
(gdb) print *(char*)0x8048590='H'
$1 = 72 'H'
(gdb) print c
$2 = 0x8048590 "Hello world"
(gdb) 
可以看到c的第一个字母变面了大写的H,那如果要改result的值呢
(gdb) print result[0]=0
$3 = 0
(gdb) print result[0]
$4 = 0
(gdb)
也可以通过地址来修改:
(gdb) print &result[1]
$5 = (int *) 0xbffff450
(gdb) print *(int*)0xbffff450=1
$6 = 1
(gdb) print result[1]
$7 = 1
好了,继续往下走
(gdb) step
Hello world
22          result[0] = add_range(1, 10);
(gdb) s
add_range (low=1, high=10) at test.c:5
5           int i = 0;
(gdb) 
用step命令进入add_range函数,可以用display实时打印出这个函数里的变量的值
(gdb) display i,sum
1: i,sum = 0
(gdb) s
6           int sum = 0;
1: i,sum = 0
(gdb) 
8           for(i = low; i <= high; i++)
1: i,sum = 0
(gdb) 
10              sum = sum + i;
1: i,sum = 0
(gdb) 
8           for(i = low; i <= high; i++)
1: i,sum = 1
(gdb) 
此时可以用finish命令执行完本函数
最后就是用quit命令结束调试
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值