lldb / gdb有什么问题,忽略OS X中的第一个sleep()语句?

时间:2012-09-26 01:45:40

标签: c++ gdb fork sleep lldb

我在最新版本的OS X 10.8.2上遇到了以下问题,最新的Xcode 4.5。

采取以下简单的代码:

#include <iostream>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>

int main(int argc, const char * argv[])
{
    pid_t pid = fork();

    if (0 == pid)
    {
        std::cout << "Child process!\n";

        exit(0);
    }
    else if (-1 == pid)
    {
        std::cout << "Error forking.\n";
    }
    else
    {
        std::cout << "In parent, created pid " << pid << ".\n";

        sleep(100000);      // Sleep a long time - GDB/LLDB ignores the first sleep statement
        sleep(3);           // Sleep 3 more seconds - GDB/LLDB doesn't ignore the second sleep statement

        std::cout << "Done in parent!\n";
    }

    return 0;
}

使用clang++ foo.cpp -o foog++ foo.cpp -o foo对其进行编译并使用./foo运行它,按预期运行需要很长时间。

现在执行lldb ./foogdb ./foo,然后执行run并注意它在3秒内完成。无论何时使用任何调试器,第一个睡眠语句似乎都被忽略了。

由于Xcode在运行项目时默认使用lldb,因此将上述代码粘贴到空白的Xcode项目中并执行Product-&gt; Run也会产生类似的结果。

我在使用gdb 7.2的Linux机器上尝试了相同的实验,问题是在那里发生。

这是Apple使用的旧版gdb中的错误(gdb 6.3.50-20050815(Apple版本gdb-1822)),还是其他的?如果其他OS X用户没有发生这种情况,可能只是我的计算机搞砸了?

2 个答案:

答案 0 :(得分:2)

虽然很多人不使用它,sleep实际上有一个返回值。

man 3 sleep

  

返回值

If the sleep() function returns because the requested time has elapsed,
the value returned will be zero.  If the sleep() function returns due
to the delivery of a signal, the value returned will be the unslept amount
(the requested time minus the time actually slept) in seconds.

果然,考虑到观察到的行为,会返回预期值。

答案 1 :(得分:1)

我认为问题是由于调试器想要暂停进程的任何时候,如果该进程正处于系统调用的中间(它正在kernel-land中执行代码),那么系统调用将被中止Mac OS X上的EINTR风格。我不知道Linux系统如何处理这个问题,但这就是在Mac OS X上发生的事情。如果你运行你的程序,并在一个单独的窗口中用lldb附加它并继续这个过程,你将会找到你的睡眠(100000);一旦执行恢复,呼叫就会终止。似乎必须在子进程退出时广播一个SIGCHLD信号并导致父进程被调试器中断 - 但我不清楚导致长睡眠()调用早期结束的原因是什么在这个具体案例中。