GDB调试下的多进程与多线程
来源:互联网 发布:淘宝背景材图 编辑:程序博客网 时间:2024/05/18 00:54
主要方法
1、attach方法
2、follow-fork-mode方法
背景知识
首先要进行调试,我们就不得不先搞清楚调试的一些基本操作。
gdb(Linux调试器)使用
(1)产生调试信息:要进行代码的调试,就需要有调试信息,要产生调试信息,就需要在源代码生成时添加-g选项;
(2)调试的开始和退出
开始调试:gdb file(file表示要进行调试的源文件)
退出调试:ctrl+d或quit
(3)调试的一些基本操作
attach调试方法
attach是GDB中中有附着到正在运行的进程中的功能实现,通过attach(pid),就可直接该进程进行调试
在介绍这种调试方法时,我们需要先对守护进程做一个简单的学习,因为attach方法对于守护进程的调试有很大的作用
守护进程
定义:守护进程(daemon)是一类在后台运行的特殊进程,用于执行特定的系统任务。很多守护进程在系统引导的时候启动,并且一直运行直到系统关闭。另一些只在需要的时候才启动,完成任务后就自动结束。
简介:守护进程是一个在后台运行并且不受任何终端控制的进程,如果你了解过信号方面的知识,你就会明白信号在捕捉的时候为什么会单独留下一个‘9号’进程不能被捕获,两者其实都是从保护系统的角度所设计出来的。
守护进程创建步骤:
(1)创建子进程,终结父进程;
(2)在子进程中创建新会话;
(3)改变工作目录;
(4)重建子网掩码;
简单测试(在这段代码中我们很明显会发现父进程中调用的Div函数中有一个除0错误):
//Makefile(Makefile中的注释并不是“//”这里这是为了表示文件的信息,后面将不再做解释)gdb:gdb.c gcc -o $@ $^ -g -lpthread.PHONY:cleanclean: rm -f gdb
代码编译结果:
#include<stdio.h>#include<pthread.h>#include<stdlib.h>int Div(int num1, int num2){ pit_t id=getpid(); printf("my pid is %d\n",id); int result, diff; diff = num1 - num2; result = num1 / diff; return result;}int main(){ pid_t pid; pid = fork(); if (pid <0) { printf("fork err\n"); exit(-1); } else if (pid == 0) {//child int val1 = 5; int val2 = 1; int ret = 0; int i=5; while(i--) {//parent ret = Div(val1, val2); val2++; val1--; printf("cur result is %d\n",ret); } } else {//child sleep(4); wait(-1); exit(0); }}
运行结果:
先让程序运行到后台:执行gdb &
调试演示:
follow-fork-mode调试方法
使用方法:
set follow-fork-mode [parent|child]
(1)parent:fork之后继续调试父进程,子进程不受影响
(2)child::fork之后继续调试子进程,父进程不受影响
子进程调试方法:
启动gdb之后:
(gdb) set follow-fork-mode child
(1)在子进程相应可能会出错的地方设置断点
(2)设置detach-on-fork参数(用于指示gdb在fork之后,gdb的进程)
设置方法设置方法:set follow-fork-mode [parent|child] set detach-on-fork [on|off]
具体设置和功能如图所示:(GDB 6.6或以上版本)
常用的一些其他方法:
查询正在调试的进程:info inferiors
切换调试的进程: inferior <infer number>
添加新的调试进程: add-inferior [-copies n] [-exec executable] ,可以用file executable来分配给inferior可执行文件。
其他:remove-inferiors infno, detach inferior
简单演示(这个我们只是走一下调试的过程本身并没有错误):
//MakefileGdb:Gdb.c gcc -o $@ $^ -g -lpthread.PHONY:cleanclean: rm -f Gdb
#include<stdio.h>#include<pthread.h>void* Thread(void* arg){ pid_t id=getpid(); printf("I am a thread, my pid is %d\n",id);}void childfunc(){ pid_t id=getpid(); printf("I am a child , my pid is %d\n",id);}void parentfunc(){ pid_t id=getpid(); int stat; pthread_t pt; printf("I am a parent , my pid is %d\n",id); stat=pthread_create(&pt,NULL,Thread,NULL); if(stat!=0){ printf("parent process can not create thread"); } Thread(NULL); sleep(2);}int main(){ int id=fork(); if(id<0){ perror("fork"); return -1; } else if(id==0){//child childfunc(); sleep(2); } else{//parent parentfunc(); sleep(2); } return 0;}
运行结果:
调试演示:
(1)调试主进程,block子进程
(2)切换到子进程
(3)调试主进程中产生的两个线程
两种调试方法比较
attach子进程方法:灵活强大,但需要添加额外代码,适合于各种复杂情况,特别是守护进程;
follow-fork-mode方法:方便易用,对系统内核和GDB版本有限制,适合于较为简单的多进程系
- GDB调试下的多进程与多线程
- GDB 下的多线程多进程调试
- Linux下用gdb调试多进程与多线程程序
- Linux下使用gdb调试多进程与多线程程序
- gdb下的多进程多线程的调试
- gdb调试多进程与多线程
- GDB调试-多进程与多线程程序
- gdb调试多进程与多线程
- gdb调试多进程与多线程
- gdb调试多进程与多线程
- 使用gdb调试多线程与多进程
- gdb调试多线程与多进程
- 多进程多线程的gdb调试
- GDB调试多进程、多线程
- gdb多进程多线程调试
- gdb 多进程,多线程调试
- GDB多进程多线程调试
- gdb调试多线程多进程
- BZOJ1407: [Noi2002]Savage
- onethink中修改ucenter用户的密码
- JS实现回车搜索
- SpringBoot四大神器之Actuator
- 使用ORACLE在线重定义将普通表改为分区表
- GDB调试下的多进程与多线程
- 破解前端面试(80% 应聘者不及格系列):从 DOM 说起
- 离线环境安装python第三方库
- java 中Throwable常用方法
- 2017年第八届蓝桥杯C/C++B组决赛题解
- 两种进入容器的方法
- Flutter进阶—实现动画效果(九)
- 在 CentOS 7 中使用 Nginx 和 PHP7-FPM 安装 Nextcloud
- 驱动线程和干活线程的关系