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

编辑:

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

我使用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 */ } 

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

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

干杯。

请参阅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 } } 

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