GDB ---- chapter

本文介绍了GDB调试的相关知识,包括内存断点watch的使用,如对不同类型变量(整形、指针、数组等)设置观察点,以及局部变量观察点的有效性;还整理了GDB常用命令,最后说明了GDB调试时指定跳到第几行的方法及注意事项。

gdb 内存断点watch 的使用

https://blog.youkuaiyun.com/hejinjing_tom_com/article/details/50570442

 

1.  watch 变量的类型
    a. 整形变量: int i; watch i;
    b. 指针类型:  char *p; watch p, watch *p;
    它们是有区别的.
      watch p 是查看 *(&p), 是p 变量本身。
      watch (*p) 是 p 所指的内存的内容, 查看地址,一般是我们所需要的。

      我们就是要看莫地址上的数据是怎样变化的,虽然这个地址具体位置只有编译器知道。

    c. watch 一个数组或内存区间
    char buf[128], watch buf,  
    是对buf 的128个数据进行了监视. 此时不是采用硬件断点,而是软中断实现的。
    软中断方式去检查内存变量是比较耗费cpu资源的。
    精确的指明地址是硬件中断。

2. 当你设置的观察点是一个局部变量时。局部变量无效后,观察点无效
 Watchpoint 2 deleted because the program has left the block in 
  which its expression is valid. 
               
3. 附上一个简单程序方便你利用内存断点观察,调试.

$ cat test.cpp
#include <stdio.h>
#include <string.h>
void initBuf(char *buf);
void prtBuf(char *buf);
char mem[8];
char buf[128];
int main()
{
    initBuf(buf);
    prtBuf(buf);
    return 0;
}
 
void initBuf(char *pBuf)
{
    int i, j;
    mem[0]='0';
    mem[1]='1';
    mem[2]='2';
    mem[3]='3';
    mem[4]='4';
    mem[5]='5';
    mem[6]='6';
    mem[7]='7';
    //ascii table first 32 is not printable
    for(i=2;i<8;i++)
    {
        for(j=0;j<16;j++)
            pBuf[i*16+j]=i*16+j;
    }
}
 
void prtBuf(char *pBuf)
{
    int i, j;
    for(i=2;i<8;i++)
    {
        for(j=0;j<16;j++)
            printf("%c  ", pBuf[i*16+j]);
        printf("\n");
    }
}
 

玩弄内存调试于股掌之中。
(由于效率问题你需要适当控制内存断点设置,当然,对这个小程序无所谓.)
----------------------------------------
看一下mem 数组, 内存数据是怎样被写入的。
----------------------------------------
gdb test
b main
watch mem
run
Breakpoint 1, main () at test.cpp:9
gdb) continue
  Continuing.
  Hardware watchpoint 2: mem
  Old value = "\000\000\000\000\000\000\000"
  New value = "0\000\000\000\000\000\000"
  initBuf (pBuf=0x6010a0 <buf> "") at test.cpp:18
(gdb) continue
  Continuing.
  Hardware watchpoint 2: mem
  Old value = "0\000\000\000\000\000\000"
  New value = "01\000\000\000\000\000"
  initBuf (pBuf=0x6010a0 <buf> "") at test.cpp:19
(gdb) continue
  Continuing.
  Hardware watchpoint 2: mem
  Old value = "01\000\000\000\000\000"
  New value = "012\000\000\000\000"
  initBuf (pBuf=0x6010a0 <buf> "") at test.cpp:20
(gdb) 
......

(gdb) continue
  Continuing.
  Hardware watchpoint 2: mem
  Old value = "0123456"
  New value = "01234567" 
  initBuf (pBuf=0x6010a0 <buf> "") at test.cpp:26

 

 

GDB常用命令总结

http://blog.sina.com.cn/s/blog_7880d3350102vw2d.html

在低端微控制器上进行仿真时,直接使用JTAG和IDE集成开发环境进行在线调试,不仅操作简单,而且界面良好,运行情况和结果非常直观。但是在Linux平台,很少有类似的集成开发环境,Linux上的GDB使用命令操作的方式,而且它要比集成开发环境强大多。下面是整理的常用的GDB调试命令。

 

编译时必须添加-g才能利用GDB进行调试,如:gcc -g test.c -o test

 

1.       gdb -tui test打开调试程序,界面分页,上面是代码,下面是命令;

2.       gdbtui的开关快捷键:ctrl+x ctrl+a或者ctrl+x A

3.       file test在运行gdb下打开某个文件

 

4.       run/r 运行

5.       continue/c 继续运行

6.       step/s 如果有函数则进入函数执行

7.       finish 跳出当前的函数

8.       stop 停止运行

9.       until xxx 可用于跳出循环

10.   guit/ctrl+d 退出GDB

 

11.   print/p var 打印变量的值

12.   print/p &var 打印变量地址

13.   printf/p *addr 打印地址的值

14.   printf/p /x var 用16进制显示数据

x十六进制/d十进制/u十六进制无符号/t二进制/c字符/f浮点

 

15.   break/b xxx 在某行打断点

16.   break/b fun 在某个函数处加断点

17.   break/b 30 if n==100 //当变量n等于100的时候在30行处加断点

18.   break fileName:N 在某个文件的N行加断点

19.   info break/b 查看断点

20.   clear N 删除N行断点

21.   delete N 删除N号断点

22.   delete 删除所有断点

23.   disable xxx 失能断点

24.   enable xxx 使能断点

 

25.   info b 查看断点

26.   info source 查看当前程序

27.   info stack 查看堆栈信息

28.   info args 查看当前参数值

29.   display args 查看当前参数值

30.   bt 查看函数堆栈

31.   pwd查看程序路径

 

32.   ctrl+p 前一条命令

33.   ctrl+n 下一条命令

 

34.   watch xxx 设置监控点,在变量改变的时候停下来。(不可直接设置,先加断点在监测)

 

35.   ctrl+l可能layout会造成控制台花屏,使用ctrl+L清屏

 

36.   list linenum:以linenum指定的行号为中心,显示10行

37.   list function:以指定的函数为中心,显示10行

38.   list:重复上一次的list指令,也可以直接按回车键,重复上次指令。

39.   set listsize count:设置每次显示的行数。

40.   show listsize:显示已设置的显示行数。

41.   list first,last:显示指定起始行到结束结束行的源文件。

42.   list ,last:显示以指定的last为结束行,显示10行。

43.   list first,:以first为第一行,显示10行。

44.   list +:以上次显示的结束行为起始行显示后10行

45.   list –:以上次显示的起始行为结束行,显示前10行

 

gdb 调试时指定跳到第几行

https://www.cnblogs.com/habibah-chang/p/5160246.html

假设要从当前位置(main.c, ln 18)跳到 main.c, ln 21,忽略中间的 main.c, ln 19 ~ ln 20,可以这样做:(jump 缩写是 j)

(gdb) b 21

(gdb) j 21

在 (gdb) c 之后,gdb 会跳过 ln 19 ~ ln 20,停在 ln 21

 

注意:

1)要在 ln 21 设置断点,否则 gdb 会在 jump 到 ln 21 之后继续执行,直到下一个断点或程序结束

2)如果要忽略的是一个函数调用,比如像下面这样,运行到 ln 10,要跳到 ln 12

10 i++;

11 i = foo();

12 i--;

可以:

(gdb) step

(gdb) return

即,进入 foo(),然后直接返回。但是,要小心 foo() 的返回值。如果这样做不方便的话,采用上面的方法,即

(gdb) b12

(gdb) j 12

也可以

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值