gdb调试一个进程的过程
以下面模拟实现sleep()函数为例
#include <stdio.h>
#include <unistd.h>
#include <signal.h>
void wakeup(int signo)
{
//do nothing
}
unsigned int mysleep(unsigned int t)
{
struct sigaction new,old;
sigset_t newmask,oldmask,suspmask;
unsigned int unsleep=0;
new.sa_handler=wakeup;
new.sa_flags=0;
sigemptyset(&new.sa_mask);
//注册一个信号处理函数
sigaction(SIGALRM,&new,&old);
sigemptyset(&newmask);
//添加一个信号到newmask阻塞集
sigaddset(&newmask,SIGALRM);
//阻塞SIGALRM信号
sigprocmask(SIG_BLOCK,&newmask,&oldmask);
//设置一个闹钟
alarm(t);
suspmask=oldmask;
sigdelset(&suspmask,SIGALRM);
//解除信号屏蔽并挂起进程,等待闹钟响起
sigsuspend(&suspmask);
//清空闹钟
unsleep=alarm(0);
//回复默认信号处理动作
sigaction(SIGALRM,&old,NULL);
sigprocmask(SIG_SETMASK,&oldmask,NULL);
return unsleep;
}
int main( )
{
while( 1)
{
mysleep(5);
printf( "5s passed...\n");
printf( "pid=%d\n",getpid( ));
}
return 0;
}
程序编译通过无错误,执行下面命令(黄色部分)
gdb a.out 开始调试a.out文件
b 4 在第四行打断点,开始调试
i b 查看断点
d 删除断点
r 让程序跑起来
n 逐行调试
p 变量名 打印变量,配合n命令效果会更好
q 退出调试
如果是进入函数,需要上s命令
gdb调试多进程
以下面程序为例,这个程序是为了测试SIGCHLD信号的测试小程序。子进程退出,发SIGCHLD信号父进程,父进程自己做自己的事情,收到信号就回收子进程
#include <signal.h>
#include <stdlib.h>
void handler(int sig)
{
pid_t id;
while(id=waitpid(-1,NULL,WNOHANG)>0)
{
printf( "wait child success:%d\n",id);
}
printf(" child is quit! %d\n",getpid( ));
}
int main( )
{
signal(SIGCHLD,handler);
pid_t cpid;
if( cpid=fork()==0)
{
printf("child:%d\n",getpid());
sleep(10);
exit(1);
}
while(1)
{
printf( " father proc is doing some thing!pid:%d\n",getpid());
sleep(1);
}
return 0;
}
首先让程序编译通过,最好打印出各自pid
如果不打印,用 “ps aux | grep 目标文件名“查看进程pid
在另外一个终端输入:gdb a.out命令进入调试模式后,用attach 进程pid就可以调试该进程,但必须保证进程跑完.
其他操作和调试单个进程类似