我一直在编写一个生成子进程的程序,并调用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.
}
waitpid
状态的联机帮助页WIFEXITED
:
WIFEXITED(status)
returns true if the child terminated normally, that is, by calling exit(3) or
_exit(2), or by returning from main().
我的意思是它应该在成功时返回一个整数!= 0,这在我的程序执行中没有发生,因为我观察到WIFEXITED(status) == 0
但是,从命令行执行相同的程序会导致$? == 0
,从 gdb 开始会导致:
[Inferior 1 (process 31934) exited normally]
该程序运行正常,除了触发的警告,这让我觉得这里发生了其他事情,我错过了。
编辑:
正如评论中建议的那样,我检查了孩子是否通过段错误终止,并且确实WIFSIGNALED(status)
返回 1,并WTERMSIG(status)
返回 11,即SIGSEGV
.
但我不明白的是,为什么通过 execv 的调用会因段错误而失败,而通过 gdb 或 shell 的相同调用会成功?
EDIT2:
我的应用程序的行为很大程度上取决于子进程的行为,特别是子进程在声明的函数中写入的文件__attribute__ ((destructor))
。waitpid
调用返回后,此文件存在并正确生成,这意味着段错误发生在另一个析构函数的某个地方,或者我无法控制的某个地方。