【问题标题】:Why waitpid return -1 when run in debugger?为什么在调试器中运行时waitpid返回-1?
【发布时间】:2014-02-28 12:33:22
【问题描述】:

我在Mac平台上使用fork创建进程,在父进程中等待子进程完成。但是waitpid 返回 -1 并且 errno 是 4 (EINTR)。

可以重现此问题的示例代码如下:

#include <iostream>
#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <assert.h>
int main(int argc, const char *argv[])
{
    pid_t pid = ::fork();
    if (pid == 0)
    {
        return 0;
    }

    int s = 0;
    if (::waitpid(pid, &s, 0) == -1)
    {
        printf("The errno is :%d\n", errno); // <<<The errno is 4(EINTR) in my machine.
        assert(false);  // <<<<This will be hit if run in debugger.
    }
    return 0;
}

当我在GDBLLDB 中运行此代码时,assert 将始终被命中。如果不在调试器中运行,它不会返回 -1。

我认为我对 debuggerfork/waitpid 的工作原理有些不理解。那么谁能解释为什么会发生这种情况?

【问题讨论】:

  • 如果你将它包含在你的问题中,你的 printf 的输出会更能说明问题(并用 '\n' 尾随它来刷新它。很确定它将是 EINTR;一个中断的系统打电话。
  • Seams Xcode 显示 errno 值不正确,实际 errno 值为 4(EINTR)。我已经在这篇文章中更正了。
  • 2 是SIGINT,这也是有道理的。
  • 如果返回 EINTR,waitpid 是可重新启动的。相应地构造一个循环。我不得不在我的 Mac 上做同样的事情。
  • 唯一一个公众反响非常好的主题帖子是:stackoverflow.com/a/2708512/715269

标签: c macos posix fork waitpid


【解决方案1】:

调试器正在向进程发送信号。正如 WhozCraig 所说,这些应该通过检测 EINTR 并在循环中再次调用 waitpid 来处理。请注意,在调试器中运行 child 进程时,调试器可能会将父进程更改为调试器的 PID,因此子 PID 上的 waitpid 将失败,认为子进程已退出,即使它已经退出不是。当调试器退出时,它将子进程的 PPID 恢复为原始父进程的 PID。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-05-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多