aboutsummaryrefslogtreecommitdiffstats
path: root/test
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
commit4b07d73f4e683d85546d78793a9914a4b5d3d98e (patch)
tree4423fe5ca3a26ee734cbe8a8dc9c589570bd4a31 /test
parent294f69f9575bb3b56ca95a40968862726cc57e1f (diff)
downloadgoogletest-4b07d73f4e683d85546d78793a9914a4b5d3d98e.tar.gz
googletest-4b07d73f4e683d85546d78793a9914a4b5d3d98e.tar.bz2
googletest-4b07d73f4e683d85546d78793a9914a4b5d3d98e.zip
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).
Diffstat (limited to 'test')
-rw-r--r--test/gtest-death-test_test.cc55
1 files changed, 55 insertions, 0 deletions
diff --git a/test/gtest-death-test_test.cc b/test/gtest-death-test_test.cc
index bcf8e2a3..afbdf8a2 100644
--- a/test/gtest-death-test_test.cc
+++ b/test/gtest-death-test_test.cc
@@ -52,6 +52,10 @@ using testing::internal::AlwaysTrue;
# include <signal.h>
# include <stdio.h>
+# if GTEST_OS_LINUX
+# include <sys/time.h>
+# endif // GTEST_OS_LINUX
+
# include "gtest/gtest-spi.h"
// Indicates that this translation unit is part of Google Test's
@@ -372,6 +376,57 @@ TEST_F(TestForDeathTest, FastDeathTestInChangedDir) {
ASSERT_DEATH(_exit(1), "");
}
+# if GTEST_OS_LINUX
+void SigprofAction(int, siginfo_t*, void*) { /* no op */ }
+
+// Sets SIGPROF action and ITIMER_PROF timer (interval: 1ms).
+void SetSigprofActionAndTimer() {
+ struct itimerval timer;
+ timer.it_interval.tv_sec = 0;
+ timer.it_interval.tv_usec = 1;
+ timer.it_value = timer.it_interval;
+ ASSERT_EQ(0, setitimer(ITIMER_PROF, &timer, NULL));
+ struct sigaction signal_action;
+ memset(&signal_action, 0, sizeof(signal_action));
+ sigemptyset(&signal_action.sa_mask);
+ signal_action.sa_sigaction = SigprofAction;
+ signal_action.sa_flags = SA_RESTART | SA_SIGINFO;
+ ASSERT_EQ(0, sigaction(SIGPROF, &signal_action, NULL));
+}
+
+// Disables ITIMER_PROF timer and ignores SIGPROF signal.
+void DisableSigprofActionAndTimer(struct sigaction* old_signal_action) {
+ struct itimerval timer;
+ timer.it_interval.tv_usec = 0;
+ timer.it_value.tv_usec = 0;
+ ASSERT_EQ(0, setitimer(ITIMER_PROF, &timer, NULL));
+ struct sigaction signal_action;
+ memset(&signal_action, 0, sizeof(signal_action));
+ sigemptyset(&signal_action.sa_mask);
+ signal_action.sa_handler = SIG_IGN;
+ ASSERT_EQ(0, sigaction(SIGPROF, &signal_action, old_signal_action));
+}
+
+// Tests that death tests work when SIGPROF handler and timer are set.
+TEST_F(TestForDeathTest, FastSigprofActionSet) {
+ testing::GTEST_FLAG(death_test_style) = "fast";
+ SetSigprofActionAndTimer();
+ EXPECT_DEATH(_exit(1), "");
+ struct sigaction old_signal_action;
+ DisableSigprofActionAndTimer(&old_signal_action);
+ EXPECT_TRUE(old_signal_action.sa_sigaction == SigprofAction);
+}
+
+TEST_F(TestForDeathTest, ThreadSafeSigprofActionSet) {
+ testing::GTEST_FLAG(death_test_style) = "threadsafe";
+ SetSigprofActionAndTimer();
+ EXPECT_DEATH(_exit(1), "");
+ struct sigaction old_signal_action;
+ DisableSigprofActionAndTimer(&old_signal_action);
+ EXPECT_TRUE(old_signal_action.sa_sigaction == SigprofAction);
+}
+# endif // GTEST_OS_LINUX
+
// Repeats a representative sample of death tests in the "threadsafe" style:
TEST_F(TestForDeathTest, StaticMemberFunctionThreadsafeStyle) {