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