1. Linux下GDB调试常用命令
在调试前明确:在生成源代码的时候加上 -g 选项,开始使用: gdb binFile,退出: ctrl + d 或 quit。下面是调试的常用命令。
list/l 行号:显示binFile源代码,接着上次的位置往下列,每次列10行。
list/l 函数名:列出某个函数的源代码。
r或run:运行程序。
s或step:进行函数调用
breaktrace(或bt):查看各级函数调用及参数
info(i) locals:查看当前栈帧局部变量的值
info break :查看断点信息。
finish:执行到当前函数返回,然后停下来等待命令
print(p):打印表达式的值,通过表达式可以修改变量的值或者调用函数
set var:修改变量的值
quit:退出gdb
break(b) 行号:在某一行设置断点
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 变量:打印变量值
2. 调试多进程
1)调试代码
#include <stdio.h>
#include <unistd.h>
int main()
{
pid_t id;
id = fork();
if(id < 0)
{
perror("fork error\n");
return -1;
}
if(id == 0)
{
printf("I am child: pid: %d ppid: %d",getpid(), getppid());
sleep(1);
}
else
{
printf("I am father: pid: %d ppid: %d",getpid(), getppid());
wait(NULL);
}
return 0;
}
2)测试方法
默认设置下,在调试多进程程序时GDB只会调试主进程。但是GDB(>V7.0)支持多进程的分别以及同时调试,GDB可以同时调试多个程序。需要设置follow-fork-mode(默认为parent)和detach-on-fork(默认为on),下面为两者的介绍。
follow-fork-mode | detach-on-fork | 调试位置 |
---|---|---|
parent | on | 仅主程序 |
child | on | 仅子程序 |
parent | off | 同时调试两个进程,gdb随主进程,子进程阻塞在fork位置 |
child | off | 同时调试两个进程,gdb随子进程,主进程阻塞在fork位置 |
开启方法 set follow-fork-mode parent/child set detach-on-fork on/off
进程间切换:info inferiors(inferiors记录被调试程序的执行状态)用来查看所有进程,带*为正在调试的进程。inferior + 进程号,可以切换正在调试的进程。
添加新的调试进程:add-inferior [-copies n] [-exec executable]。 添加新的调试进程,可以用file executable来分配给inferior可执行文件。增加n个inferior并执行程序为executable。如果不指定n只增加一个inferior。如果不指定executable,则执行程序留空,增加后可使用file命令重新指定执行程序。
删除一个调试进程:首先通过detach inferior(detach掉编号为infno的inferior) 或者kill inferior infno:(kill掉编号为infno的inferior),此时并没有删掉inferior。最后通过remove-inferiors infno删除编号为infno的inferior。
3. 多线程的调试
gdb调试多线程常用命令
1)显示所有线程:info threads 显示可以调试的所有线程。gdb会为每个线程分配一个ID,编号一般从1开始。
2)线程的切换: thread ID 切换当前调试的线程为指定ID的线程。
3)断点设置:break FileName.cpp:LineNum thread all 所有的线程都在文件FileName.cpp的第LinueNum行有断点。
4)command命令:thread apply ID1 ID2 IDN command 让线程编号是ID1,ID2…等等的线程都执行command命令,thread apply all command:所有线程都执行command命令。
5)线程的锁定:set scheduler-locking off|on|step:
在调式某一个线程时,其他线程是否执行。在使用step或continue命令调试当前被调试线程的时候,其他线程也是同时执行的,如果我们只想要被调试的线程执行,而其他线程停止等待,那就要锁定要调试的线程,只让他运行。off:不锁定任何线程,默认值。 on:锁定其他线程,只有当前线程执行。
step:在step(单步)时,只有被调试线程运行。
6)同步和异步:set target-async on/ff:
同步和异步。同步,gdb在输出提示符之前等待程序报告一些线程已经终止的信息。而异步的则是直接返回。