gdb基本命令
命令 | 作用 |
---|---|
list或l + 行号 | 显示从行号开始的源代码 |
list或l + 函数名 | 列出某个函数的源代码 |
run或r | 运行程序 |
step或s | 进入函数调用 |
breaktrace或bt | 查看各级函数调用及参数 |
info或i | locals查看当前栈帧局部变量的值 |
info break | 查看断点信息 |
finish | 执行到当前函数返回,然后停下来等待命令 |
print或p | 打印表达式的值,通过表达式可以修改变量的值或者调用函数 |
break或b + 行号 | 在某一行设置断点 |
set var | 修改变量的值 |
quit | 退出调试 |
break + 函数名 | 在某个函数开头设置断点 |
continue或c | 从当前位置开始连续而非单步执行调试程序 |
run或r | 从开头连续执行程序而非单步执行 |
delete breakpoints | 删除断点 |
delete breakpoints n | 删除序号为n的断点 |
disable breakpoints | 禁用断点 |
enable breakpoints | 启用断点 |
info或i breakpoints | 查看当前设置了哪些断点 |
display + 变量名 | 跟踪查看一个变量,每次停下来都显示这个值 |
undisplay | 取消先前对那些变量设置的跟踪 |
until + x | 跳至第x行 |
n或next | 单步执行 |
p + 变量 | 打印变量值 |
list或l | 列出源代码,接着上次的位置往下列,每次列10行 |
frame或f | 帧编号,选择栈帧 |
start | 开始执行程序,停在main函数第一行语句前面等待命令 |
call + 函数名 | 强制调用某个函数 |
gdb调试多进程
调试多进程程序时gdb默认调试主进程,gdb支持同时调试多个进程,只需要设置follow-fork-mode(默认为parent)和detach-on-fork(默认为on)即可。我们还可以使用catch fork指令,如果fork异常,会停止程序。
follow-fork-mode | detach-on-fork | 说明 |
---|---|---|
parent | on | 只调试主进程(gdb默认) |
child | on | 只调试子进程 |
parent | off | 同时调试两个进程,gdb跟主进程,子进程block(阻塞)在fork位置 |
child | off | 同时调试两个进程,gdb跟子进程,主进程block在fork位置 |
可以用 set 设置、show 查看当前状态
测试用例:
#include<stdio.h>
#include<stdlib.h>
#include<sys/types.h>
#include<unistd.h>
int main()
{
pid_t pid = fork();
if(pid == 0)
{
printf("i am child! pid = %d, ppid = %d\n",getpid(),getppid());
}
else
{
printf("i am father! pid = %d, ppid = %d\n",getpid(),getppid());
}
return 0;
}
开始调试
设置为只调试父进程,子进程阻塞式等待。设置方法在表二中说明。
设置为先调试父进程,子进程阻塞式等待。调试完父进程之后切换到子进程再次调试。
gdb调试多线程
测试用例:
#include<stdio.h>
#include<pthread.h>
#include<sys/types.h>
void* thread1(void* arg)
{
printf("thread1 running pid = %d, tid = %u\n", getpid(),pthread_self());
pthread_exit((void*)1);
}
void* thread2(void* arg)
{
printf("thread2 running pid = %d, tid = %u\n", getpid(),pthread_self());
return (void*2;
}
int main()
{
pthread_t p1,p2;
pthread_create(&p1, NULL, &thread1, NULL);
pthread_create(&p2, NULL, &thread2, NULL);
pthread_cancel(p2);
void* ret1=NULL;
void* ret2=NULL;
pthread_join(p1, &ret1);
pthread_join(p2, &ret2);
printf("thread1 ret = %d\n", ret1);
printf("thread2 ret = %d\n", ret2);
return 0;
}
开始调试
设置core文件
core的意思是核心,dumped的意思就是抛出,转储,core dumped就是核心转储的意思。当一个进程异常退出前,该进程会抛出当时该程序进程的内存详细情况存储在硬盘上,文件名通常是core,这就叫core dump。
进程异常终止通常是因为代码存在BUG,比如非法内存访问导致段错误,事后可以用调试器检查core文件以查清错误原因,这叫做事后调试。