0

我正在尝试从父进程访问分叉子进程的退出状态,但我得到了奇怪的答案。有时,我得到 256 或有时我得到一个负数,具体取决于我指定 &status 还是仅指定 status。我知道我真的很亲近。有人可以为我提供一点帮助,我将如何获得 EXIT_STATUS

这是我的代码

pid_t  pid;
int *status;
if((pid = fork()) < 0)
    fprintf(stdout, "Error forking child process\n");

else if (pid == 0)
{
    execvp(input[0], input);
    fprintf(stdout, "Invalid process!!\n");
    _exit(EXIT_FAILURE);

}
else
{
    while (waitpid(-1, status, 0) != pid);
    fprintf(stdout, "The status is %d\n", &status);
}
4

2 回答 2

4

您看到这种行为是因为您没有初始化您正在使用的指针,因此您正在调用undefined behavior,这意味着,从字面上看,任何事情都可能发生。尝试更改statusint(而不是int*):

int status;
/* ... */
while (waitpid(-1, &status, 0) != pid);
fprintf(stdout, "The status is %d\n", status);

另一方面,您的代码:

int * status;

这会创建一个指向 int 的指针并且不会对其进行初始化。

while (waitpid(-1, status, 0) != pid);

在这里,您将此指针传递给 waitpid(),它将写入指向的位置。由于您尚未初始化指针,因此它正在写入未指定的内存位置!这可能会导致进程崩溃或覆盖其他地方分配的内存,这可能会导致以后自发崩溃或数据损坏!

fprintf(stdout, "The status is %d\n", &status);

这会打印出指针变量的地址——而不是它指向的值!使用*status而不是 &status可能允许这部分工作,但您仍在使用未初始化的指针。

我强烈建议您将编译器的警告设置调到最大值(-Wall使用 gcc 传递)以使其对所有内容发出警告。它会捕捉到未初始化指针的使用,并且它还可能警告您将%d格式说明符与指针类型值一起使用。

于 2012-11-11T03:32:54.337 回答
0

不要使用大数或负数作为返回值,它们会混淆事物。例如,在 32 位系统上:

对于 int:255 是0x000000ff-1 是0xffffffff. 因此,如果您返回 -1 中的任何八个位块,它们都是0xff或 255。

如果你调用 exit(1) 或 exit(2) 或 exit(3),或其他一些小的正数,事情对你来说会更好。在父母一定WIFEXITED(&status)要先打电话。

由于您似乎想使用退出状态来“告诉”您发生的问题,请尝试 sysexits:http ://www.gsp.com/cgi-bin/man.cgi?section=3&topic=sysexits

或者简单地使用EXIT SUCCESSor EXIT_FAILUREex: return EXIT_SUCCESS;or exit(EXIT_FAILURE); which are 保证工作 - 即,给你一个成功或失败作为回报。

于 2012-11-11T18:12:03.557 回答