GDB是GNU开源组织发布的一个强大的UNIX下的程序调试工具。或许,各位比较喜欢那种图形界面方式的,像VC、BCB等IDE的调试,但若是你是在UNIX平台下作软件,你会发现GDB这个调试工具备比VC、BCB的图形化调试器更强大的功能。所谓“寸有所长,尺有所短”就是这个道理。html
通常来讲,GDB主要帮忙你完成下面四个方面的功能:linux
一、启动你的程序,能够按照你的自定义的要求为所欲为的运行程序。
二、可以让被调试的程序在你所指定的调置的断点处停住。(断点能够是条件表达式)
三、当程序被停住时,能够检查此时你的程序中所发生的事。
四、动态的改变你程序的执行环境。git
从上面看来,GDB和通常的调试工具没有什么两样,基本上也是完成这些功能,不过在细节上,你会发现GDB这个调试工具的强大,你们可能比较习惯了图形化的调试工具,但有时候,命令行的调试工具却有着图形化工具所不能完成的功能。让咱们一一看来。redis
先用vim
写一个示例程序(tst.c
):shell
#include <stdio.h> int func(int n) { int sum=0, i; for(i=0;i<n;i++) { sum+=i; } return sum; } void main() { int i; long result=0; for(i=1;i<=100;i++) { result+=i; } printf("result[1-100]=%d \n", result); printf("result[1-250]=%d \n", func(250)); }
编译生成可执行文件:ubuntu
$ gcc -g tst.c -o tst # -g 选项的意思是加入调试信息
使用gdb
调试(感性理解):vim
(体验好差,能够来这里看:https://blog.csdn.net/HaoZiHu... )markdown
$ gdb tst <----------启动GDB GNU gdb (Ubuntu 8.1-0ubuntu3) 8.1.0.20180409-git <-------显示GDB说明,无论它 Copyright (C) 2018 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 "x86_64-linux-gnu". Type "show configuration" for configuration details. For bug reporting instructions, please see: <http://www.gnu.org/software/gdb/bugs/>. Find the GDB manual and other documentation resources online at: <http://www.gnu.org/software/gdb/documentation/>. For help, type "help". Type "apropos word" to search for commands related to "word"... Reading symbols from tst...done. (gdb) l <-----------l命令至关于list,从第一行开始列出源码 2 3 int func(int n) 4 { 5 int sum=0, i; 6 for(i=0;i<n;i++) 7 { 8 sum+=i; 9 } 10 return sum; 11 } (gdb) <-------------- 直接回车,重复上一次命令 12 13 void main() 14 { 15 int i; 16 int result=0; 17 for(i=1;i<=100;i++) 18 { 19 result+=i; 20 } 21 printf("result[1-100]=%d /n", result); (gdb) break 15 <-------------- 设置断点,在源程序第15行设置断点 Breakpoint 1 at 0x680: file tst.c, line 15. (gdb) break func <-------------- 设置断点,在函数func()入口处 Breakpoint 2 at 0x651: file tst.c, line 5. (gdb) info break <--------------- 查看断点信息 Num Type Disp Enb Address What 1 breakpoint keep y 0x0000000000000680 in main at tst.c:15 2 breakpoint keep y 0x0000000000000651 in func at tst.c:5 (gdb) r <--------------- 运行程序,run命令简写 Starting program: /home/jack/demo/gdb/tst Breakpoint 1, main () at tst.c:16 16 int result=0; <--------------- 在断点处停住 (gdb) n <--------------- 单条语句执行,next命令简写 17 for(i=1;i<=100;i++) (gdb) n 19 result+=i; (gdb) n 17 for(i=1;i<=100;i++) (gdb) n 19 result+=i; (gdb) n 17 for(i=1;i<=100;i++) (gdb) n 19 result+=i; (gdb) c <--------------- 继续运行命令,continue命令简写 Continuing. Breakpoint 2, func (n=250) at tst.c:5 5 int sum=0, i; (gdb) n 6 for(i=0;i<n;i++) (gdb) n 8 sum+=i; (gdb) p i <--------------- 打印变量的值 print命令缩写 $1 = 0 (gdb) p sum $2 = 0 (gdb) bt <--------------- 查看函数堆栈 #0 func (n=250) at tst.c:8 #1 0x00005555555546c0 in main () at tst.c:22 (gdb) finish <---------------- 退出函数 Run till exit from #0 func (n=250) at tst.c:8 0x00005555555546c0 in main () at tst.c:22 22 printf("result[1-250]=%d /n", func(250)); Value returned is $3 = 31125 (gdb) c Continuing. result[1-100]=5050 result[1-250]=31125 [Inferior 1 (process 7775) exited with code 026] <-------------- 程序退出,调试结束 (gdb) q <--------------- 退出gdb
在此处咱们简单总结一下gdb
的命令(<br/>
是换行的意思,SF的markdown没有内嵌这个元素......):函数
命令 | 解释 | 实例 |
---|---|---|
file <文件名> | 加载被调试的可执行程序文件 | (gdb) file gdb_sample |
r | run 的简写,运行被调试的程序<br/>若是此前没有设置过断点,则完整执行整个程序<br/>若是有断点,则程序暂停在第一个可用断点处 |
(gdb) r |
c | continue 的简写,继续执行被调试过的程序,<br/>直至下一个断点停在第一个可用断点处 |
(gdb) c |
b <行号><br/>b <函数名称><br/>b <函数名称><br/>b <代码地址><br/>d [编号] | b:break的简写,设置断点,可使用行号、函数名称<br/>或执行地址等方式来设置断点位置<br/>其中在函数名称前加* 符号表示将断点设置在"由编译器<br/>生成的prolog"代码处,若是不了解汇编,能够无论此用法<br/>d:delete的简写,删除指定编号的某个断点,<br/>或删除全部断点,断点编号从1开始递增 |
(gdb) b 8<br/>(gdb) b main<br/>(gdb) b main<br/>(gdb) b 0x3422<br/>(gdb) d 1 |
s, n | s:执行一行源程序代码,若是此行代码中函数调用,则进入该函数<br/>n:执行一行源程序代码,此行代码中的函数调用也一并执行<br/>s 至关于其余调试器中的Step Into(单步跟踪进入) <br/>n 至关于其余调试器中的Step Over(单步跟踪) <br/>这两个命令必须在有源代码调试信息的状况下才可使用<br/>(GCC 编译时使用-g 参数) |
(gdb) s<br/>(gdb) n |
si, ni | si命令相似于s命令,ni命令相似于n命令,不一样的是:<br/>这两条命令所针对的是汇编指令<br/>而s/n针对的是源代码 | (gdb) si<br/>(gdb) ni |
p <变量名称> | print的简称,显示指定变量(临时或全局变量)的值 | (gdb) p i<br/>(gdb) p cardPlay |
display ...<br/>undisplay <编号> | display 设置程序中断后欲显示的数据及其格式<br/>例如,若是但愿每次程序中断后能够看到即将被执行的下一条汇编指令,可使用命令"display /i $pc" <br/>其中 $pc 表明当前汇编指令,/i 表示以十六进行显示,当须要关心汇编代码时,此命令至关有用<br/>undisplay,取消先前的display设置,编号从1开始递增 |
(gdb) display /i $pc<br/>(gdb) undisplay 1 |
i | info的简写,显示各种信息 | (gdb) i r<br/>(gdb) i b<br/>(gdb) info break |
q | quit的简写,退出GDB 调试环境 |
(gdb) q |
help [命令名称] | GDB帮助命令,提供对GDB名种命令的解释说明。<br/>若是指定了“命令名称”参数,则显示该命令的详细说明;<br/>若是没有指定参数,则分类显示全部GDB命令,供用户进一步浏览和查询。 | (gdb) help display |