我正在编写一个程序,它会创建一个子进程,并调用waitpid
等待子进程的结束。代码如下:
// fork & exec the child
pid_t pid = fork();
if (pid == -1)
// here is error handling code that is **not** triggered
if (!pid)
{
// binary_invocation is an array of the child process program and its arguments
execv(args.binary_invocation[0], (char * const*)args.binary_invocation);
// here is some error handling code that is **not** triggered
}
else
{
int status = 0;
pid_t res = waitpid(pid, &status, 0);
// here I see pid_t being a positive integer > 0
// and status being 11, which means WIFEXITED(status) is 0.
// this triggers a warning in my programs output.
}
< p > waitpid
的 man 页面对于 WIFEXITED
的说明如下:
WIFEXITED(status)
returns true if the child terminated normally, that is, by calling exit(3) or
_exit(2), or by returning from main().
我理解为函数应该返回一个非零整数表示成功,但在我的程序执行中并未发生这种情况,因为我观察到WIFEXITED(status) == 0
然而,从命令行执行同一程序会导致$? == 0
,从gdb启动则结果如下:
[Inferior 1 (process 31934) exited normally]
该程序表现正常,除了触发的警告之外,这让我认为还有其他问题存在,而我自己没有意识到。
编辑:如下方评论所建议,我检查了子进程是否通过段错误终止,确实,WIFSIGNALED(status)返回1,WTERMSIG(status)返回11,即SIGSEGV。
然而,我不明白为什么通过execv调用会失败并导致段错误,而通过gdb或shell进行同样的调用却会成功?
编辑2:我的应用程序行为在很大程度上取决于子进程的行为,尤其是子进程在声明为__attribute__((destructor))的函数中写入的文件。waitpid调用返回后,这个文件存在且生成正确,这意味着段错误发生在另一个析构函数中,或者发生在我无法控制的某个地方。
SIGSEGV
。非信号退出是传递给_exit
或exit
或由main
返回的值的低8位的256倍。如果您在像Linux这样具有strace
的平台上,请使用它(带有-f
标志)查看子进程是否由于对execv
的错误调用或成功执行后而收到信号。 - rob mayoffargs.binary_invocation
是什么样子的?它来自哪里?你创建了它吗? - Dabo