一、简介
Linux下fork创建子进程执行程序,而父进程检测子进程的执行过程并处理部分信号,当出现段错误生成core文件时被重新命名,以便能随时通过时间调试core。
二、详解
1、代码
process_signal.cpp(测试程序):
#include <iostream>
#include <unistd.h>
#include <assert.h>
#include <stdio.h>
#include <sys/time.h>
#include <sys/wait.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
using namespace std;
void process_signal(int signo) //信号处理函数
{
fprintf(stderr,"\nsignal %d catched!\n", signo);
cout<<"Please wait for clear operations"<<endl;
exit(0);
}
int set_signal_hander() //设置信号
{
assert( signal(SIGPIPE, SIG_IGN) != SIG_ERR );
assert( signal(SIGINT, process_signal) != SIG_ERR );
assert( signal(SIGTERM, process_signal) != SIG_ERR );
assert( signal(SIGQUIT, process_signal) != SIG_ERR );
assert( signal(SIGTRAP, process_signal) != SIG_ERR );
assert( signal(SIGTSTP, process_signal) != SIG_ERR );
return 0;
}
int check_signal_core()
{
int child_status = 0;
pid_t child_pid = 0;
static char core_file[10] = {0};
char core_name[1024] = {0};
struct timeval tms;
char time_now[22] = {0};
timerclear(&tms);
child_pid = fork();
if (child_pid > 0) { //父进程
cout<<"child_pid:"<<child_pid<<endl;
wait(&child_status); // 停止等待子进程结束
if (WIFEXITED(child_status)) {
cout << "child exited, exit code=" << WEXITSTATUS(child_status) << endl;
if (WEXITSTATUS(child_status) == 1) {
cout << "child exec error!\n";
}
}
else if (WIFSIGNALED(child_status)) {
cout << "child killed (signal " << WTERMSIG(child_status) << ")\n";
if(WTERMSIG(child_status) == 9) {
exit(0);
}
}
else if (WCOREDUMP(child_status)) { //检测不到core文件类型
cout << "child core file generated"<<endl;
}
else if (WIFSTOPPED(child_status)) {
cout << "child stopped (signal " << WSTOPSIG(child_status) << ")"<<endl;
}
else if (WIFCONTINUED(child_status)) {
cout << "child continued!"<<endl;
}
else {
cout << "Unexpected child_status (" << child_status << ")\n";
}
sprintf(core_file, "core.%d", child_pid);
if(access(core_file, 0) == 0){ //core文件改名
gettimeofday(&tms,NULL);
strftime(time_now, 22, "%Y%m%d%H%M%S", localtime(&tms.tv_sec));
sprintf(core_name, "%s_%s", core_file, time_now);
assert(rename(core_file, core_name) == 0);
}
exit(0);
}
while(1) {
sleep(1);
cout << "child is running..." <<endl;
char *p = NULL;
strcpy(p, "aoyang"); //会段错误,加上ulimit -c unlimited,生成core文件
}
return 0;
}
int main()
{
set_signal_hander();
check_signal_core();
return 0;
}
2、编译运行
g++ -o process_signal process_signal.cpp
ulimit -c unlimited
./process_signal
子进程出现段错误,被父进程捕获,生成的core文件被重新命名为core.9842_20151106104335。
三、总结
(1)不同系统下生成的core的命名方式不同,可以进行调整。。
(2)可以在子进程中去掉while循环,加上相应的运行代码。
(3)若有建议,请留言,在此先感谢!。