diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/gtest-death-test.cc | 25 | ||||
-rw-r--r-- | src/gtest-internal-inl.h | 4 | ||||
-rw-r--r-- | src/gtest.cc | 2 |
3 files changed, 29 insertions, 2 deletions
diff --git a/src/gtest-death-test.cc b/src/gtest-death-test.cc index b667682f..6499842c 100644 --- a/src/gtest-death-test.cc +++ b/src/gtest-death-test.cc @@ -68,6 +68,17 @@ GTEST_DEFINE_string_( "\"fast\" (child process runs the death test immediately " "after forking)."); +GTEST_DEFINE_bool_( + death_test_use_fork, + internal::BoolFromGTestEnv("death_test_use_fork", false), + "Instructs to use fork()/_exit() instead of clone() in death tests. " + "Useful when running under valgrind or similar tools if those " + "do not support clone(). Valgrind 3.3.1 will just fail if " + "it sees an unsupported combination of clone() flags. " + "It is not recommended to use this flag w/o valgrind though it will " + "work in 99% of the cases. Once valgrind is fixed, this flag will " + "most likely be removed."); + namespace internal { GTEST_DEFINE_string_( internal_run_death_test, "", @@ -603,8 +614,18 @@ static pid_t ExecDeathTestFork(char* const* argv, int close_fd) { void* const stack_top = static_cast<char*>(stack) + (stack_grows_down ? stack_size : 0); ExecDeathTestArgs args = { argv, close_fd }; - const pid_t child_pid = clone(&ExecDeathTestChildMain, stack_top, - SIGCHLD, &args); + pid_t child_pid; + if (GTEST_FLAG(death_test_use_fork)) { + // Valgrind-friendly version. As of valgrind 3.3.1 the clone() call below + // is not supported (valgrind will fail with an error message). + if ((child_pid = fork()) == 0) { + ExecDeathTestChildMain(&args); + _exit(0); + } + } else { + child_pid = clone(&ExecDeathTestChildMain, stack_top, + SIGCHLD, &args); + } GTEST_DEATH_TEST_CHECK_(child_pid != -1); GTEST_DEATH_TEST_CHECK_(munmap(stack, stack_size) != -1); return child_pid; diff --git a/src/gtest-internal-inl.h b/src/gtest-internal-inl.h index b8f67c18..353c40a6 100644 --- a/src/gtest-internal-inl.h +++ b/src/gtest-internal-inl.h @@ -66,6 +66,7 @@ namespace testing { GTEST_DECLARE_bool_(break_on_failure); GTEST_DECLARE_bool_(catch_exceptions); GTEST_DECLARE_string_(color); +GTEST_DECLARE_bool_(death_test_use_fork); GTEST_DECLARE_string_(filter); GTEST_DECLARE_bool_(list_tests); GTEST_DECLARE_string_(output); @@ -100,6 +101,7 @@ class GTestFlagSaver { catch_exceptions_ = GTEST_FLAG(catch_exceptions); color_ = GTEST_FLAG(color); death_test_style_ = GTEST_FLAG(death_test_style); + death_test_use_fork_ = GTEST_FLAG(death_test_use_fork); filter_ = GTEST_FLAG(filter); internal_run_death_test_ = GTEST_FLAG(internal_run_death_test); list_tests_ = GTEST_FLAG(list_tests); @@ -114,6 +116,7 @@ class GTestFlagSaver { GTEST_FLAG(catch_exceptions) = catch_exceptions_; GTEST_FLAG(color) = color_; GTEST_FLAG(death_test_style) = death_test_style_; + GTEST_FLAG(death_test_use_fork) = death_test_use_fork_; GTEST_FLAG(filter) = filter_; GTEST_FLAG(internal_run_death_test) = internal_run_death_test_; GTEST_FLAG(list_tests) = list_tests_; @@ -127,6 +130,7 @@ class GTestFlagSaver { bool catch_exceptions_; String color_; String death_test_style_; + bool death_test_use_fork_; String filter_; String internal_run_death_test_; bool list_tests_; diff --git a/src/gtest.cc b/src/gtest.cc index a9ca334a..ae20d874 100644 --- a/src/gtest.cc +++ b/src/gtest.cc @@ -3867,6 +3867,8 @@ void ParseGoogleTestFlagsOnlyImpl(int* argc, CharType** argv) { ParseStringFlag(arg, kColorFlag, >EST_FLAG(color)) || ParseStringFlag(arg, kDeathTestStyleFlag, >EST_FLAG(death_test_style)) || + ParseBoolFlag(arg, kDeathTestUseFork, + >EST_FLAG(death_test_use_fork)) || ParseStringFlag(arg, kFilterFlag, >EST_FLAG(filter)) || ParseStringFlag(arg, kInternalRunDeathTestFlag, >EST_FLAG(internal_run_death_test)) || |