linux下c/c++实例之四父检测子进程和信号处理

一、简介

      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)若有建议,请留言,在此先感谢!。
 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

乌托邦2号

博文不易,支持的请给予小小打赏

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值