C实战:强大的程序调试工具GDB

1.基本调试

这里只列举最最常用的GDB命令。

1.1 启动GDB

gdb program:准备调试程序。也可以直接进入gdb,再通过file命令加载。

1.2 添加断点

b function:为函数设置断点。b是break的缩写,除了函数名,还可以是地址、当前执行处的+/-偏移等。

1.3 运行程序

run args:开始运行程序,run后面可以加程序需要的参数,就像在命令行正常运行时那样。

1.4 单步调试

s/n/si/c/kill:s即step in,进入下一行代码执行;n即step next,执行下一行代码但不进入;si即step instruction,执行下一条汇编/CPU指令;c即continue,继续执行直到下一个断点处;kill终止调试;quit退出GDB。

1.5 打印调试信息

bt:bt是backtrace的缩写,打印当前所在函数的堆栈路径。

info frame id:打印选中的栈帧的信息。

info args:打印选中栈帧的参数。

print variable:打印指定变量的值。

list:列出相应的源代码。

info registers:查看所有寄存器的值。

还有个更灵活强大的是直接打印%esp开始的前N个元素,例如打印栈上前10个元素就是:x/10x $sp

2.GDB实战

下面是一个使用了上述命令的实战例子:

  1. [root@BC-VM-edce4ac67d304079868c0bb265337bd4 bufbomb]# gdb bufbomb
  2. GNU gdb (GDB) Red Hat Enterprise Linux (7.2-75.el6)
  3. Copyright (C) 2010 Free Software Foundation, Inc.
  4. License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
  5. This is free software: you are free to change and redistribute it.
  6. There is NO WARRANTY, to the extent permitted by law. Type "show copying"
  7. and "show warranty" for details.
  8. This GDB was configured as "x86_64-redhat-linux-gnu".
  9. For bug reporting instructions, please see:
  10. <http://www.gnu.org/software/gdb/bugs/>...
  11. Reading symbols from /root/Temp/bufbomb/bufbomb...done.
  12. (gdb) b getbuf
  13. Breakpoint 1 at 0x8048ad6
  14. (gdb) run -t cdai
  15. Starting program: /root/Temp/bufbomb/bufbomb -t cdai
  16. Team: cdai
  17. Cookie: 0x5e5ee04e
  18. Breakpoint 1, 0x08048ad6 in getbuf ()
  19. Missing separate debuginfos, use: debuginfo-install glibc-2.12-1.149.el6_6.4.i686
  20. (gdb) bt
  21. #0 0x08048ad6 in getbuf ()
  22. #1 0x08048db2 in test ()
  23. #2 0x08049085 in launch ()
  24. #3 0x08049257 in main ()
  25. (gdb) info frame 0
  26. Stack frame at 0xffffb540:
  27. eip = 0x8048ad6 in getbuf; saved eip 0x8048db2
  28. called by frame at 0xffffb560
  29. Arglist at 0xffffb538, args:
  30. Locals at 0xffffb538, Previous frame's sp is 0xffffb540
  31. Saved registers:
  32. ebp at 0xffffb538, eip at 0xffffb53c
  33. (gdb) info registers
  34. eax 0xc 12
  35. ecx 0xffffb548 -19128
  36. edx 0xc8c340 13157184
  37. ebx 0x0 0
  38. esp 0xffffb510 0xffffb510
  39. ebp 0xffffb538 0xffffb538
  40. esi 0x804b018 134524952
  41. edi 0xffffffff -1
  42. eip 0x8048ad6 0x8048ad6 <getbuf+6>
  43. eflags 0x282 [ SF IF ]
  44. cs 0x23 35
  45. ss 0x2b 43
  46. ds 0x2b 43
  47. es 0x2b 43
  48. fs 0x0 0
  49. gs 0x63 99
  50. (gdb) x/10x $sp
  51. 0xffffb510: 0xf7ffc6b0 0x00000001 0x00000001 0xffffb564
  52. 0xffffb520: 0x08048448 0x0804a12c 0xffffb548 0x00c8aff4
  53. 0xffffb530: 0x0804b018 0xffffffff
  54. (gdb) si
  55. 0x08048ad9 in getbuf ()
  56. (gdb) si
  57. 0x08048adc in getbuf ()
  58. (gdb) si
  59. 0x080489c0 in Gets ()
  60. (gdb) n
  61. Single stepping until exit from function Gets,
  62. which has no line number information.
  63. Type string:123
  64. 0x08048ae1 in getbuf ()
  65. (gdb) si
  66. 0x08048ae2 in getbuf ()
  67. (gdb) c
  68. Continuing.
  69. Dud: getbuf returned 0x1
  70. Better luck next time
  71. Program exited normally.
  72. (gdb) quit

3.逆向调试

GDB 7.0后加入了Reversal Debugging功能。具体来说,比如我在getbuf()和main()上设置了断点,当启动程序时会停在main()函数的断点上。此时敲入record后continue到下一断点getbuf(),GDB就会记录从main()到getbuf()的运行时信息。现在用rn就可以逆向地从getbuf()调试到main()。就像《X战警:逆转未来》里一样,挺神奇吧!

这种方式适合从bug处反向去找引起bug的代码,实用性因情况而异。当然,它也是有局限性的。像程序假如有I/O输出等外部条件改变时,GDB是没法“逆转”的。

  1. [root@vm bufbomb]# gdb bufbomb
  2. GNU gdb (GDB) Red Hat Enterprise Linux (7.2-75.el6)
  3. Copyright (C) 2010 Free Software Foundation, Inc.
  4. License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
  5. This is free software: you are free to change and redistribute it.
  6. There is NO WARRANTY, to the extent permitted by law. Type "show copying"
  7. and "show warranty" for details.
  8. This GDB was configured as "x86_64-redhat-linux-gnu".
  9. For bug reporting instructions, please see:
  10. <http://www.gnu.org/software/gdb/bugs/>...
  11. Reading symbols from /root/Temp/bufbomb/bufbomb...done.
  12. (gdb) b getbuf
  13. Breakpoint 1 at 0x8048ad6
  14. (gdb) b main
  15. Breakpoint 2 at 0x80490c6
  16. (gdb) run -t cdai
  17. The program being debugged has been started already.
  18. Start it from the beginning? (y or n) y
  19. Starting program: /root/Temp/bufbomb/bufbomb -t cdai
  20. Breakpoint 2, 0x080490c6 in main ()
  21. (gdb) record
  22. (gdb) c
  23. Continuing.
  24. Team: cdai
  25. Cookie: 0x5e5ee04e
  26. Breakpoint 1, 0x08048ad6 in getbuf ()
  27. (gdb) rn
  28. Single stepping until exit from function getbuf,
  29. which has no line number information.
  30. 0x08048dad in test ()
  31. (gdb) rn
  32. Single stepping until exit from function test,
  33. which has no line number information.
  34. 0x08049080 in launch ()
  35. (gdb) rn
  36. Single stepping until exit from function launch,
  37. which has no line number information.
  38. 0x08049252 in main ()

C实战:强大的程序调试工具GDB的更多相关文章

  1. 应用程序调试工具gdb,王明学learn

    应用程序调试工具gdb学习使用 一.GDB简介 GDB 是 GNU 发布的一款功能强大的程序调试工具.GDB 主要完成下面三个方面的功能: 1.启动被调试程序. 2.让被调试的程序在指定的位置停住. ...

  2. GDB程序调试工具

    GDB程序调试工具 GDB主要完成下面三个方面的功能: 启动被调试程序 让被调试程序在指定的位置停住 当程序被停住时,可以检查程序状态 GDB快速入门 编译生成可执行文件 gcc -g test.c ...

  3. 软件调试工具——GDB

    1.GDB调试器概述 GDB是GNU开源组织发布的一个强大的程序调试工具,具有查看程序运行状态.设置断点.查看表达式.显示变量等众多功能,是程序员进行Linux编程必须要掌握的一种调试技术. GDB调 ...

  4. Linux GDB程序调试工具使用简单介绍

    GDB概述 GDB是GNU开源组织公布的一个强大的UNIX下的程序调试工具.也许,各位比較喜欢那种图形界面方式的,像VC.BCB等IDE的调试,但假设你是在UNIX平台下做软件,你会发现GDB这个调试 ...

  5. Linux GDB 程序调试工具使用详解

    转自    http://www.codeceo.com/article/linux-gdb-tools.html 整理的挺全的 GDB概述 GDB是GNU开源组织发布的一个强大的UNIX下的程序调试 ...

  6. 调试工具GDB详解

    1 简介 2 生成调试信息 3 启动GDB 的方法 4 程序运行上下文 4.1 程序运行参数 4.2 工作目录 4.3 程序的输入输出 5 设置断点 5.1 简单断点 5.2 多文件设置断点 5.3 ...

  7. 调试工具gdb

    1.1 gdb符号调试器简介 gdb是一个用来调试C和C++程序的功能强大的调试器,它能在程序运行时观察程序的内部结构和内存的使用情况. gdb主要提供以下几种功能: 监视程序中变量值的变化 设置断点 ...

  8. 转 -Linux 自检和 SystemTap (强大的内核调试工具)---包含下载地址

    下载: http://www.oschina.net/p/systemtap/ https://sourceware.org/systemtap/ftp/releases/   Linux 自检和 S ...

  9. 出书了!实战微信小程序

    真正用心写完一本书,才知道写书真的很不容易. 我热衷喜欢分享一些技术,也喜欢钻研一些新东西,去年微信小程序刚内测的时候,我和我的同事四个人就一起研究,恰好公司有小程序相关的项目,做项目的同时,越发感觉 ...

随机推荐

  1. [转]map函数补充

    map()函数 map()是 Python 内置的高阶函数,它接收一个函数 f 和一个 list,并通过把函数 f 依次作用在 list 的每个元素上,得到一个新的 list 并返回. 例如,对于li ...

  2. 远程连接服务器jupyter notebook、浏览器以及深度学习可视化方法

    h1 { counter-reset: h2counter; } h2 { counter-reset: h3counter; } h3 { counter-reset: h4counter; } h ...

  3. thinkphp3.2v

    1.thinphp环境搭建 一.将thinkphp文件拿出来,对我们有用的是cof和library,其他对开发都没有作用. 在thinkphp/library/think文件夹中几个重要的文件 1.A ...

  4. 将 Net 项目升级 Core项目经验:(一)迁移Net项目为Net Core\Standard项目

    迁移Net项目为Net Core\Standard项目 背景: 我们公司内部有自己ORM开发框架,最新因为需要将系统迁移到国产服务器上,所以首先需要将最基础的ORM框架改造可以运行在国产服务器上.对于 ...

  5. Java:扩展后的赋值运算符(带强转功能)

    扩展后的赋值运算符,即 +=,-=,*=,/=,%=,&=,|=,^=,<<=,>>=,>>>=. 代码实例一: byte a=5; a=a+5; 此 ...

  6. Python3玩转儿 机器学习(3)

    机器学习算法可以分为: 监督学习 非监督学习 半监督学习 增强学习 监督学习:给机器的训练数据拥有"标记"或者"答案",例如: 我们需要告诉机器左边的画面是一只 ...

  7. [AtCoder arc090E]Avoiding Collision

    Description 题库链接 给出一张 \(N\) 个节点, \(M\) 条边的无向图,给出起点 \(S\) 和终点 \(T\) .询问两个人分别从 \(S\) 和 \(T\) 出发,走最短路不相 ...

  8. BZOJ4894 天赋

    Description 小明有许多潜在的天赋,他希望学习这些天赋来变得更强.正如许多游戏中一样,小明也有n种潜在的天赋,但有 一些天赋必须是要有前置天赋才能够学习得到的.也就是说,有一些天赋必须是要在 ...

  9. [BZOJ]3532: [Sdoi2014]Lis

    Time Limit: 10 Sec  Memory Limit: 512 MB Description 给定序列A,序列中的每一项Ai有删除代价Bi和附加属性Ci.请删除若干项,使得4的最长上升子序 ...

  10. poj 2774 最长公共子串 后缀数组

    Long Long Message Time Limit: 4000MS   Memory Limit: 131072K Total Submissions: 25752   Accepted: 10 ...