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:
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user