我在最新版本的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 foo
或g++ foo.cpp -o foo
对其进行编译并使用./foo
运行它,按预期运行需要很长时间。
现在执行lldb ./foo
或gdb ./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用户没有发生这种情况,可能只是我的计算机搞砸了?
答案 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信号并导致父进程被调试器中断 - 但我不清楚导致长睡眠()调用早期结束的原因是什么在这个具体案例中。