summaryrefslogtreecommitdiff
path: root/src/gtest-death-test.cc
diff options
context:
space:
mode:
authorvladlosev <vladlosev@861a406c-534a-0410-8894-cb66d6ee9925>2011-09-09 05:42:09 +0000
committervladlosev <vladlosev@861a406c-534a-0410-8894-cb66d6ee9925>2011-09-09 05:42:09 +0000
commit7c3004c3013fe4adf5e0447d37ee2d0501c2b227 (patch)
tree4423fe5ca3a26ee734cbe8a8dc9c589570bd4a31 /src/gtest-death-test.cc
parente0e93e5547c71906b6c70eb06e781ced1dae0407 (diff)
downloadgoogletest-7c3004c3013fe4adf5e0447d37ee2d0501c2b227.tar.gz
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).
git-svn-id: http://googletest.googlecode.com/svn/trunk@592 861a406c-534a-0410-8894-cb66d6ee9925
Diffstat (limited to 'src/gtest-death-test.cc')
-rw-r--r--src/gtest-death-test.cc21
1 files changed, 21 insertions, 0 deletions
diff --git a/src/gtest-death-test.cc b/src/gtest-death-test.cc
index fb4a9f9..2f0b0e3 100644
--- a/src/gtest-death-test.cc
+++ b/src/gtest-death-test.cc
@@ -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;