参考资料:GDB调试精粹及使用实例

# 调试实例

  1. #include <iostream>
  2. #include <cstring>
  3. using namespace std;
  4. int f[][];
  5. int ax,ay;
  6. int bx,by;
  7. int dx[]={,,-,};
  8. int dy[]={,,,-};
  9. int _count=;
  10. int _min=;
  11. int n,m,k;
  12.  
  13. void dfs(int d,int t,int curx,int cury)
  14. {
  15. if(t>_min)
  16. return ;
  17. if(curx< || cury< || cury>n- || curx>m-)
  18. return ;
  19. if(f[cury][curx])
  20. return ;
  21. if(curx==by && cury==bx){
  22. if(t<_min){
  23. _count=;
  24. _min=t;
  25. }
  26. else{
  27. _count++;
  28. }
  29. return ;
  30. }
  31. f[cury][curx]=true;
  32. if(d==-){
  33. for(int i=;i<;i++){
  34. bool bt = f[cury+dy[i]][curx+dx[i]];
  35. if(!bt){
  36. dfs(i,t+,curx+dx[i],cury+dy[i]);
  37. if( !(bx==cury+dy[i] && by==curx+dx[i] ))
  38. f[cury+dy[i]][curx+dx[i]]=false;
  39. }
  40. }
  41. }
  42. else{
  43. for(int i=;i<;i++){
  44. bool bt = f[cury+dy[i]][curx+dx[i]];
  45. int tt=d^;
  46. if(tt==i) continue;
  47. if(!bt){
  48. dfs(i,t+,curx+dx[i],cury+dy[i]);
  49. if( !(bx==cury+dy[i] && by==curx+dx[i] ))
  50. f[cury+dy[i]][curx+dx[i]]=false;
  51. }
  52. }
  53. }
  54. return ;
  55. }
  56.  
  57. int main()
  58. {
  59. while(cin>>n>>m>>k){
  60. _count=;
  61. _min=;
  62. memset(f,,sizeof(f));
  63. for(int i=;i<=k;i++){
  64. int a,b;
  65. cin>>a>>b;
  66. f[a][b]=true;
  67. }
  68. cin>>ax>>ay;
  69. cin>>bx>>by;
  70. dfs(-,,ay,ax);
  71. cout<<_min<<endl;
  72. cout<<_count<<endl;
  73. }
  74. return ;
  75. }

  这是一道“小鼠迷宫问题”的代码,是道搜索题,要求输出矩阵内a到b的最短路的长度以及最短路的条数。这道题的第一遍代码写完之后,运行后发现堆栈溢出了程序没有输出直接结束。用codeblocks自带的调试debug了一会,发现不是很好用,遂转入cygwin下编译原程序启动gdb调试。顺便也复习了一下gdb的命令。

  下面是我以此程序为例,学习gdb的笔记:

  1. Administrator@PC- /cygdrive/d/bin/小鼠迷宫问题
  2. $ g++ -o xs -ggdb main.cpp
-- 编译原程序,并产生调试信息,便于之后进行gdb调试。
•$ g++ -o ex1 -g  ex1.cpp
利用操作系统的native format生成调试信息。GDB 可以直接利用这个信息,其它调试器也可以使用这个调试信息。
•$ g++ -o ex1 -ggdb  ex1.cpp
为 GDB 生成专用的更为丰富的调试信息,但是,此时就不能用其他的调试器来进行调试了 (如 ddx)
(引自L老师课件)
  1. Administrator@PC- /cygdrive/d/bin/小鼠迷宫问题
  2. $ gdb xs

-- 启动gdb调试原程序。

-- 启动之后会刷出以下内容:

  1. Administrator@PC- /cygdrive/d/bin/小鼠迷宫问题
  2. $ gdb xs
  3. GNU gdb (GDB) 7.6.50.20130728-cvs (cygwin-special)
  4. Copyright (C) Free Software Foundation, Inc.
  5. License GPLv3+: GNU GPL version or later <http://gnu.org/licenses/gpl.html>
  6. This is free software: you are free to change and redistribute it.
  7. There is NO WARRANTY, to the extent permitted by law. Type "show copying"
  8. and "show warranty" for details.
  9. This GDB was configured as "i686-pc-cygwin".
  10. Type "show configuration" for configuration details.
  11. For bug reporting instructions, please see:
  12. <http://www.gnu.org/software/gdb/bugs/>.
  13. Find the GDB manual and other documentation resources online at:
  14. <http://www.gnu.org/software/gdb/documentation/>.
  15. For help, type "help".
  16. Type "apropos word" to search for commands related to "word".
  17. ..
  18. Reading symbols from /cygdrive/d/bin/小鼠迷宫问题/xs...done.
  19. (gdb)

-- 最后一行(gdb)后面会有一个光标“_”在闪,表示可以输入命令。

  1. (gdb) l
  2. f[cury+dy[i]][curx+dx[i]]=false;
  3. }
  4. }
  5. }
  6. return ;
  7. }
  8.  
  9. int main()
  10. {
  11. while(cin>>n>>m>>k){

-- list(可简写为 l):显示代码

  1. (gdb) l
  2. #include <iostream>
  3. #include <cstring>
  4. using namespace std;
  5. int f[][];
  6. int ax,ay;
  7. int bx,by;
  8. int dx[]={,,-,};
  9. int dy[]={,,,-};
  10. int _count=;
  11. int _min=;

-- list 1:从第一行显示代码

  1. (gdb) l
  2. int n,m,k;
  3.  
  4. void dfs(int d,int t,int curx,int cury)
  5. {
  6. if(curx< || cury< || cury>n- || curx>m-)
  7. return ;
  8. if(f[cury][curx])
  9. return ;
  10. if(curx==by && cury==bx){
  11. if(t<_min){

-- 继续显示代码

=============== 插入一下 ================

这个时候我看命令行里代码有堆起来了,想清理一下,结果尝试性的输入命令“cls”和“clear”,发现这两个命令是行不通的。

  1. (gdb) cls
  2. Undefined command: "cls". Try "help".
  3. (gdb) clear
  4. No source file specified.

好吧,既然不行,我们继续。

======================================

  1. (gdb) b dfs
  2. Breakpoint at 0x401186: file main.cpp, line .

-- breakpoint dfs:在函数dfs入口处设置断点

-- breakpoint 1 表示这是第一个断点

  1. (gdb) r
  2. Starting program: /cygdrive/d/bin/小鼠迷宫问题/xs
  3. [New Thread .0xdc0]
  4. [New Thread .0x155c]
  5.  
  6. Breakpoint , dfs (d=-, t=, curx=, cury=) at main.cpp:
  7. if(curx< || cury< || cury>n- || curx>m-)

-- run:运行程序。

-- run 命令运行之后,光标会停下来闪烁,表示在等待输入数据。输入数据之后会直接运行到第一个断点处停止,并显示相关信息。

  1. (gdb) c
  2. Continuing.
  3.  
  4. Breakpoint , dfs (d=, t=, curx=, cury=) at main.cpp:
  5. if(curx< || cury< || cury>n- || curx>m-)

-- continue:继续运行。

========== 小问题 ============

  1. (gdb) b dfs if curx== && cury==
  2. Note: breakpoint also set at pc 0x401186.
  3. Breakpoint at 0x401186: file main.cpp, line .
  4. (gdb) c
  5. Continuing.
  6.  
  7. Breakpoint , dfs (d=, t=, curx=, cury=) at main.cpp:
  8. if(curx< || cury< || cury>n- || curx>m-)

第一条gdb命令设置一个条件断点为第二个断点,第二条gdb命令为继续运行,为何继续运行后不是跳到刚设置的第二个断点处呢?

===========================

  1. (gdb) p curx
  2. $ =

-- print:显示一个变量的值

========== 小例子 ==========

  1. (gdb) p curx
  2. $ =
  3. (gdb) p
  4. $ =
  5. (gdb) p
  6. $ =
  7. (gdb) p cury
  8. $ =
  9. (gdb) p
  10. $ =

连续输入p会持续显示上一次观察的变量的值。

==========================

====== 小问题:这时候连续输入“continue”会发生什么呢? =======

  1. (gdb) c
  2. Continuing.
  3.  
  4. Breakpoint , dfs (d=, t=, curx=, cury=) at main.cpp:
  5. if(curx< || cury< || cury>n- || curx>m-)
  6. (gdb) c
  7. Continuing.
  8.  
  9. Breakpoint , dfs (d=, t=, curx=, cury=) at main.cpp:
  10. if(curx< || cury< || cury>n- || curx>m-)
  11. (gdb) c
  12. Continuing.
  13.  
  14. Breakpoint , dfs (d=, t=, curx=, cury=) at main.cpp:
  15. if(curx< || cury< || cury>n- || curx>m-)
  16. (gdb) c
  17. Continuing.
  18.  
  19. Breakpoint , dfs (d=, t=, curx=, cury=) at main.cpp:
  20. if(curx< || cury< || cury>n- || curx>m-)

会连续显示第一个断点处的变化。

===========================================

还有其它常用命令:

  1. (gdb) s
  2. if(f[cury][curx])
  3. (gdb) s
  4. if(curx==by && cury==bx){
  5. (gdb) s
  6. s20 if(t<_min){
  7. (gdb) s
  8. _count=;
  9. (gdb) s
  10. _min=t;
  11. (gdb) s
  12. return ;

-- step:单步执行,等效于step into(可进入函数)。

与之相对的

-- next(n):单步执行,等效于step over(只在当前函数中执行)。

-- finish(f):跳出当前函数,等效于step out。

  1. (gdb) b dfs if curx== && cury==
  2. Breakpoint at 0x401186: file main.cpp, line .

-- b dfs if curx==2 && cury==2:设置条件断点,程序执行到符合条件处停止。

  1. (gdb) watch i
  2. Hardware watchpoint : i
  3. (gdb) s
  4. if(!bt){
  5. (gdb) s
  6. for(int i=;i<;i++){
  7. (gdb) s
  8. Hardware watchpoint : i
  9.  
  10. Old value =
  11. New value =
  12. 0x00401443 in dfs (d=, t=, curx=, cury=) at main.cpp:

-- watch:设置一个监测点(数据断点),被检测变量在程序中出现时,显示其变化。

  1. (gdb) i b
  2. Num Type Disp Enb Address What
  3. breakpoint keep y 0x00401186 in dfs(int, int, int, int)
  4. at main.cpp:
  5. stop only if curx== && cury==
  6. breakpoint already hit time
  7. breakpoint keep y 0x00401186 in dfs(int, int, int, int)
  8. at main.cpp:
  9. breakpoint keep y 0x004011bc in dfs(int, int, int, int)
  10. at main.cpp:

-- info breakpoint:显示当前所有断点信息。

  1. (gdb) d b
  2. Ambiguous delete command "b 1": bookmark, breakpoints.
  3. (gdb) d breakpoint
  4. (gdb) i b
  5. Num Type Disp Enb Address What
  6. breakpoint keep y 0x00401186 in dfs(int, int, int, int)
  7. at main.cpp:
  8. breakpoint keep y 0x004011bc in dfs(int, int, int, int)
  9. at main.cpp:

-- delete breakpoint 断点号:删除指定断点

  1. (gdb) d
  2. Delete all breakpoints? (y or n) y
  3. (gdb) i b
  4. No breakpoints or watchpoints.

-- delete:删除当前所有断点

Freecode : www.cnblogs.com/yym2013

GDB调试笔记的更多相关文章

  1. nginx模块_使用gdb调试nginx源码

    工欲善其事必先利其器,如何使用调试工具gdb一步步调试nginx是了解nginx的重要手段. ps:本文的目标人群是像我这样初接触Unix编程的同学,如果有什么地方错误请指正. 熟悉gdb的使用 这里 ...

  2. 用gdb调试程序笔记: 以段错误(Segmental fault)为例

    用gdb调试程序笔记: 以段错误(Segmental fault)为例[转] 1.背景介绍2.程序中常见的bug分类3.程序调试器(如gdb)有什么用4.段错误(Segmental fault)介绍5 ...

  3. GDB调试基础

    GDB调试基础 https://lesca.me/archives/gdb-basic-knowledge.html GDB笔记(二):条件断点.命令列表.监视点 https://lesca.me/a ...

  4. GDB调试命令小结

    1.启动调试 前置条件:编译生成执行码时带上 -g,如果使用Makefile,通过给CFLAGS指定-g选项,否则调试时没有符号信息.gdb program //最常用的用gdb启动程序,开始调试的方 ...

  5. GDB调试汇编堆栈过程分析

    GDB调试汇编堆栈过程分析 分析过程 这是我的C源文件:click here 使用gcc - g example.c -o example -m32指令在64位的机器上产生32位汇编,然后使用gdb ...

  6. gdb调试器的使用

    想要使用gdb调试程序的话,首先需要gcc -g main.c -o test 然后运行gdb test对程序进行调试 l (小写的l,是list的首字母),用以列出程序 回车    是运行上一个命令 ...

  7. 20145212——GDB调试汇编堆栈过程分析

    GDB调试汇编堆栈过程分析 测试代码 #include <stdio.h> short val = 1; int vv = 2; int g(int xxx) { return xxx + ...

  8. gdb调试PHP扩展错误

    有时候,使用PHP的第三方扩展之后,可能会发生一些错误,这个时候,可能就需要更底层的方式追踪调试程序发生错误的地方和原因,熟悉linux下C编程的肯定不陌生gdb 首先,使用ulimit -c命令,查 ...

  9. gdb调试汇编堆栈过程的学习

    gdb调试汇编堆栈过程的学习 以下为C源文件 使用gcc - g code.c -o code -m32指令在64位的机器上产生32位汇编,然后使用gdb example指令进入gdb调试器: 进入之 ...

随机推荐

  1. 大数据分析与机器学习领域Python兵器谱

    http://www.thebigdata.cn/JieJueFangAn/13317.html 曾经因为NLTK的缘故开始学习Python,之后渐渐成为我工作中的第一辅助脚本语言,虽然开发语言是C/ ...

  2. hdu 2049 不容易系列之(4)——考新郎

    在本博AC代码中,求CNM用的是Anm/amm没用阶乘的形式,两者皆可 #include <stdio.h> int main(void) { long long a,b,larr[21] ...

  3. 利用dedecms autoindex让文章列表加上序列号

    有些时候我们在制作模板的需要在文章标题前面加上序列号,可以通过织梦自带的autoindex属性来实现,实现方法很简单,只需要在序号递增的地方加上 这段代码就行,[field:global runphp ...

  4. 调用gluNurbsCurve绘制圆弧

    <OpenGL编程指南>第12章第3小结专门介绍调用GLU绘制NURBS曲线或曲面,很可惜的是并未给出绘制圆弧的例子.网上可以找到很多绘制整个园的例子,却没圆弧例子,自己瞎折腾了2个礼拜, ...

  5. 用LoadRunner实现接口测试

    接口测试的两种方法 其实无论用那种测试方法,接口测试的原理是通过测试程序模拟客户端向服务器发送请求报文,服务器接收请求报文后对相应的报文做出处理然后再把应答报文发送给客户端,客户端接收应答报文这一个过 ...

  6. java笔记--超级类Object多线程的应用+哲学家进餐算法内部类与多线程结合

    关于Object类中的线程方法: Object类是所有Java类的 父类,在该类中定义了三个与线程操作有关的方法,使得所有的Java类在创建之后就支持多线程 这三个方法是:notify(),notif ...

  7. Ubuntu 16.04 下安装Firefox的Flash插件

    在ubuntu系统环境下面打开优酷视频,发现无法播放视频.Adobe Flash Player 是一款轻量级浏览器插件,具有丰富的 Internet 应用运行时间,提供持续的迷人用户体验.绝妙的音频/ ...

  8. B,B+,B-,B*树

    B树 即二叉搜索树: 1.所有非叶子结点至多拥有两个儿子(Left和Right): 2.所有结点存储一个关键字: 3.非叶子结点的左指针指向小于其关键字的子树,右指针指向大于其关键字的子树: 如: B ...

  9. 黑客讲述渗透Hacking Team全过程(详细解说)

    近期,黑客Phineas Fisher在pastebin.com上讲述了入侵Hacking Team的过程,以下为其讲述的原文情况,文中附带有相关文档.工具及网站的链接,请在安全环境下进行打开,并合理 ...

  10. Delphi10 安装Graphics32

    一.下载Graphics安装包 官网:www.graphics32.org 下载地址:http://sourceforge.net/projects/graphics32/files/graphics ...