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我会很高兴更新此条目.
最后但同样重要的是:当然使用这种方法可能无法进行任何清理.
干杯.
请参阅文档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)正确更新状态.