本文为自我常用,详细请见转载出处:linux下gdb调试方法与技巧整理
gdb调试详解
是 GNU 调试器(GNU Debugger)的缩写,它是一个功能强大的 Unix-like 系统下的源代码调试器。使用 gdb
,程序员可以查看程序在运行时的状态,设置断点,单步执行代码,检查变量的值,以及执行其他调试任务。(在命令行终端中进行)
gdb启动流程
-
编译相关:编译链接的时候
-g
表示可以调试,如果要使用gdb调试记得加上gcc -g test.cpp -o test
-
启动gdb,示例如下:
gdb test gbd -q test //表示不打印gbd版本信息,界面比较干净
-
gdb下查看源码:
list
(gdb) list 9 #define MAX_SIZE 10 11 int main() 12 { 13 int i,fd,size1 ,size2 ,len; 14 char *buf = "helo!I'm liujiangyong "; 15 char buf_r[15]; 16 len = strlen(buf); 17 fd = open("/home/hello.txt",O_CREAT | O_TRUNC | O_RDWR,0666); 18 if (fd<0) (gdb) 19 { 20 perror("open :"); 21 exit(1); 22 } 23 else 24 { 25 printf("open file:hello.txt %d\n",fd); 26 } 27 size1 = write(fd,buf,len); 28 if (fd<0) (gdb) 29 { 30 printf("writre erro;"); 31 32 } 33 else 34 { 35 printf("写入的长度:%d\n写入文本内容:%s\n",size1,buf); 36 37 } 38 lseek(fd,0,SEEK_SET); (gdb) 39 size2 = read(fd,buf_r,12); 40 if (size2 <0) 41 { 42 printf("read erro\n"); 43 } 44 else 45 { 46 printf("读取长度:%d\n 文本内容是:%s\n",size2,buf_r); 47 } 48 close(fd); (gdb) 49 50 51 } (gdb) Line number 52 out of range; write.c has 51 lines. (gdb)
-
gbd下运行程序:
run
该命令会运行程序直到结束或者遇到断点等待下一个命令
(gdb) r The program being debugged has been started already. Start it from the beginning? (y or n) y Starting program: /home/eit/c_test/test open file:hello.txt 3 写入的长度:22 写入文本内容:helo!I'm liujiangyong 读取长度:12 文本内容是:helo!I'm liu [Inferior 1 (process 19987) exited normally] (gdb)
-
gdb下设置断点:
break
+行号该命令会在某一行设置一个断点,
info breakpoints
会显示所有断点信息(gdb) b 5 Breakpoint 3 at 0x400836: file write.c, line 5. (gdb) b 26 Breakpoint 4 at 0x4008a6: file write.c, line 26. (gdb) b 30 Breakpoint 5 at 0x4008c6: file write.c, line 30. (gdb) info breakpoints Num Type Disp Enb Address What 3 breakpoint keep y 0x0000000000400836 in main at write.c:5 4 breakpoint keep y 0x00000000004008a6 in main at write.c:26 5 breakpoint keep y 0x00000000004008c6 in main at write.c:30 (gdb)
num type disp enb address what 断点编号 类型 断点执行一次后是否有效,keep(有) 当前断点是否有效,y(有) 内存地址 在函数中的位置 -
gdb下单步执行:
continue
、step
、next
、finish
-
continue
:在断点处继续执行程序 -
next
:执行下一行代码(跳过函数内部) -
step
:执行下一行代码(进入函数内部) -
finish
:执行完当前函数并返回到父函数
(gdb) r Starting program: /home/eit/c_test/test Breakpoint 3, main () at write.c:12 12 { (gdb) n 14 char *buf = "helo!I'm liujiangyong "; (gdb) 16 len = strlen(buf); (gdb) 17 fd = open("/home/hello.txt",O_CREAT | O_TRUNC | O_RDWR,0666); (gdb) s open64 () at ../sysdeps/unix/syscall-template.S:81 81 ../sysdeps/unix/syscall-template.S: No such file or directory. (gdb) main () at write.c:18 18 if (fd<0) (gdb) 25 printf("open file:hello.txt %d\n",fd); (gdb) __printf (format=0x400a26 "open file:hello.txt %d\n") at printf.c:28 28 printf.c: No such file or directory. (gdb) c Continuing. open file:hello.txt 3 Breakpoint 4, main () at write.c:27 27 size1 = write(fd,buf,len); (gdb) Continuing. 写入的长度:22 写入文本内容:helo!I'm liujiangyong 读取长度:12 文本内容是:helo!I'm liu [Inferior 1 (process 20737) exited normally] (gdb)
-
-
gdb下查看变量:
print
、whatis
main () at write.c:28 28 if (fd<0) (gdb) 35 printf("写入的长度:%d\n写入文本内容:%s\n",size1,buf); (gdb) print fd $10 = 3 (gdb) whatis fd type = int (gdb)
-
gdb下退出gdb:
quit
(gdb) r Starting program: /home/eit/c_test/test open file:hello.txt 3 写入的长度:22 写入文本内容:helo!I'm liujiangyong 读取长度:12 文本内容是:helo!I'm liu [Inferior 1 (process 20815) exited normally] (gdb) q root@ubuntu:/home/eit/c_test#
常用命令
当使用表格来表示 gdb
的常用命令时,可以如下所示:
命令分类 | 命令 | 描述 |
---|---|---|
启动和退出 | gdb your_program | 启动 GDB 并加载指定的程序 |
quit 或 q | 退出 GDB | |
调试控制 | run [arguments] 或 r [arguments] | 运行程序并传递参数 |
continue 或 c | 继续执行,直到遇到下一个断点或程序结束 | |
next 或 n | 执行下一行代码(不进入函数) | |
step 或 s | 执行下一行代码(进入函数) | |
finish | 执行完当前函数并返回到父函数 | |
断点管理 | break [location] 或 b [location] | 在指定位置设置断点 |
info breakpoints 或 info b | 显示所有断点信息 | |
disable [breakpoint_number] | 禁用指定编号的断点 | |
enable [breakpoint_number] | 启用指定编号的断点 | |
delete [breakpoint_number] 或 d [breakpoint_number] | 删除指定编号的断点 | |
变量和内存查看 | print [variable_name] 或 p [variable_name] | 显示变量的值 |
ptype [variable_name] | 显示变量的类型 | |
set var [variable_name]=[newValue] | 修改变量的值 | |
x/NFU [address] | 显示内存内容,N是数量,F是格式,U是单位,address是地址 | |
其他常用命令 | list [location] 或 l [location] | 显示源代码 |
backtrace 或 bt | 显示堆栈跟踪 | |
watch [expression] | 设置观察点,当表达式值改变时停止 | |
catch [event] | 捕获特定事件(如异常) | |
show path | 显示GDB搜索源代码的路径 | |
setargs [arguments] | 设置传递给程序的命令行参数 | |
show args | 显示设置好的运行时参数 | |
attach [process_id] | 连接到正在运行的进程 | |
detach | 断开与已连接进程的连接 | |
shell [command] | 执行shell命令 | |
自定义命令和脚本 | define [cmd_name] [command_list] | 定义自定义命令 |
脚本文件 | 使用脚本文件来自动化调试任务 | |
多线程和多进程调试 | info threads | 显示所有线程信息 |
thread [tid] | 切换到指定编号的线程 | |
`set follow-fork-mode [child | parent]` |
请注意,这个表格只是提供了 gdb
的一些常用命令的概览,每个命令还有更多的选项和用法可以探索。