目录
GDB调试
...
GDB多进程调试
使用GDB调试的时候,默认只能跟踪一个进程,因此我们需要在调试之前,通过指令设置GDB调试工具要跟进的是父进程还是子进程,GDB调试默认跟进的是父进程。
上代码:
#include <stdio.h>
#include <unistd.h>
int main() {
printf("begin\n");
if(fork() > 0) {
printf("我是父进程:pid = %d, ppid = %d\n", getpid(), getppid());
int i;
for(i = 0; i < 10; i++) {
printf("i = %d\n", i);
sleep(1);
}
} else {
printf("我是子进程:pid = %d, ppid = %d\n", getpid(), getppid());
int j;
for(j = 0; j < 10; j++) {
printf("j = %d\n", j);
sleep(1);
}
}
return 0;
}
调试父进程:
1、先进行编译 ,并加上调试参数 -g :
gcc -o test test.c -g
2、编译完成后生成可执行文件, 输入 gdb + 可执行文件名 进入调试:
gdb test
3、输入 l 可以查看代码信息
4、 在第10行 和 第20行 分别打上断点,输入 info b 可以查看断点信息:
b 10
b 20
info b
5、输入 run ,执行调试程序,默认情况下是以父进程代码进行调试,同一时刻,子进程的代码会先运行完:
run //默认执行到父进程的断点处
6、输入 continue 或者 next,才会开始执行父进程的代码:
continue // 继续运行直到下一个断点
next // 向下执行一步
调试子进程
保持以上的gdb调试模式, 输入 show follow-fork-mode
可以看到默认调试模式就是父进程 “paraent”。
因此输入:set follow-fork-mode child 就可以修改调试父子进程模式:
修改后调试过程就跟父进程是一样的了。
设置调试模式
set detach-on-fork [on off] 默认为 on,表示调试当前进程的时候,其它的进程继续运行,也就是代表父子进程进行脱离,在调试父进程的时候,子进程已经脱离了,因此会出现子进程先运行完的情况,在调试父进程时我们出现过这种情况:
set detach-on-fork on //默认为on 可以不用此命令设置
如果为 off,调试当前进程的时候,其它进程被 GDB挂起。
可以使用 show detach-on-fork 查看当前调试模式,使用 set detach-on-fork + on/off 进行设置。
set detach-on-fork off
还是用上面的代码,两个断点,当 run 运行调试时可以发现调试的是父进程,此时子进程处于挂起状态:
在该调试模式中, 以下几个命令会用到:
1、 需要查看当前正在调试的进程,执行图中 ✳ 则代表的是当前正在调试的进程信息(即父进程):
info inferiors
2、 切换当前调试的进程,输入 inferior + id 即可切换当前需要进行调试的进程:
inferior id
从以上info 可以知道子进程的 id 为2 ,执行 inferior 2 ,可以切换到子进程:
当其中一个进程调试运行完后,在info信息中的 description 会显示 null:
3、需要使当前进程脱离 gdb 调试:
detach inferiors id
GDB多线程调试
多线程调试与多进程调试的操作原理相差不大,下面列出常用的调试命令:
gdb调试命令
查看可切换调试的线程:info threads
切换调试的线程:thread + 线程id
只运行当前线程:set scheduler-locking on
运行全部线程:set scheduler-locking off
指定某线程执行某gdb命令:thread apply 线程id gdb_cmd
全部的线程执行某gdb命令:thread apply all gdb_cmd
shell 常用命令
查看当前运行的进程:ps aux | grep book
查看当前运行的轻量级进程:ps -aL | grep book
查看主线程和子线程的关系:pstree -p 主线程id
coredump
定义
程序core掉了,需要定位解决,是指对应程序由于各种异常或者bug导致在运行过程中异常退出或者中止,并且在满足一定条件下(ulimit –c参数指定)会产生一个叫做 core 的文件。
通常情况下,core文件会包含了程序运行时的内存,寄存器状态,堆栈指针,内存管理信息还有各种函数调用堆栈信息等,可以理解为是程序工作当前状态存储生成第一个文件。
许多的程序出错的时候都会产生一个core文件,通过工具分析这个文件,可以定位到程序异常退出的时候对应的堆栈调用等信息,找出问题所在并进行及时解决。
查看core文件
1、当程序出现异常等情况时:
2、要查询错误的原因我们需要查看到 core文件,输入 ulimit - a 查询有无设置生成core文件的条件, core文件的大小被设置为0,这样系统就不dump出core文件了,因此当数值为0则表示关闭状态(即不生成core文件):
3、输入命令 ulimit - c unlimit ,即设置生成的core文件的大小为无限大,当然也可以使用数字来替代unlimited,对core文件的上限制做更精确的设定。
4、设置成功后,重新编译程序并再次生成可调试代码 gcc test.c -o test -g ,可以看到core文件已经生成:
5、要查看core 文件还需要进入 gdb调试模式, 输入 gdb test 进入调试模式,进入调试模式后输入 core-file core 即可查看core 文件: