c:在exec()中捕获一个在子进程中运行的段错误

Flo*_*ian 2 c popen segmentation-fault

编辑:

我正在尝试编写一个简单的冒烟测试,其中测试了所有选项和合理的参数.

我使用popen()来执行应该测试的程序.使用这种方法不起作用,因为如果进程因信号而死(SIGINT,SIGSEGV ...),来自popen()的管道不会告诉我发生了什么.

编写信号处理程序并没有帮助,因为popen创建了一个接收信号而不是我的冒烟的新过程.

由于答案,我使用pipe(),fork()和execv()来创建我自己的popen() - 版本.

当程序现在段错误时,管道是无用的(读取导致奇怪的行为 - >阻止该过程,直到我向父母发送sigkill!)

为了避免这种情况,我尝试了不同的东西,我的解决方案如下(这很简单,但我需要一段时间来弄明白).所以这是我的示例代码:

static int child_dead = 0;

void sigaction_sigchld(int signal) { /* Child died */
    child_dead = 1;
}

int main(int argc, char *argv[], char *env[])
{
    char *crashing_program = "/program_path/and_name";
    int ret;
    int byte;

    pid = fork();

    if(pid == 0) /* Child */
    {
        execve(crashing_program, argv, env);

        /* if execve returns that it mus have failed! */
        fprintf(stderr, "Exec failed\n");
        _exit(-1);
    } else /* Parent */
    {
        if(!child_dead)
        {
            byte = read(pipe_out[1], line, BUFFSIZE);
            if(!byte){
                perror("Smoketest:Line:xxx");
            } else
            {
                fprintf(stdout, line);
            }
        }
        wait(&child_status);
        /*
          check if the child died with SIGSEGV etc
        */
    }
Run Code Online (Sandbox Code Playgroud)

这似乎工作得很好,只要我一次只有一个孩子,这对我来说已经足够了.我有任何人有更好的想法或任何tipps我会很高兴更新此条目.

最后但同样重要的是:当然使用这种方法可能无法进行任何清理.

干杯.

Ada*_*eld 7

请参阅文档waitpid(2).您可以使用一堆宏来测试子进程的终止方式.特别是,您可以使用WIFSIGNALED()WTERMSIG()测试子进程是否被信号终止,如果是,则发出以下信号:

int status = pclose(...);
if (WIFSIGNALED(status))
{
    // It was terminated by a signal
    if (WTERMSIG(status) == SIGSEGV)
    {
        // It was terminated by a segfault
    }
}
Run Code Online (Sandbox Code Playgroud)

编辑:如评论中所述,您宁愿使用fork和exec,然后使用waitpid(2)正确更新状态.