michael@0: // Copyright 2005, Google Inc. michael@0: // All rights reserved. michael@0: // michael@0: // Redistribution and use in source and binary forms, with or without michael@0: // modification, are permitted provided that the following conditions are michael@0: // met: michael@0: // michael@0: // * Redistributions of source code must retain the above copyright michael@0: // notice, this list of conditions and the following disclaimer. michael@0: // * Redistributions in binary form must reproduce the above michael@0: // copyright notice, this list of conditions and the following disclaimer michael@0: // in the documentation and/or other materials provided with the michael@0: // distribution. michael@0: // * Neither the name of Google Inc. nor the names of its michael@0: // contributors may be used to endorse or promote products derived from michael@0: // this software without specific prior written permission. michael@0: // michael@0: // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS michael@0: // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT michael@0: // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR michael@0: // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT michael@0: // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, michael@0: // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT michael@0: // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, michael@0: // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY michael@0: // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT michael@0: // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE michael@0: // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. michael@0: // michael@0: // Author: wan@google.com (Zhanyong Wan), vladl@google.com (Vlad Losev) michael@0: // michael@0: // This file implements death tests. michael@0: michael@0: #include "gtest/gtest-death-test.h" michael@0: #include "gtest/internal/gtest-port.h" michael@0: michael@0: #if GTEST_HAS_DEATH_TEST michael@0: michael@0: # if GTEST_OS_MAC michael@0: # include michael@0: # endif // GTEST_OS_MAC michael@0: michael@0: # include michael@0: # include michael@0: # include michael@0: michael@0: # if GTEST_OS_LINUX michael@0: # include michael@0: # endif // GTEST_OS_LINUX michael@0: michael@0: # include michael@0: michael@0: # if GTEST_OS_WINDOWS michael@0: # include michael@0: # else michael@0: # include michael@0: # include michael@0: # endif // GTEST_OS_WINDOWS michael@0: michael@0: # if GTEST_OS_QNX michael@0: # include michael@0: # endif // GTEST_OS_QNX michael@0: michael@0: #endif // GTEST_HAS_DEATH_TEST michael@0: michael@0: #include "gtest/gtest-message.h" michael@0: #include "gtest/internal/gtest-string.h" michael@0: michael@0: // Indicates that this translation unit is part of Google Test's michael@0: // implementation. It must come before gtest-internal-inl.h is michael@0: // included, or there will be a compiler error. This trick is to michael@0: // prevent a user from accidentally including gtest-internal-inl.h in michael@0: // his code. michael@0: #define GTEST_IMPLEMENTATION_ 1 michael@0: #include "src/gtest-internal-inl.h" michael@0: #undef GTEST_IMPLEMENTATION_ michael@0: michael@0: namespace testing { michael@0: michael@0: // Constants. michael@0: michael@0: // The default death test style. michael@0: static const char kDefaultDeathTestStyle[] = "fast"; michael@0: michael@0: GTEST_DEFINE_string_( michael@0: death_test_style, michael@0: internal::StringFromGTestEnv("death_test_style", kDefaultDeathTestStyle), michael@0: "Indicates how to run a death test in a forked child process: " michael@0: "\"threadsafe\" (child process re-executes the test binary " michael@0: "from the beginning, running only the specific death test) or " michael@0: "\"fast\" (child process runs the death test immediately " michael@0: "after forking)."); michael@0: michael@0: GTEST_DEFINE_bool_( michael@0: death_test_use_fork, michael@0: internal::BoolFromGTestEnv("death_test_use_fork", false), michael@0: "Instructs to use fork()/_exit() instead of clone() in death tests. " michael@0: "Ignored and always uses fork() on POSIX systems where clone() is not " michael@0: "implemented. Useful when running under valgrind or similar tools if " michael@0: "those do not support clone(). Valgrind 3.3.1 will just fail if " michael@0: "it sees an unsupported combination of clone() flags. " michael@0: "It is not recommended to use this flag w/o valgrind though it will " michael@0: "work in 99% of the cases. Once valgrind is fixed, this flag will " michael@0: "most likely be removed."); michael@0: michael@0: namespace internal { michael@0: GTEST_DEFINE_string_( michael@0: internal_run_death_test, "", michael@0: "Indicates the file, line number, temporal index of " michael@0: "the single death test to run, and a file descriptor to " michael@0: "which a success code may be sent, all separated by " michael@0: "the '|' characters. This flag is specified if and only if the current " michael@0: "process is a sub-process launched for running a thread-safe " michael@0: "death test. FOR INTERNAL USE ONLY."); michael@0: } // namespace internal michael@0: michael@0: #if GTEST_HAS_DEATH_TEST michael@0: michael@0: namespace internal { michael@0: michael@0: // Valid only for fast death tests. Indicates the code is running in the michael@0: // child process of a fast style death test. michael@0: static bool g_in_fast_death_test_child = false; michael@0: michael@0: // Returns a Boolean value indicating whether the caller is currently michael@0: // executing in the context of the death test child process. Tools such as michael@0: // Valgrind heap checkers may need this to modify their behavior in death michael@0: // tests. IMPORTANT: This is an internal utility. Using it may break the michael@0: // implementation of death tests. User code MUST NOT use it. michael@0: bool InDeathTestChild() { michael@0: # if GTEST_OS_WINDOWS michael@0: michael@0: // On Windows, death tests are thread-safe regardless of the value of the michael@0: // death_test_style flag. michael@0: return !GTEST_FLAG(internal_run_death_test).empty(); michael@0: michael@0: # else michael@0: michael@0: if (GTEST_FLAG(death_test_style) == "threadsafe") michael@0: return !GTEST_FLAG(internal_run_death_test).empty(); michael@0: else michael@0: return g_in_fast_death_test_child; michael@0: #endif michael@0: } michael@0: michael@0: } // namespace internal michael@0: michael@0: // ExitedWithCode constructor. michael@0: ExitedWithCode::ExitedWithCode(int exit_code) : exit_code_(exit_code) { michael@0: } michael@0: michael@0: // ExitedWithCode function-call operator. michael@0: bool ExitedWithCode::operator()(int exit_status) const { michael@0: # if GTEST_OS_WINDOWS michael@0: michael@0: return exit_status == exit_code_; michael@0: michael@0: # else michael@0: michael@0: return WIFEXITED(exit_status) && WEXITSTATUS(exit_status) == exit_code_; michael@0: michael@0: # endif // GTEST_OS_WINDOWS michael@0: } michael@0: michael@0: # if !GTEST_OS_WINDOWS michael@0: // KilledBySignal constructor. michael@0: KilledBySignal::KilledBySignal(int signum) : signum_(signum) { michael@0: } michael@0: michael@0: // KilledBySignal function-call operator. michael@0: bool KilledBySignal::operator()(int exit_status) const { michael@0: return WIFSIGNALED(exit_status) && WTERMSIG(exit_status) == signum_; michael@0: } michael@0: # endif // !GTEST_OS_WINDOWS michael@0: michael@0: namespace internal { michael@0: michael@0: // Utilities needed for death tests. michael@0: michael@0: // Generates a textual description of a given exit code, in the format michael@0: // specified by wait(2). michael@0: static String ExitSummary(int exit_code) { michael@0: Message m; michael@0: michael@0: # if GTEST_OS_WINDOWS michael@0: michael@0: m << "Exited with exit status " << exit_code; michael@0: michael@0: # else michael@0: michael@0: if (WIFEXITED(exit_code)) { michael@0: m << "Exited with exit status " << WEXITSTATUS(exit_code); michael@0: } else if (WIFSIGNALED(exit_code)) { michael@0: m << "Terminated by signal " << WTERMSIG(exit_code); michael@0: } michael@0: # ifdef WCOREDUMP michael@0: if (WCOREDUMP(exit_code)) { michael@0: m << " (core dumped)"; michael@0: } michael@0: # endif michael@0: # endif // GTEST_OS_WINDOWS michael@0: michael@0: return m.GetString(); michael@0: } michael@0: michael@0: // Returns true if exit_status describes a process that was terminated michael@0: // by a signal, or exited normally with a nonzero exit code. michael@0: bool ExitedUnsuccessfully(int exit_status) { michael@0: return !ExitedWithCode(0)(exit_status); michael@0: } michael@0: michael@0: # if !GTEST_OS_WINDOWS michael@0: // Generates a textual failure message when a death test finds more than michael@0: // one thread running, or cannot determine the number of threads, prior michael@0: // to executing the given statement. It is the responsibility of the michael@0: // caller not to pass a thread_count of 1. michael@0: static String DeathTestThreadWarning(size_t thread_count) { michael@0: Message msg; michael@0: msg << "Death tests use fork(), which is unsafe particularly" michael@0: << " in a threaded context. For this test, " << GTEST_NAME_ << " "; michael@0: if (thread_count == 0) michael@0: msg << "couldn't detect the number of threads."; michael@0: else michael@0: msg << "detected " << thread_count << " threads."; michael@0: return msg.GetString(); michael@0: } michael@0: # endif // !GTEST_OS_WINDOWS michael@0: michael@0: // Flag characters for reporting a death test that did not die. michael@0: static const char kDeathTestLived = 'L'; michael@0: static const char kDeathTestReturned = 'R'; michael@0: static const char kDeathTestThrew = 'T'; michael@0: static const char kDeathTestInternalError = 'I'; michael@0: michael@0: // An enumeration describing all of the possible ways that a death test can michael@0: // conclude. DIED means that the process died while executing the test michael@0: // code; LIVED means that process lived beyond the end of the test code; michael@0: // RETURNED means that the test statement attempted to execute a return michael@0: // statement, which is not allowed; THREW means that the test statement michael@0: // returned control by throwing an exception. IN_PROGRESS means the test michael@0: // has not yet concluded. michael@0: // TODO(vladl@google.com): Unify names and possibly values for michael@0: // AbortReason, DeathTestOutcome, and flag characters above. michael@0: enum DeathTestOutcome { IN_PROGRESS, DIED, LIVED, RETURNED, THREW }; michael@0: michael@0: // Routine for aborting the program which is safe to call from an michael@0: // exec-style death test child process, in which case the error michael@0: // message is propagated back to the parent process. Otherwise, the michael@0: // message is simply printed to stderr. In either case, the program michael@0: // then exits with status 1. michael@0: void DeathTestAbort(const String& message) { michael@0: // On a POSIX system, this function may be called from a threadsafe-style michael@0: // death test child process, which operates on a very small stack. Use michael@0: // the heap for any additional non-minuscule memory requirements. michael@0: const InternalRunDeathTestFlag* const flag = michael@0: GetUnitTestImpl()->internal_run_death_test_flag(); michael@0: if (flag != NULL) { michael@0: FILE* parent = posix::FDOpen(flag->write_fd(), "w"); michael@0: fputc(kDeathTestInternalError, parent); michael@0: fprintf(parent, "%s", message.c_str()); michael@0: fflush(parent); michael@0: _exit(1); michael@0: } else { michael@0: fprintf(stderr, "%s", message.c_str()); michael@0: fflush(stderr); michael@0: posix::Abort(); michael@0: } michael@0: } michael@0: michael@0: // A replacement for CHECK that calls DeathTestAbort if the assertion michael@0: // fails. michael@0: # define GTEST_DEATH_TEST_CHECK_(expression) \ michael@0: do { \ michael@0: if (!::testing::internal::IsTrue(expression)) { \ michael@0: DeathTestAbort(::testing::internal::String::Format( \ michael@0: "CHECK failed: File %s, line %d: %s", \ michael@0: __FILE__, __LINE__, #expression)); \ michael@0: } \ michael@0: } while (::testing::internal::AlwaysFalse()) michael@0: michael@0: // This macro is similar to GTEST_DEATH_TEST_CHECK_, but it is meant for michael@0: // evaluating any system call that fulfills two conditions: it must return michael@0: // -1 on failure, and set errno to EINTR when it is interrupted and michael@0: // should be tried again. The macro expands to a loop that repeatedly michael@0: // evaluates the expression as long as it evaluates to -1 and sets michael@0: // errno to EINTR. If the expression evaluates to -1 but errno is michael@0: // something other than EINTR, DeathTestAbort is called. michael@0: # define GTEST_DEATH_TEST_CHECK_SYSCALL_(expression) \ michael@0: do { \ michael@0: int gtest_retval; \ michael@0: do { \ michael@0: gtest_retval = (expression); \ michael@0: } while (gtest_retval == -1 && errno == EINTR); \ michael@0: if (gtest_retval == -1) { \ michael@0: DeathTestAbort(::testing::internal::String::Format( \ michael@0: "CHECK failed: File %s, line %d: %s != -1", \ michael@0: __FILE__, __LINE__, #expression)); \ michael@0: } \ michael@0: } while (::testing::internal::AlwaysFalse()) michael@0: michael@0: // Returns the message describing the last system error in errno. michael@0: String GetLastErrnoDescription() { michael@0: return String(errno == 0 ? "" : posix::StrError(errno)); michael@0: } michael@0: michael@0: // This is called from a death test parent process to read a failure michael@0: // message from the death test child process and log it with the FATAL michael@0: // severity. On Windows, the message is read from a pipe handle. On other michael@0: // platforms, it is read from a file descriptor. michael@0: static void FailFromInternalError(int fd) { michael@0: Message error; michael@0: char buffer[256]; michael@0: int num_read; michael@0: michael@0: do { michael@0: while ((num_read = posix::Read(fd, buffer, 255)) > 0) { michael@0: buffer[num_read] = '\0'; michael@0: error << buffer; michael@0: } michael@0: } while (num_read == -1 && errno == EINTR); michael@0: michael@0: if (num_read == 0) { michael@0: GTEST_LOG_(FATAL) << error.GetString(); michael@0: } else { michael@0: const int last_error = errno; michael@0: GTEST_LOG_(FATAL) << "Error while reading death test internal: " michael@0: << GetLastErrnoDescription() << " [" << last_error << "]"; michael@0: } michael@0: } michael@0: michael@0: // Death test constructor. Increments the running death test count michael@0: // for the current test. michael@0: DeathTest::DeathTest() { michael@0: TestInfo* const info = GetUnitTestImpl()->current_test_info(); michael@0: if (info == NULL) { michael@0: DeathTestAbort("Cannot run a death test outside of a TEST or " michael@0: "TEST_F construct"); michael@0: } michael@0: } michael@0: michael@0: // Creates and returns a death test by dispatching to the current michael@0: // death test factory. michael@0: bool DeathTest::Create(const char* statement, const RE* regex, michael@0: const char* file, int line, DeathTest** test) { michael@0: return GetUnitTestImpl()->death_test_factory()->Create( michael@0: statement, regex, file, line, test); michael@0: } michael@0: michael@0: const char* DeathTest::LastMessage() { michael@0: return last_death_test_message_.c_str(); michael@0: } michael@0: michael@0: void DeathTest::set_last_death_test_message(const String& message) { michael@0: last_death_test_message_ = message; michael@0: } michael@0: michael@0: String DeathTest::last_death_test_message_; michael@0: michael@0: // Provides cross platform implementation for some death functionality. michael@0: class DeathTestImpl : public DeathTest { michael@0: protected: michael@0: DeathTestImpl(const char* a_statement, const RE* a_regex) michael@0: : statement_(a_statement), michael@0: regex_(a_regex), michael@0: spawned_(false), michael@0: status_(-1), michael@0: outcome_(IN_PROGRESS), michael@0: read_fd_(-1), michael@0: write_fd_(-1) {} michael@0: michael@0: // read_fd_ is expected to be closed and cleared by a derived class. michael@0: ~DeathTestImpl() { GTEST_DEATH_TEST_CHECK_(read_fd_ == -1); } michael@0: michael@0: void Abort(AbortReason reason); michael@0: virtual bool Passed(bool status_ok); michael@0: michael@0: const char* statement() const { return statement_; } michael@0: const RE* regex() const { return regex_; } michael@0: bool spawned() const { return spawned_; } michael@0: void set_spawned(bool is_spawned) { spawned_ = is_spawned; } michael@0: int status() const { return status_; } michael@0: void set_status(int a_status) { status_ = a_status; } michael@0: DeathTestOutcome outcome() const { return outcome_; } michael@0: void set_outcome(DeathTestOutcome an_outcome) { outcome_ = an_outcome; } michael@0: int read_fd() const { return read_fd_; } michael@0: void set_read_fd(int fd) { read_fd_ = fd; } michael@0: int write_fd() const { return write_fd_; } michael@0: void set_write_fd(int fd) { write_fd_ = fd; } michael@0: michael@0: // Called in the parent process only. Reads the result code of the death michael@0: // test child process via a pipe, interprets it to set the outcome_ michael@0: // member, and closes read_fd_. Outputs diagnostics and terminates in michael@0: // case of unexpected codes. michael@0: void ReadAndInterpretStatusByte(); michael@0: michael@0: private: michael@0: // The textual content of the code this object is testing. This class michael@0: // doesn't own this string and should not attempt to delete it. michael@0: const char* const statement_; michael@0: // The regular expression which test output must match. DeathTestImpl michael@0: // doesn't own this object and should not attempt to delete it. michael@0: const RE* const regex_; michael@0: // True if the death test child process has been successfully spawned. michael@0: bool spawned_; michael@0: // The exit status of the child process. michael@0: int status_; michael@0: // How the death test concluded. michael@0: DeathTestOutcome outcome_; michael@0: // Descriptor to the read end of the pipe to the child process. It is michael@0: // always -1 in the child process. The child keeps its write end of the michael@0: // pipe in write_fd_. michael@0: int read_fd_; michael@0: // Descriptor to the child's write end of the pipe to the parent process. michael@0: // It is always -1 in the parent process. The parent keeps its end of the michael@0: // pipe in read_fd_. michael@0: int write_fd_; michael@0: }; michael@0: michael@0: // Called in the parent process only. Reads the result code of the death michael@0: // test child process via a pipe, interprets it to set the outcome_ michael@0: // member, and closes read_fd_. Outputs diagnostics and terminates in michael@0: // case of unexpected codes. michael@0: void DeathTestImpl::ReadAndInterpretStatusByte() { michael@0: char flag; michael@0: int bytes_read; michael@0: michael@0: // The read() here blocks until data is available (signifying the michael@0: // failure of the death test) or until the pipe is closed (signifying michael@0: // its success), so it's okay to call this in the parent before michael@0: // the child process has exited. michael@0: do { michael@0: bytes_read = posix::Read(read_fd(), &flag, 1); michael@0: } while (bytes_read == -1 && errno == EINTR); michael@0: michael@0: if (bytes_read == 0) { michael@0: set_outcome(DIED); michael@0: } else if (bytes_read == 1) { michael@0: switch (flag) { michael@0: case kDeathTestReturned: michael@0: set_outcome(RETURNED); michael@0: break; michael@0: case kDeathTestThrew: michael@0: set_outcome(THREW); michael@0: break; michael@0: case kDeathTestLived: michael@0: set_outcome(LIVED); michael@0: break; michael@0: case kDeathTestInternalError: michael@0: FailFromInternalError(read_fd()); // Does not return. michael@0: break; michael@0: default: michael@0: GTEST_LOG_(FATAL) << "Death test child process reported " michael@0: << "unexpected status byte (" michael@0: << static_cast(flag) << ")"; michael@0: } michael@0: } else { michael@0: GTEST_LOG_(FATAL) << "Read from death test child process failed: " michael@0: << GetLastErrnoDescription(); michael@0: } michael@0: GTEST_DEATH_TEST_CHECK_SYSCALL_(posix::Close(read_fd())); michael@0: set_read_fd(-1); michael@0: } michael@0: michael@0: // Signals that the death test code which should have exited, didn't. michael@0: // Should be called only in a death test child process. michael@0: // Writes a status byte to the child's status file descriptor, then michael@0: // calls _exit(1). michael@0: void DeathTestImpl::Abort(AbortReason reason) { michael@0: // The parent process considers the death test to be a failure if michael@0: // it finds any data in our pipe. So, here we write a single flag byte michael@0: // to the pipe, then exit. michael@0: const char status_ch = michael@0: reason == TEST_DID_NOT_DIE ? kDeathTestLived : michael@0: reason == TEST_THREW_EXCEPTION ? kDeathTestThrew : kDeathTestReturned; michael@0: michael@0: GTEST_DEATH_TEST_CHECK_SYSCALL_(posix::Write(write_fd(), &status_ch, 1)); michael@0: // We are leaking the descriptor here because on some platforms (i.e., michael@0: // when built as Windows DLL), destructors of global objects will still michael@0: // run after calling _exit(). On such systems, write_fd_ will be michael@0: // indirectly closed from the destructor of UnitTestImpl, causing double michael@0: // close if it is also closed here. On debug configurations, double close michael@0: // may assert. As there are no in-process buffers to flush here, we are michael@0: // relying on the OS to close the descriptor after the process terminates michael@0: // when the destructors are not run. michael@0: _exit(1); // Exits w/o any normal exit hooks (we were supposed to crash) michael@0: } michael@0: michael@0: // Returns an indented copy of stderr output for a death test. michael@0: // This makes distinguishing death test output lines from regular log lines michael@0: // much easier. michael@0: static ::std::string FormatDeathTestOutput(const ::std::string& output) { michael@0: ::std::string ret; michael@0: for (size_t at = 0; ; ) { michael@0: const size_t line_end = output.find('\n', at); michael@0: ret += "[ DEATH ] "; michael@0: if (line_end == ::std::string::npos) { michael@0: ret += output.substr(at); michael@0: break; michael@0: } michael@0: ret += output.substr(at, line_end + 1 - at); michael@0: at = line_end + 1; michael@0: } michael@0: return ret; michael@0: } michael@0: michael@0: // Assesses the success or failure of a death test, using both private michael@0: // members which have previously been set, and one argument: michael@0: // michael@0: // Private data members: michael@0: // outcome: An enumeration describing how the death test michael@0: // concluded: DIED, LIVED, THREW, or RETURNED. The death test michael@0: // fails in the latter three cases. michael@0: // status: The exit status of the child process. On *nix, it is in the michael@0: // in the format specified by wait(2). On Windows, this is the michael@0: // value supplied to the ExitProcess() API or a numeric code michael@0: // of the exception that terminated the program. michael@0: // regex: A regular expression object to be applied to michael@0: // the test's captured standard error output; the death test michael@0: // fails if it does not match. michael@0: // michael@0: // Argument: michael@0: // status_ok: true if exit_status is acceptable in the context of michael@0: // this particular death test, which fails if it is false michael@0: // michael@0: // Returns true iff all of the above conditions are met. Otherwise, the michael@0: // first failing condition, in the order given above, is the one that is michael@0: // reported. Also sets the last death test message string. michael@0: bool DeathTestImpl::Passed(bool status_ok) { michael@0: if (!spawned()) michael@0: return false; michael@0: michael@0: const String error_message = GetCapturedStderr(); michael@0: michael@0: bool success = false; michael@0: Message buffer; michael@0: michael@0: buffer << "Death test: " << statement() << "\n"; michael@0: switch (outcome()) { michael@0: case LIVED: michael@0: buffer << " Result: failed to die.\n" michael@0: << " Error msg:\n" << FormatDeathTestOutput(error_message); michael@0: break; michael@0: case THREW: michael@0: buffer << " Result: threw an exception.\n" michael@0: << " Error msg:\n" << FormatDeathTestOutput(error_message); michael@0: break; michael@0: case RETURNED: michael@0: buffer << " Result: illegal return in test statement.\n" michael@0: << " Error msg:\n" << FormatDeathTestOutput(error_message); michael@0: break; michael@0: case DIED: michael@0: if (status_ok) { michael@0: const bool matched = RE::PartialMatch(error_message.c_str(), *regex()); michael@0: if (matched) { michael@0: success = true; michael@0: } else { michael@0: buffer << " Result: died but not with expected error.\n" michael@0: << " Expected: " << regex()->pattern() << "\n" michael@0: << "Actual msg:\n" << FormatDeathTestOutput(error_message); michael@0: } michael@0: } else { michael@0: buffer << " Result: died but not with expected exit code:\n" michael@0: << " " << ExitSummary(status()) << "\n" michael@0: << "Actual msg:\n" << FormatDeathTestOutput(error_message); michael@0: } michael@0: break; michael@0: case IN_PROGRESS: michael@0: default: michael@0: GTEST_LOG_(FATAL) michael@0: << "DeathTest::Passed somehow called before conclusion of test"; michael@0: } michael@0: michael@0: DeathTest::set_last_death_test_message(buffer.GetString()); michael@0: return success; michael@0: } michael@0: michael@0: # if GTEST_OS_WINDOWS michael@0: // WindowsDeathTest implements death tests on Windows. Due to the michael@0: // specifics of starting new processes on Windows, death tests there are michael@0: // always threadsafe, and Google Test considers the michael@0: // --gtest_death_test_style=fast setting to be equivalent to michael@0: // --gtest_death_test_style=threadsafe there. michael@0: // michael@0: // A few implementation notes: Like the Linux version, the Windows michael@0: // implementation uses pipes for child-to-parent communication. But due to michael@0: // the specifics of pipes on Windows, some extra steps are required: michael@0: // michael@0: // 1. The parent creates a communication pipe and stores handles to both michael@0: // ends of it. michael@0: // 2. The parent starts the child and provides it with the information michael@0: // necessary to acquire the handle to the write end of the pipe. michael@0: // 3. The child acquires the write end of the pipe and signals the parent michael@0: // using a Windows event. michael@0: // 4. Now the parent can release the write end of the pipe on its side. If michael@0: // this is done before step 3, the object's reference count goes down to michael@0: // 0 and it is destroyed, preventing the child from acquiring it. The michael@0: // parent now has to release it, or read operations on the read end of michael@0: // the pipe will not return when the child terminates. michael@0: // 5. The parent reads child's output through the pipe (outcome code and michael@0: // any possible error messages) from the pipe, and its stderr and then michael@0: // determines whether to fail the test. michael@0: // michael@0: // Note: to distinguish Win32 API calls from the local method and function michael@0: // calls, the former are explicitly resolved in the global namespace. michael@0: // michael@0: class WindowsDeathTest : public DeathTestImpl { michael@0: public: michael@0: WindowsDeathTest(const char* a_statement, michael@0: const RE* a_regex, michael@0: const char* file, michael@0: int line) michael@0: : DeathTestImpl(a_statement, a_regex), file_(file), line_(line) {} michael@0: michael@0: // All of these virtual functions are inherited from DeathTest. michael@0: virtual int Wait(); michael@0: virtual TestRole AssumeRole(); michael@0: michael@0: private: michael@0: // The name of the file in which the death test is located. michael@0: const char* const file_; michael@0: // The line number on which the death test is located. michael@0: const int line_; michael@0: // Handle to the write end of the pipe to the child process. michael@0: AutoHandle write_handle_; michael@0: // Child process handle. michael@0: AutoHandle child_handle_; michael@0: // Event the child process uses to signal the parent that it has michael@0: // acquired the handle to the write end of the pipe. After seeing this michael@0: // event the parent can release its own handles to make sure its michael@0: // ReadFile() calls return when the child terminates. michael@0: AutoHandle event_handle_; michael@0: }; michael@0: michael@0: // Waits for the child in a death test to exit, returning its exit michael@0: // status, or 0 if no child process exists. As a side effect, sets the michael@0: // outcome data member. michael@0: int WindowsDeathTest::Wait() { michael@0: if (!spawned()) michael@0: return 0; michael@0: michael@0: // Wait until the child either signals that it has acquired the write end michael@0: // of the pipe or it dies. michael@0: const HANDLE wait_handles[2] = { child_handle_.Get(), event_handle_.Get() }; michael@0: switch (::WaitForMultipleObjects(2, michael@0: wait_handles, michael@0: FALSE, // Waits for any of the handles. michael@0: INFINITE)) { michael@0: case WAIT_OBJECT_0: michael@0: case WAIT_OBJECT_0 + 1: michael@0: break; michael@0: default: michael@0: GTEST_DEATH_TEST_CHECK_(false); // Should not get here. michael@0: } michael@0: michael@0: // The child has acquired the write end of the pipe or exited. michael@0: // We release the handle on our side and continue. michael@0: write_handle_.Reset(); michael@0: event_handle_.Reset(); michael@0: michael@0: ReadAndInterpretStatusByte(); michael@0: michael@0: // Waits for the child process to exit if it haven't already. This michael@0: // returns immediately if the child has already exited, regardless of michael@0: // whether previous calls to WaitForMultipleObjects synchronized on this michael@0: // handle or not. michael@0: GTEST_DEATH_TEST_CHECK_( michael@0: WAIT_OBJECT_0 == ::WaitForSingleObject(child_handle_.Get(), michael@0: INFINITE)); michael@0: DWORD status_code; michael@0: GTEST_DEATH_TEST_CHECK_( michael@0: ::GetExitCodeProcess(child_handle_.Get(), &status_code) != FALSE); michael@0: child_handle_.Reset(); michael@0: set_status(static_cast(status_code)); michael@0: return status(); michael@0: } michael@0: michael@0: // The AssumeRole process for a Windows death test. It creates a child michael@0: // process with the same executable as the current process to run the michael@0: // death test. The child process is given the --gtest_filter and michael@0: // --gtest_internal_run_death_test flags such that it knows to run the michael@0: // current death test only. michael@0: DeathTest::TestRole WindowsDeathTest::AssumeRole() { michael@0: const UnitTestImpl* const impl = GetUnitTestImpl(); michael@0: const InternalRunDeathTestFlag* const flag = michael@0: impl->internal_run_death_test_flag(); michael@0: const TestInfo* const info = impl->current_test_info(); michael@0: const int death_test_index = info->result()->death_test_count(); michael@0: michael@0: if (flag != NULL) { michael@0: // ParseInternalRunDeathTestFlag() has performed all the necessary michael@0: // processing. michael@0: set_write_fd(flag->write_fd()); michael@0: return EXECUTE_TEST; michael@0: } michael@0: michael@0: // WindowsDeathTest uses an anonymous pipe to communicate results of michael@0: // a death test. michael@0: SECURITY_ATTRIBUTES handles_are_inheritable = { michael@0: sizeof(SECURITY_ATTRIBUTES), NULL, TRUE }; michael@0: HANDLE read_handle, write_handle; michael@0: GTEST_DEATH_TEST_CHECK_( michael@0: ::CreatePipe(&read_handle, &write_handle, &handles_are_inheritable, michael@0: 0) // Default buffer size. michael@0: != FALSE); michael@0: set_read_fd(::_open_osfhandle(reinterpret_cast(read_handle), michael@0: O_RDONLY)); michael@0: write_handle_.Reset(write_handle); michael@0: event_handle_.Reset(::CreateEvent( michael@0: &handles_are_inheritable, michael@0: TRUE, // The event will automatically reset to non-signaled state. michael@0: FALSE, // The initial state is non-signalled. michael@0: NULL)); // The even is unnamed. michael@0: GTEST_DEATH_TEST_CHECK_(event_handle_.Get() != NULL); michael@0: const String filter_flag = String::Format("--%s%s=%s.%s", michael@0: GTEST_FLAG_PREFIX_, kFilterFlag, michael@0: info->test_case_name(), michael@0: info->name()); michael@0: const String internal_flag = String::Format( michael@0: "--%s%s=%s|%d|%d|%u|%Iu|%Iu", michael@0: GTEST_FLAG_PREFIX_, michael@0: kInternalRunDeathTestFlag, michael@0: file_, line_, michael@0: death_test_index, michael@0: static_cast(::GetCurrentProcessId()), michael@0: // size_t has the same with as pointers on both 32-bit and 64-bit michael@0: // Windows platforms. michael@0: // See http://msdn.microsoft.com/en-us/library/tcxf1dw6.aspx. michael@0: reinterpret_cast(write_handle), michael@0: reinterpret_cast(event_handle_.Get())); michael@0: michael@0: char executable_path[_MAX_PATH + 1]; // NOLINT michael@0: GTEST_DEATH_TEST_CHECK_( michael@0: _MAX_PATH + 1 != ::GetModuleFileNameA(NULL, michael@0: executable_path, michael@0: _MAX_PATH)); michael@0: michael@0: String command_line = String::Format("%s %s \"%s\"", michael@0: ::GetCommandLineA(), michael@0: filter_flag.c_str(), michael@0: internal_flag.c_str()); michael@0: michael@0: DeathTest::set_last_death_test_message(""); michael@0: michael@0: CaptureStderr(); michael@0: // Flush the log buffers since the log streams are shared with the child. michael@0: FlushInfoLog(); michael@0: michael@0: // The child process will share the standard handles with the parent. michael@0: STARTUPINFOA startup_info; michael@0: memset(&startup_info, 0, sizeof(STARTUPINFO)); michael@0: startup_info.dwFlags = STARTF_USESTDHANDLES; michael@0: startup_info.hStdInput = ::GetStdHandle(STD_INPUT_HANDLE); michael@0: startup_info.hStdOutput = ::GetStdHandle(STD_OUTPUT_HANDLE); michael@0: startup_info.hStdError = ::GetStdHandle(STD_ERROR_HANDLE); michael@0: michael@0: PROCESS_INFORMATION process_info; michael@0: GTEST_DEATH_TEST_CHECK_(::CreateProcessA( michael@0: executable_path, michael@0: const_cast(command_line.c_str()), michael@0: NULL, // Retuned process handle is not inheritable. michael@0: NULL, // Retuned thread handle is not inheritable. michael@0: TRUE, // Child inherits all inheritable handles (for write_handle_). michael@0: 0x0, // Default creation flags. michael@0: NULL, // Inherit the parent's environment. michael@0: UnitTest::GetInstance()->original_working_dir(), michael@0: &startup_info, michael@0: &process_info) != FALSE); michael@0: child_handle_.Reset(process_info.hProcess); michael@0: ::CloseHandle(process_info.hThread); michael@0: set_spawned(true); michael@0: return OVERSEE_TEST; michael@0: } michael@0: # else // We are not on Windows. michael@0: michael@0: // ForkingDeathTest provides implementations for most of the abstract michael@0: // methods of the DeathTest interface. Only the AssumeRole method is michael@0: // left undefined. michael@0: class ForkingDeathTest : public DeathTestImpl { michael@0: public: michael@0: ForkingDeathTest(const char* statement, const RE* regex); michael@0: michael@0: // All of these virtual functions are inherited from DeathTest. michael@0: virtual int Wait(); michael@0: michael@0: protected: michael@0: void set_child_pid(pid_t child_pid) { child_pid_ = child_pid; } michael@0: michael@0: private: michael@0: // PID of child process during death test; 0 in the child process itself. michael@0: pid_t child_pid_; michael@0: }; michael@0: michael@0: // Constructs a ForkingDeathTest. michael@0: ForkingDeathTest::ForkingDeathTest(const char* a_statement, const RE* a_regex) michael@0: : DeathTestImpl(a_statement, a_regex), michael@0: child_pid_(-1) {} michael@0: michael@0: // Waits for the child in a death test to exit, returning its exit michael@0: // status, or 0 if no child process exists. As a side effect, sets the michael@0: // outcome data member. michael@0: int ForkingDeathTest::Wait() { michael@0: if (!spawned()) michael@0: return 0; michael@0: michael@0: ReadAndInterpretStatusByte(); michael@0: michael@0: int status_value; michael@0: GTEST_DEATH_TEST_CHECK_SYSCALL_(waitpid(child_pid_, &status_value, 0)); michael@0: set_status(status_value); michael@0: return status_value; michael@0: } michael@0: michael@0: // A concrete death test class that forks, then immediately runs the test michael@0: // in the child process. michael@0: class NoExecDeathTest : public ForkingDeathTest { michael@0: public: michael@0: NoExecDeathTest(const char* a_statement, const RE* a_regex) : michael@0: ForkingDeathTest(a_statement, a_regex) { } michael@0: virtual TestRole AssumeRole(); michael@0: }; michael@0: michael@0: // The AssumeRole process for a fork-and-run death test. It implements a michael@0: // straightforward fork, with a simple pipe to transmit the status byte. michael@0: DeathTest::TestRole NoExecDeathTest::AssumeRole() { michael@0: const size_t thread_count = GetThreadCount(); michael@0: if (thread_count != 1) { michael@0: GTEST_LOG_(WARNING) << DeathTestThreadWarning(thread_count); michael@0: } michael@0: michael@0: int pipe_fd[2]; michael@0: GTEST_DEATH_TEST_CHECK_(pipe(pipe_fd) != -1); michael@0: michael@0: DeathTest::set_last_death_test_message(""); michael@0: CaptureStderr(); michael@0: // When we fork the process below, the log file buffers are copied, but the michael@0: // file descriptors are shared. We flush all log files here so that closing michael@0: // the file descriptors in the child process doesn't throw off the michael@0: // synchronization between descriptors and buffers in the parent process. michael@0: // This is as close to the fork as possible to avoid a race condition in case michael@0: // there are multiple threads running before the death test, and another michael@0: // thread writes to the log file. michael@0: FlushInfoLog(); michael@0: michael@0: const pid_t child_pid = fork(); michael@0: GTEST_DEATH_TEST_CHECK_(child_pid != -1); michael@0: set_child_pid(child_pid); michael@0: if (child_pid == 0) { michael@0: GTEST_DEATH_TEST_CHECK_SYSCALL_(close(pipe_fd[0])); michael@0: set_write_fd(pipe_fd[1]); michael@0: // Redirects all logging to stderr in the child process to prevent michael@0: // concurrent writes to the log files. We capture stderr in the parent michael@0: // process and append the child process' output to a log. michael@0: LogToStderr(); michael@0: // Event forwarding to the listeners of event listener API mush be shut michael@0: // down in death test subprocesses. michael@0: GetUnitTestImpl()->listeners()->SuppressEventForwarding(); michael@0: g_in_fast_death_test_child = true; michael@0: return EXECUTE_TEST; michael@0: } else { michael@0: GTEST_DEATH_TEST_CHECK_SYSCALL_(close(pipe_fd[1])); michael@0: set_read_fd(pipe_fd[0]); michael@0: set_spawned(true); michael@0: return OVERSEE_TEST; michael@0: } michael@0: } michael@0: michael@0: // A concrete death test class that forks and re-executes the main michael@0: // program from the beginning, with command-line flags set that cause michael@0: // only this specific death test to be run. michael@0: class ExecDeathTest : public ForkingDeathTest { michael@0: public: michael@0: ExecDeathTest(const char* a_statement, const RE* a_regex, michael@0: const char* file, int line) : michael@0: ForkingDeathTest(a_statement, a_regex), file_(file), line_(line) { } michael@0: virtual TestRole AssumeRole(); michael@0: private: michael@0: static ::std::vector michael@0: GetArgvsForDeathTestChildProcess() { michael@0: ::std::vector args = GetInjectableArgvs(); michael@0: return args; michael@0: } michael@0: // The name of the file in which the death test is located. michael@0: const char* const file_; michael@0: // The line number on which the death test is located. michael@0: const int line_; michael@0: }; michael@0: michael@0: // Utility class for accumulating command-line arguments. michael@0: class Arguments { michael@0: public: michael@0: Arguments() { michael@0: args_.push_back(NULL); michael@0: } michael@0: michael@0: ~Arguments() { michael@0: for (std::vector::iterator i = args_.begin(); i != args_.end(); michael@0: ++i) { michael@0: free(*i); michael@0: } michael@0: } michael@0: void AddArgument(const char* argument) { michael@0: args_.insert(args_.end() - 1, posix::StrDup(argument)); michael@0: } michael@0: michael@0: template michael@0: void AddArguments(const ::std::vector& arguments) { michael@0: for (typename ::std::vector::const_iterator i = arguments.begin(); michael@0: i != arguments.end(); michael@0: ++i) { michael@0: args_.insert(args_.end() - 1, posix::StrDup(i->c_str())); michael@0: } michael@0: } michael@0: char* const* Argv() { michael@0: return &args_[0]; michael@0: } michael@0: michael@0: private: michael@0: std::vector args_; michael@0: }; michael@0: michael@0: // A struct that encompasses the arguments to the child process of a michael@0: // threadsafe-style death test process. michael@0: struct ExecDeathTestArgs { michael@0: char* const* argv; // Command-line arguments for the child's call to exec michael@0: int close_fd; // File descriptor to close; the read end of a pipe michael@0: }; michael@0: michael@0: # if GTEST_OS_MAC michael@0: inline char** GetEnviron() { michael@0: // When Google Test is built as a framework on MacOS X, the environ variable michael@0: // is unavailable. Apple's documentation (man environ) recommends using michael@0: // _NSGetEnviron() instead. michael@0: return *_NSGetEnviron(); michael@0: } michael@0: # else michael@0: // Some POSIX platforms expect you to declare environ. extern "C" makes michael@0: // it reside in the global namespace. michael@0: extern "C" __attribute__ ((visibility ("default"))) char** environ; michael@0: inline char** GetEnviron() { return environ; } michael@0: # endif // GTEST_OS_MAC michael@0: michael@0: # if !GTEST_OS_QNX michael@0: // The main function for a threadsafe-style death test child process. michael@0: // This function is called in a clone()-ed process and thus must avoid michael@0: // any potentially unsafe operations like malloc or libc functions. michael@0: static int ExecDeathTestChildMain(void* child_arg) { michael@0: ExecDeathTestArgs* const args = static_cast(child_arg); michael@0: GTEST_DEATH_TEST_CHECK_SYSCALL_(close(args->close_fd)); michael@0: michael@0: // We need to execute the test program in the same environment where michael@0: // it was originally invoked. Therefore we change to the original michael@0: // working directory first. michael@0: const char* const original_dir = michael@0: UnitTest::GetInstance()->original_working_dir(); michael@0: // We can safely call chdir() as it's a direct system call. michael@0: if (chdir(original_dir) != 0) { michael@0: DeathTestAbort(String::Format("chdir(\"%s\") failed: %s", michael@0: original_dir, michael@0: GetLastErrnoDescription().c_str())); michael@0: return EXIT_FAILURE; michael@0: } michael@0: michael@0: // We can safely call execve() as it's a direct system call. We michael@0: // cannot use execvp() as it's a libc function and thus potentially michael@0: // unsafe. Since execve() doesn't search the PATH, the user must michael@0: // invoke the test program via a valid path that contains at least michael@0: // one path separator. michael@0: execve(args->argv[0], args->argv, GetEnviron()); michael@0: DeathTestAbort(String::Format("execve(%s, ...) in %s failed: %s", michael@0: args->argv[0], michael@0: original_dir, michael@0: GetLastErrnoDescription().c_str())); michael@0: return EXIT_FAILURE; michael@0: } michael@0: # endif // !GTEST_OS_QNX michael@0: michael@0: // Two utility routines that together determine the direction the stack michael@0: // grows. michael@0: // This could be accomplished more elegantly by a single recursive michael@0: // function, but we want to guard against the unlikely possibility of michael@0: // a smart compiler optimizing the recursion away. michael@0: // michael@0: // GTEST_NO_INLINE_ is required to prevent GCC 4.6 from inlining michael@0: // StackLowerThanAddress into StackGrowsDown, which then doesn't give michael@0: // correct answer. michael@0: void StackLowerThanAddress(const void* ptr, bool* result) GTEST_NO_INLINE_; michael@0: void StackLowerThanAddress(const void* ptr, bool* result) { michael@0: int dummy; michael@0: *result = (&dummy < ptr); michael@0: } michael@0: michael@0: bool StackGrowsDown() { michael@0: int dummy; michael@0: bool result; michael@0: StackLowerThanAddress(&dummy, &result); michael@0: return result; michael@0: } michael@0: michael@0: // Spawns a child process with the same executable as the current process in michael@0: // a thread-safe manner and instructs it to run the death test. The michael@0: // implementation uses fork(2) + exec. On systems where clone(2) is michael@0: // available, it is used instead, being slightly more thread-safe. On QNX, michael@0: // fork supports only single-threaded environments, so this function uses michael@0: // spawn(2) there instead. The function dies with an error message if michael@0: // anything goes wrong. michael@0: static pid_t ExecDeathTestSpawnChild(char* const* argv, int close_fd) { michael@0: ExecDeathTestArgs args = { argv, close_fd }; michael@0: pid_t child_pid = -1; michael@0: michael@0: # if GTEST_OS_QNX michael@0: // Obtains the current directory and sets it to be closed in the child michael@0: // process. michael@0: const int cwd_fd = open(".", O_RDONLY); michael@0: GTEST_DEATH_TEST_CHECK_(cwd_fd != -1); michael@0: GTEST_DEATH_TEST_CHECK_SYSCALL_(fcntl(cwd_fd, F_SETFD, FD_CLOEXEC)); michael@0: // We need to execute the test program in the same environment where michael@0: // it was originally invoked. Therefore we change to the original michael@0: // working directory first. michael@0: const char* const original_dir = michael@0: UnitTest::GetInstance()->original_working_dir(); michael@0: // We can safely call chdir() as it's a direct system call. michael@0: if (chdir(original_dir) != 0) { michael@0: DeathTestAbort(String::Format("chdir(\"%s\") failed: %s", michael@0: original_dir, michael@0: GetLastErrnoDescription().c_str())); michael@0: return EXIT_FAILURE; michael@0: } michael@0: michael@0: int fd_flags; michael@0: // Set close_fd to be closed after spawn. michael@0: GTEST_DEATH_TEST_CHECK_SYSCALL_(fd_flags = fcntl(close_fd, F_GETFD)); michael@0: GTEST_DEATH_TEST_CHECK_SYSCALL_(fcntl(close_fd, F_SETFD, michael@0: fd_flags | FD_CLOEXEC)); michael@0: struct inheritance inherit = {0}; michael@0: // spawn is a system call. michael@0: child_pid = spawn(args.argv[0], 0, NULL, &inherit, args.argv, GetEnviron()); michael@0: // Restores the current working directory. michael@0: GTEST_DEATH_TEST_CHECK_(fchdir(cwd_fd) != -1); michael@0: GTEST_DEATH_TEST_CHECK_SYSCALL_(close(cwd_fd)); michael@0: michael@0: # else // GTEST_OS_QNX michael@0: # if GTEST_OS_LINUX michael@0: // When a SIGPROF signal is received while fork() or clone() are executing, michael@0: // the process may hang. To avoid this, we ignore SIGPROF here and re-enable michael@0: // it after the call to fork()/clone() is complete. michael@0: struct sigaction saved_sigprof_action; michael@0: struct sigaction ignore_sigprof_action; michael@0: memset(&ignore_sigprof_action, 0, sizeof(ignore_sigprof_action)); michael@0: sigemptyset(&ignore_sigprof_action.sa_mask); michael@0: ignore_sigprof_action.sa_handler = SIG_IGN; michael@0: GTEST_DEATH_TEST_CHECK_SYSCALL_(sigaction( michael@0: SIGPROF, &ignore_sigprof_action, &saved_sigprof_action)); michael@0: # endif // GTEST_OS_LINUX michael@0: michael@0: # if GTEST_HAS_CLONE michael@0: const bool use_fork = GTEST_FLAG(death_test_use_fork); michael@0: michael@0: if (!use_fork) { michael@0: static const bool stack_grows_down = StackGrowsDown(); michael@0: const size_t stack_size = getpagesize(); michael@0: // MMAP_ANONYMOUS is not defined on Mac, so we use MAP_ANON instead. michael@0: void* const stack = mmap(NULL, stack_size, PROT_READ | PROT_WRITE, michael@0: MAP_ANON | MAP_PRIVATE, -1, 0); michael@0: GTEST_DEATH_TEST_CHECK_(stack != MAP_FAILED); michael@0: michael@0: // Maximum stack alignment in bytes: For a downward-growing stack, this michael@0: // amount is subtracted from size of the stack space to get an address michael@0: // that is within the stack space and is aligned on all systems we care michael@0: // about. As far as I know there is no ABI with stack alignment greater michael@0: // than 64. We assume stack and stack_size already have alignment of michael@0: // kMaxStackAlignment. michael@0: const size_t kMaxStackAlignment = 64; michael@0: void* const stack_top = michael@0: static_cast(stack) + michael@0: (stack_grows_down ? stack_size - kMaxStackAlignment : 0); michael@0: GTEST_DEATH_TEST_CHECK_(stack_size > kMaxStackAlignment && michael@0: reinterpret_cast(stack_top) % kMaxStackAlignment == 0); michael@0: michael@0: child_pid = clone(&ExecDeathTestChildMain, stack_top, SIGCHLD, &args); michael@0: michael@0: GTEST_DEATH_TEST_CHECK_(munmap(stack, stack_size) != -1); michael@0: } michael@0: # else michael@0: const bool use_fork = true; michael@0: # endif // GTEST_HAS_CLONE michael@0: michael@0: if (use_fork && (child_pid = fork()) == 0) { michael@0: ExecDeathTestChildMain(&args); michael@0: _exit(0); michael@0: } michael@0: # endif // GTEST_OS_QNX michael@0: # if GTEST_OS_LINUX michael@0: GTEST_DEATH_TEST_CHECK_SYSCALL_( michael@0: sigaction(SIGPROF, &saved_sigprof_action, NULL)); michael@0: # endif // GTEST_OS_LINUX michael@0: michael@0: GTEST_DEATH_TEST_CHECK_(child_pid != -1); michael@0: return child_pid; michael@0: } michael@0: michael@0: // The AssumeRole process for a fork-and-exec death test. It re-executes the michael@0: // main program from the beginning, setting the --gtest_filter michael@0: // and --gtest_internal_run_death_test flags to cause only the current michael@0: // death test to be re-run. michael@0: DeathTest::TestRole ExecDeathTest::AssumeRole() { michael@0: const UnitTestImpl* const impl = GetUnitTestImpl(); michael@0: const InternalRunDeathTestFlag* const flag = michael@0: impl->internal_run_death_test_flag(); michael@0: const TestInfo* const info = impl->current_test_info(); michael@0: const int death_test_index = info->result()->death_test_count(); michael@0: michael@0: if (flag != NULL) { michael@0: set_write_fd(flag->write_fd()); michael@0: return EXECUTE_TEST; michael@0: } michael@0: michael@0: int pipe_fd[2]; michael@0: GTEST_DEATH_TEST_CHECK_(pipe(pipe_fd) != -1); michael@0: // Clear the close-on-exec flag on the write end of the pipe, lest michael@0: // it be closed when the child process does an exec: michael@0: GTEST_DEATH_TEST_CHECK_(fcntl(pipe_fd[1], F_SETFD, 0) != -1); michael@0: michael@0: const String filter_flag = michael@0: String::Format("--%s%s=%s.%s", michael@0: GTEST_FLAG_PREFIX_, kFilterFlag, michael@0: info->test_case_name(), info->name()); michael@0: const String internal_flag = michael@0: String::Format("--%s%s=%s|%d|%d|%d", michael@0: GTEST_FLAG_PREFIX_, kInternalRunDeathTestFlag, michael@0: file_, line_, death_test_index, pipe_fd[1]); michael@0: Arguments args; michael@0: args.AddArguments(GetArgvsForDeathTestChildProcess()); michael@0: args.AddArgument(filter_flag.c_str()); michael@0: args.AddArgument(internal_flag.c_str()); michael@0: michael@0: DeathTest::set_last_death_test_message(""); michael@0: michael@0: CaptureStderr(); michael@0: // See the comment in NoExecDeathTest::AssumeRole for why the next line michael@0: // is necessary. michael@0: FlushInfoLog(); michael@0: michael@0: const pid_t child_pid = ExecDeathTestSpawnChild(args.Argv(), pipe_fd[0]); michael@0: GTEST_DEATH_TEST_CHECK_SYSCALL_(close(pipe_fd[1])); michael@0: set_child_pid(child_pid); michael@0: set_read_fd(pipe_fd[0]); michael@0: set_spawned(true); michael@0: return OVERSEE_TEST; michael@0: } michael@0: michael@0: # endif // !GTEST_OS_WINDOWS michael@0: michael@0: // Creates a concrete DeathTest-derived class that depends on the michael@0: // --gtest_death_test_style flag, and sets the pointer pointed to michael@0: // by the "test" argument to its address. If the test should be michael@0: // skipped, sets that pointer to NULL. Returns true, unless the michael@0: // flag is set to an invalid value. michael@0: bool DefaultDeathTestFactory::Create(const char* statement, const RE* regex, michael@0: const char* file, int line, michael@0: DeathTest** test) { michael@0: UnitTestImpl* const impl = GetUnitTestImpl(); michael@0: const InternalRunDeathTestFlag* const flag = michael@0: impl->internal_run_death_test_flag(); michael@0: const int death_test_index = impl->current_test_info() michael@0: ->increment_death_test_count(); michael@0: michael@0: if (flag != NULL) { michael@0: if (death_test_index > flag->index()) { michael@0: DeathTest::set_last_death_test_message(String::Format( michael@0: "Death test count (%d) somehow exceeded expected maximum (%d)", michael@0: death_test_index, flag->index())); michael@0: return false; michael@0: } michael@0: michael@0: if (!(flag->file() == file && flag->line() == line && michael@0: flag->index() == death_test_index)) { michael@0: *test = NULL; michael@0: return true; michael@0: } michael@0: } michael@0: michael@0: # if GTEST_OS_WINDOWS michael@0: michael@0: if (GTEST_FLAG(death_test_style) == "threadsafe" || michael@0: GTEST_FLAG(death_test_style) == "fast") { michael@0: *test = new WindowsDeathTest(statement, regex, file, line); michael@0: } michael@0: michael@0: # else michael@0: michael@0: if (GTEST_FLAG(death_test_style) == "threadsafe") { michael@0: *test = new ExecDeathTest(statement, regex, file, line); michael@0: } else if (GTEST_FLAG(death_test_style) == "fast") { michael@0: *test = new NoExecDeathTest(statement, regex); michael@0: } michael@0: michael@0: # endif // GTEST_OS_WINDOWS michael@0: michael@0: else { // NOLINT - this is more readable than unbalanced brackets inside #if. michael@0: DeathTest::set_last_death_test_message(String::Format( michael@0: "Unknown death test style \"%s\" encountered", michael@0: GTEST_FLAG(death_test_style).c_str())); michael@0: return false; michael@0: } michael@0: michael@0: return true; michael@0: } michael@0: michael@0: // Splits a given string on a given delimiter, populating a given michael@0: // vector with the fields. GTEST_HAS_DEATH_TEST implies that we have michael@0: // ::std::string, so we can use it here. michael@0: static void SplitString(const ::std::string& str, char delimiter, michael@0: ::std::vector< ::std::string>* dest) { michael@0: ::std::vector< ::std::string> parsed; michael@0: ::std::string::size_type pos = 0; michael@0: while (::testing::internal::AlwaysTrue()) { michael@0: const ::std::string::size_type colon = str.find(delimiter, pos); michael@0: if (colon == ::std::string::npos) { michael@0: parsed.push_back(str.substr(pos)); michael@0: break; michael@0: } else { michael@0: parsed.push_back(str.substr(pos, colon - pos)); michael@0: pos = colon + 1; michael@0: } michael@0: } michael@0: dest->swap(parsed); michael@0: } michael@0: michael@0: # if GTEST_OS_WINDOWS michael@0: // Recreates the pipe and event handles from the provided parameters, michael@0: // signals the event, and returns a file descriptor wrapped around the pipe michael@0: // handle. This function is called in the child process only. michael@0: int GetStatusFileDescriptor(unsigned int parent_process_id, michael@0: size_t write_handle_as_size_t, michael@0: size_t event_handle_as_size_t) { michael@0: AutoHandle parent_process_handle(::OpenProcess(PROCESS_DUP_HANDLE, michael@0: FALSE, // Non-inheritable. michael@0: parent_process_id)); michael@0: if (parent_process_handle.Get() == INVALID_HANDLE_VALUE) { michael@0: DeathTestAbort(String::Format("Unable to open parent process %u", michael@0: parent_process_id)); michael@0: } michael@0: michael@0: // TODO(vladl@google.com): Replace the following check with a michael@0: // compile-time assertion when available. michael@0: GTEST_CHECK_(sizeof(HANDLE) <= sizeof(size_t)); michael@0: michael@0: const HANDLE write_handle = michael@0: reinterpret_cast(write_handle_as_size_t); michael@0: HANDLE dup_write_handle; michael@0: michael@0: // The newly initialized handle is accessible only in in the parent michael@0: // process. To obtain one accessible within the child, we need to use michael@0: // DuplicateHandle. michael@0: if (!::DuplicateHandle(parent_process_handle.Get(), write_handle, michael@0: ::GetCurrentProcess(), &dup_write_handle, michael@0: 0x0, // Requested privileges ignored since michael@0: // DUPLICATE_SAME_ACCESS is used. michael@0: FALSE, // Request non-inheritable handler. michael@0: DUPLICATE_SAME_ACCESS)) { michael@0: DeathTestAbort(String::Format( michael@0: "Unable to duplicate the pipe handle %Iu from the parent process %u", michael@0: write_handle_as_size_t, parent_process_id)); michael@0: } michael@0: michael@0: const HANDLE event_handle = reinterpret_cast(event_handle_as_size_t); michael@0: HANDLE dup_event_handle; michael@0: michael@0: if (!::DuplicateHandle(parent_process_handle.Get(), event_handle, michael@0: ::GetCurrentProcess(), &dup_event_handle, michael@0: 0x0, michael@0: FALSE, michael@0: DUPLICATE_SAME_ACCESS)) { michael@0: DeathTestAbort(String::Format( michael@0: "Unable to duplicate the event handle %Iu from the parent process %u", michael@0: event_handle_as_size_t, parent_process_id)); michael@0: } michael@0: michael@0: const int write_fd = michael@0: ::_open_osfhandle(reinterpret_cast(dup_write_handle), O_APPEND); michael@0: if (write_fd == -1) { michael@0: DeathTestAbort(String::Format( michael@0: "Unable to convert pipe handle %Iu to a file descriptor", michael@0: write_handle_as_size_t)); michael@0: } michael@0: michael@0: // Signals the parent that the write end of the pipe has been acquired michael@0: // so the parent can release its own write end. michael@0: ::SetEvent(dup_event_handle); michael@0: michael@0: return write_fd; michael@0: } michael@0: # endif // GTEST_OS_WINDOWS michael@0: michael@0: // Returns a newly created InternalRunDeathTestFlag object with fields michael@0: // initialized from the GTEST_FLAG(internal_run_death_test) flag if michael@0: // the flag is specified; otherwise returns NULL. michael@0: InternalRunDeathTestFlag* ParseInternalRunDeathTestFlag() { michael@0: if (GTEST_FLAG(internal_run_death_test) == "") return NULL; michael@0: michael@0: // GTEST_HAS_DEATH_TEST implies that we have ::std::string, so we michael@0: // can use it here. michael@0: int line = -1; michael@0: int index = -1; michael@0: ::std::vector< ::std::string> fields; michael@0: SplitString(GTEST_FLAG(internal_run_death_test).c_str(), '|', &fields); michael@0: int write_fd = -1; michael@0: michael@0: # if GTEST_OS_WINDOWS michael@0: michael@0: unsigned int parent_process_id = 0; michael@0: size_t write_handle_as_size_t = 0; michael@0: size_t event_handle_as_size_t = 0; michael@0: michael@0: if (fields.size() != 6 michael@0: || !ParseNaturalNumber(fields[1], &line) michael@0: || !ParseNaturalNumber(fields[2], &index) michael@0: || !ParseNaturalNumber(fields[3], &parent_process_id) michael@0: || !ParseNaturalNumber(fields[4], &write_handle_as_size_t) michael@0: || !ParseNaturalNumber(fields[5], &event_handle_as_size_t)) { michael@0: DeathTestAbort(String::Format( michael@0: "Bad --gtest_internal_run_death_test flag: %s", michael@0: GTEST_FLAG(internal_run_death_test).c_str())); michael@0: } michael@0: write_fd = GetStatusFileDescriptor(parent_process_id, michael@0: write_handle_as_size_t, michael@0: event_handle_as_size_t); michael@0: # else michael@0: michael@0: if (fields.size() != 4 michael@0: || !ParseNaturalNumber(fields[1], &line) michael@0: || !ParseNaturalNumber(fields[2], &index) michael@0: || !ParseNaturalNumber(fields[3], &write_fd)) { michael@0: DeathTestAbort(String::Format( michael@0: "Bad --gtest_internal_run_death_test flag: %s", michael@0: GTEST_FLAG(internal_run_death_test).c_str())); michael@0: } michael@0: michael@0: # endif // GTEST_OS_WINDOWS michael@0: michael@0: return new InternalRunDeathTestFlag(fields[0], line, index, write_fd); michael@0: } michael@0: michael@0: } // namespace internal michael@0: michael@0: #endif // GTEST_HAS_DEATH_TEST michael@0: michael@0: } // namespace testing