一:GDB 的 TUI 模式使用
GDB的 TUI (Text User Interface)模式提供了一种图形化的调试体验,允许在终端中同时显示源代码,寄存器和汇编代码等信息,下面是GDB TUI的基本操作和快捷键
1. 显示源代码窗口:(gdb) layout src
2. 显示寄存器窗口:(gdb) layout regs
3. 显示汇编代码窗口:(gdb) layout asm
4. 关闭窗口: Ctrl + X 然后按 A
5. 刷新窗口:(gdb) refresh
6. 切换窗口:Ctrl + X 然后按 O
7. 调整窗口:Ctrl + X 然后按 +, - 来调整窗口大小
8. 调整布局:layout split
二:常用GDB命令
1. gdb attach 进程ID
gdb -p <pid>
2. 启动 gdb 带参数
gdb --args <program> <arg1> <arg2> ...
3. 打断点
break function, break file.c:10
4. 查看断点
info breakpoints
5. 继续执行
continue
6. 单步调试
step
7. 跳过当前行(执行当前行单不进入函数)
next
8. 查看调用栈
bt
9. 查看变量
print <var>
10. 查看内存
x/<format> <address> 例如 x/10xw 0x7fffffffe000 #查看10个字(word)的内存
11. 临时断点,用于跳转到某行执行,执行一次断点会自动删除
tbreak func, tbreak file.c:50
12. 查看源代码: list
13. 在窗口中查看源代码: layout src
14. 监视变量: watch expr
15. 设置条件断点:break function if <condition>
16. 捕获异常: catch throw , 除了throw之外,还有fork, loadlibname, uloadlibname。 即在某事发生时gdb停止允许,捕获这些事件。
四:多线程调试方法
1. 编译下面这个例子: gcc -g -o thread_example thread_example.c -lpthread
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
void *thread_function(void *arg) {
int id = *((int *)arg);
for (int i = 0; i < 5; i++) {
printf("Thread %d: iteration %d\n", id, i);
sleep(1);
}
return NULL;
}
int main() {
pthread_t threads[2];
int thread_args[2] = {1, 2};
for (int i = 0; i < 2; i++) {
pthread_create(&threads[i], NULL, thread_function, &thread_args[i]);
}
for (int i = 0; i < 2; i++) {
pthread_join(threads[i], NULL);
}
return 0;
}
2. 查看线程: info threads
3. 切换线程:thread 2
4. 查看当前线程调用堆栈: bt
5. 查看所有线程的调用堆栈: thread apply all bt