文章目录
gcc 编译
gcc -g hello.c -o a.out // 编译并在目标文件中添加调试信息
启动 gdb
- 直接指定文件启动
$ gdb a.out
- 先启动gdb,再载入文件
$ gdb
(gdb) file a.out // 载入文件
带参数调试
$ gdb a.out // 先正常启动gdb调试
(gdb) run [arg1] [arg2] [...] // 以指定参数重新运行当前已经加载的程序
(gdb) run // 采用和上次run相同的参数,或者 set args 指定的参数
查看转储文件
gdb [exec_file] [core_file]
gdb -c [core_file] [exec_file]
调试已经运行的进程
(gdb) attach process-id // 将进程附加到当前的 gdb
(gdb) detach // 将进程从 gdb 释放
显示源代码
更详细参考 Printing Source Lines
默认显示行数为10行。
list // 显示当前行附近的代码,如果再次执行list,则接着上次显示的代码继续显示
list linenum
list function
list first,last // 包括 last 行
list - // Print lines just before the lines last printed.
list + //Print lines just after the lines last printed.
打印数组
- 静态数组
int x[25];
(gdb) print x // 可以输出整个数组
- 动态数组
int *x;
x = (int*) malloc(25 * sizeof(int));
(gdb) print x // 打印数组地址
(gdb) print *x // 打印第一个元素
//可以使用下面两种方法输出整个数组
(gdb) print *x@25 // 人工数组 (artificial array)
(gdb) print (int [25]) *x // 强制类型转换
查看当前执行位置
使用命令 frame 或 where。
(gdb) frame
#0 unpack (
sha1=0x7fffffffdcf0 "...") at read-tree.c:16
16 unsigned char *sha1 = buffer + len;
(gdb) where
#0 unpack (
sha1=0x7fffffffdcf0 "...") at read-tree.c:16
打印字符串
参考 gdb中三种输出 print, x, display 的区别
char *a = "hello world";
char b[] = "hello world";
void *c = "hello world";
x 对于变量a, b, c 均能正确显示:
(gdb) x/s c
0x555555556004: "hello world"
对于变量 a,b,命令 print 能正确显示,但是对于变量 c 需要强制类型转换。
(gdb) print/s a
$7 = 0x555555556004 "hello world"
(gdb) print/s c
$5 = (void *) 0x555555556004
(gdb) print/s (char*)c
$7 = 0x555555556004 "hello world"
修改变量
(gdb) set variable i = 10
线程的附着和分离
(gdb) attach pid_num
(gdb) detach
查询所有线程
info threads
查询所有线程的堆栈信息
thread apply all bt
切换线程
thread num
切换栈帧
frame num
查看当前栈帧的栈信息
info frame