Ignore SIGPROF signal during clone()/fork() call. clone()/fork() call hangs permanently if it consumes more cpu than the SIGPROF signal timer interval (by Nabeel Mian).

This commit is contained in:
vladlosev
2011-09-09 05:42:09 +00:00
parent 294f69f957
commit 4b07d73f4e
2 changed files with 76 additions and 0 deletions

View File

@@ -43,6 +43,11 @@
# include <errno.h>
# include <fcntl.h>
# include <limits.h>
# if GTEST_OS_LINUX
# include <signal.h>
# endif // GTEST_OS_LINUX
# include <stdarg.h>
# if GTEST_OS_WINDOWS
@@ -998,6 +1003,18 @@ static pid_t ExecDeathTestSpawnChild(char* const* argv, int close_fd) {
GTEST_DEATH_TEST_CHECK_SYSCALL_(close(cwd_fd));
# else // GTEST_OS_QNX
# if GTEST_OS_LINUX
// When a SIGPROF signal is received while fork() or clone() are executing,
// the process may hang. To avoid this, we ignore SIGPROF here and re-enable
// it after the call to fork()/clone() is complete.
struct sigaction saved_sigprof_action;
struct sigaction ignore_sigprof_action;
memset(&ignore_sigprof_action, 0, sizeof(ignore_sigprof_action));
sigemptyset(&ignore_sigprof_action.sa_mask);
ignore_sigprof_action.sa_handler = SIG_IGN;
GTEST_DEATH_TEST_CHECK_SYSCALL_(sigaction(
SIGPROF, &ignore_sigprof_action, &saved_sigprof_action));
# endif // GTEST_OS_LINUX
# if GTEST_HAS_CLONE
const bool use_fork = GTEST_FLAG(death_test_use_fork);
@@ -1025,6 +1042,10 @@ static pid_t ExecDeathTestSpawnChild(char* const* argv, int close_fd) {
_exit(0);
}
# endif // GTEST_OS_QNX
# if GTEST_OS_LINUX
GTEST_DEATH_TEST_CHECK_SYSCALL_(
sigaction(SIGPROF, &saved_sigprof_action, NULL));
# endif // GTEST_OS_LINUX
GTEST_DEATH_TEST_CHECK_(child_pid != -1);
return child_pid;