平台
ubuntu 14.04 64bit
$ gcc -v
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/4.8/lto-wrapper
Target: x86_64-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Ubuntu 4.8.4-2ubuntu1~14.04.1' --with-bugurl=file:///usr/share/doc/gcc-4.8/README.Bugs --enable-languages=c,c++,java,go,d,fortran,objc,obj-c++ --prefix=/usr --program-suffix=-4.8 --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --with-gxx-include-dir=/usr/include/c++/4.8 --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --enable-gnu-unique-object --disable-libmudflap --enable-plugin --with-system-zlib --disable-browser-plugin --enable-java-awt=gtk --enable-gtk-cairo --with-java-home=/usr/lib/jvm/java-1.5.0-gcj-4.8-amd64/jre --enable-java-home --with-jvm-root-dir=/usr/lib/jvm/java-1.5.0-gcj-4.8-amd64 --with-jvm-jar-dir=/usr/lib/jvm-exports/java-1.5.0-gcj-4.8-amd64 --with-arch-directory=amd64 --with-ecj-jar=/usr/share/java/eclipse-ecj.jar --enable-objc-gc --enable-multiarch --disable-werror --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32,m64,mx32 --with-tune=generic --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu
Thread model: posix
gcc version 4.8.4 (Ubuntu 4.8.4-2ubuntu1~14.04.1)
1.检查gdb版本
$ gdb -v
GNU gdb (Ubuntu 7.7.1-0ubuntu5~14.04.2) 7.7.1
Copyright (C) 2014 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".
2.测试文件
// file name example.c
#include "stdio.h"
void print_scrambled(char * message)
{
int i = 3;
do{
printf("%c", (*message));
}while(*++message);
printf("\n");
}
int main()
{
char * incorrectMsg = NULL;
char * correctMsg = "hello, world.";
print_scrambled(correctMsg);
print_scrambled(incorrectMsg);
return 0;
}
3.使用步骤
编译
注意在编译时加上-g条件,即
$ gcc -g example.c -o example
否则在使用lis时将提示
(gdb) lis
1 dl-debug.c: No such file or directory.
启用gdb
正常运行为
$ ./example
hello, world.
Segmentation fault (core dumped)
使用gdb运行
$ gdb ./example
GNU gdb (Ubuntu 7.7.1-0ubuntu5~14.04.2) 7.7.1
Copyright (C) 2014 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 ./example...done.
(gdb)
开始调试
(gdb) run
Starting program: /home/inmen/myc/example
hello, world.
Program received signal SIGSEGV, Segmentation fault.
0x0000000000400544 in print_scrambled (message=0x0) at example.c:8
8 printf("%c", (*message));
上面提示,正常输出hello, world. 然后就提示段错误(一般是指针飞了)
于是指向了指针飞走的那一行
8 printf("%c", (*message));
来让我滚回去看一下,这一行属哪个程序片段
backtrace
(gdb) backtrace
#0 0x0000000000400544 in print_scrambled (message=0x0) at example.c:8
#1 0x000000000040059d in main () at example.c:19
再使用
list[lis]
(gdb) list
3
4 void print_scrambled(char * message)
5 {
6 int i = 3;
7 do{
8 printf("%c", (*message));
9 }while(*++message);
10 printf("\n");
11 }
12
使用短命令lis也是可以的,左侧明显就是代码所在原文件中的位置了
追踪局部变量值info locals
(gdb) info locals
i = 3
追踪函数参数值 info args
(gdb) info args
message = 0x0
打印变量值 print
(gdb) print i
$1 = 3
(gdb) print message
$2 = 0x0
调试向前移一帧,不是往回跑
(gdb) up
#1 0x000000000040059d in main () at example.c:19
19 print_scrambled(incorrectMsg);
(gdb) info locals
incorrectMsg = 0x0
correctMsg = 0x400634 "hello, world."
设置断点 b[breakpoint]
运行至main run
单步,不进入函数 n[next]
单步,进入函数 s[step]
(gdb) b main
Breakpoint 1 at 0x400575: file example.c, line 15.
(gdb) run
Starting program: /home/inmen/myc/example
Breakpoint 1, main () at example.c:15
15 char * incorrectMsg = NULL;
(gdb) n
16 char * correctMsg = "hello, world.";
(gdb) s
18 print_scrambled(correctMsg);
(gdb) s
print_scrambled (message=0x400634 "hello, world.") at example.c:6
6 int i = 3;
退出 q[quit]
(gdb) q
A debugging session is active.
Inferior 1 [process 3479] will be killed.
Quit anyway? (y or n) y
4.更多的使用方法
命令 | 作用 |
cd | 改变当前工作目录 |
clear | 删除刚才停止的断点 |
commands | 命中断点时,列出将要执行和命令 |
continue | 从断点继续 |
delete | 删除一个断点 |
display | 程序停止时显示变量和表达式 |
down | 使下一个函数成为当前函数 |
frame | 选择下一条continue命令的帧 |
jump | 在源程序的另一个点开始运行 |
kill | 终止在gdb运行的程序 |
pwd | 显示当前工作目录 |
pype | 显示一个数据结构的内容 |
quit | 退出GDB |
reverse-search | 在源文件中反向搜索正则表达式 |
search | 搜索正则表达式 |
set variable | 给变量赋值 |
signal | 将一个信号发送到正在运行的线程 |
undisplay | 不显示表达式 |
until | 结束当前循环 |
up | 上移栈,使上一个函数成为当前函数 |
watch | 设置监测点 |
whatis | 显示变量或函数类型 |