Что не так с lldb / gdb, игнорируя первый оператор sleep () в OS X?

Я столкнулся со следующей проблемой в последней версии 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-> Run будут иметь аналогичные результаты.

Я попробовал тот же эксперимент на машине Linux с GDB 7.2, и проблема делает не происходят там.

Это ошибка в более старой версии GDB, которую использует Apple (GDB 6.3.50-20050815 (версия Apple GDB-1822)), или это что-то еще? Возможно только мой компьютер испорчен, если это не случается с другими пользователями OS X?

1

Решение

хотя многие люди не используют его, 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.

Конечно, ожидаемое значение возвращается с учетом наблюдаемого поведения.

2

Другие решения

Я думаю, что проблема связана с тем фактом, что всякий раз, когда отладчик хочет приостановить процесс, если этот процесс находится в середине системного вызова (он выполняет код в стране ядра), этот системный вызов прерывается в стиле EINTR на Mac OS X. Я не знаю, как системы Linux справляются с этим, но именно это происходит в Mac OS X. Если вы запустите свою программу и в отдельном окне присоединитесь к ней с помощью lldb и продолжите процесс, вы обнаружите, что ваш сон (100000); вызов прекращается, как только выполнение возобновляется. Похоже, что при выходе дочернего процесса должен передаваться сигнал SIGCHLD, и это вызывает прерывание родительского процесса отладчиком — но я не совсем понимаю, что приводит к тому, что длинный вызов sleep () завершается досрочно. в этом конкретном случае.

1

По вопросам рекламы [email protected]