Thu, 15 Jan 2015 21:03:48 +0100
Integrate friendly tips from Tor colleagues to make (or not) 4.5 alpha 3;
This includes removal of overloaded (but unused) methods, and addition of
a overlooked call to DataStruct::SetData(nsISupports, uint32_t, bool.)
michael@0 | 1 | // Copyright 2005, Google Inc. |
michael@0 | 2 | // All rights reserved. |
michael@0 | 3 | // |
michael@0 | 4 | // Redistribution and use in source and binary forms, with or without |
michael@0 | 5 | // modification, are permitted provided that the following conditions are |
michael@0 | 6 | // met: |
michael@0 | 7 | // |
michael@0 | 8 | // * Redistributions of source code must retain the above copyright |
michael@0 | 9 | // notice, this list of conditions and the following disclaimer. |
michael@0 | 10 | // * Redistributions in binary form must reproduce the above |
michael@0 | 11 | // copyright notice, this list of conditions and the following disclaimer |
michael@0 | 12 | // in the documentation and/or other materials provided with the |
michael@0 | 13 | // distribution. |
michael@0 | 14 | // * Neither the name of Google Inc. nor the names of its |
michael@0 | 15 | // contributors may be used to endorse or promote products derived from |
michael@0 | 16 | // this software without specific prior written permission. |
michael@0 | 17 | // |
michael@0 | 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
michael@0 | 19 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
michael@0 | 20 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
michael@0 | 21 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
michael@0 | 22 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
michael@0 | 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
michael@0 | 24 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
michael@0 | 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
michael@0 | 26 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
michael@0 | 27 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
michael@0 | 28 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
michael@0 | 29 | // |
michael@0 | 30 | // Author: wan@google.com (Zhanyong Wan), vladl@google.com (Vlad Losev) |
michael@0 | 31 | // |
michael@0 | 32 | // This file implements death tests. |
michael@0 | 33 | |
michael@0 | 34 | #include "gtest/gtest-death-test.h" |
michael@0 | 35 | #include "gtest/internal/gtest-port.h" |
michael@0 | 36 | |
michael@0 | 37 | #if GTEST_HAS_DEATH_TEST |
michael@0 | 38 | |
michael@0 | 39 | # if GTEST_OS_MAC |
michael@0 | 40 | # include <crt_externs.h> |
michael@0 | 41 | # endif // GTEST_OS_MAC |
michael@0 | 42 | |
michael@0 | 43 | # include <errno.h> |
michael@0 | 44 | # include <fcntl.h> |
michael@0 | 45 | # include <limits.h> |
michael@0 | 46 | |
michael@0 | 47 | # if GTEST_OS_LINUX |
michael@0 | 48 | # include <signal.h> |
michael@0 | 49 | # endif // GTEST_OS_LINUX |
michael@0 | 50 | |
michael@0 | 51 | # include <stdarg.h> |
michael@0 | 52 | |
michael@0 | 53 | # if GTEST_OS_WINDOWS |
michael@0 | 54 | # include <windows.h> |
michael@0 | 55 | # else |
michael@0 | 56 | # include <sys/mman.h> |
michael@0 | 57 | # include <sys/wait.h> |
michael@0 | 58 | # endif // GTEST_OS_WINDOWS |
michael@0 | 59 | |
michael@0 | 60 | # if GTEST_OS_QNX |
michael@0 | 61 | # include <spawn.h> |
michael@0 | 62 | # endif // GTEST_OS_QNX |
michael@0 | 63 | |
michael@0 | 64 | #endif // GTEST_HAS_DEATH_TEST |
michael@0 | 65 | |
michael@0 | 66 | #include "gtest/gtest-message.h" |
michael@0 | 67 | #include "gtest/internal/gtest-string.h" |
michael@0 | 68 | |
michael@0 | 69 | // Indicates that this translation unit is part of Google Test's |
michael@0 | 70 | // implementation. It must come before gtest-internal-inl.h is |
michael@0 | 71 | // included, or there will be a compiler error. This trick is to |
michael@0 | 72 | // prevent a user from accidentally including gtest-internal-inl.h in |
michael@0 | 73 | // his code. |
michael@0 | 74 | #define GTEST_IMPLEMENTATION_ 1 |
michael@0 | 75 | #include "src/gtest-internal-inl.h" |
michael@0 | 76 | #undef GTEST_IMPLEMENTATION_ |
michael@0 | 77 | |
michael@0 | 78 | namespace testing { |
michael@0 | 79 | |
michael@0 | 80 | // Constants. |
michael@0 | 81 | |
michael@0 | 82 | // The default death test style. |
michael@0 | 83 | static const char kDefaultDeathTestStyle[] = "fast"; |
michael@0 | 84 | |
michael@0 | 85 | GTEST_DEFINE_string_( |
michael@0 | 86 | death_test_style, |
michael@0 | 87 | internal::StringFromGTestEnv("death_test_style", kDefaultDeathTestStyle), |
michael@0 | 88 | "Indicates how to run a death test in a forked child process: " |
michael@0 | 89 | "\"threadsafe\" (child process re-executes the test binary " |
michael@0 | 90 | "from the beginning, running only the specific death test) or " |
michael@0 | 91 | "\"fast\" (child process runs the death test immediately " |
michael@0 | 92 | "after forking)."); |
michael@0 | 93 | |
michael@0 | 94 | GTEST_DEFINE_bool_( |
michael@0 | 95 | death_test_use_fork, |
michael@0 | 96 | internal::BoolFromGTestEnv("death_test_use_fork", false), |
michael@0 | 97 | "Instructs to use fork()/_exit() instead of clone() in death tests. " |
michael@0 | 98 | "Ignored and always uses fork() on POSIX systems where clone() is not " |
michael@0 | 99 | "implemented. Useful when running under valgrind or similar tools if " |
michael@0 | 100 | "those do not support clone(). Valgrind 3.3.1 will just fail if " |
michael@0 | 101 | "it sees an unsupported combination of clone() flags. " |
michael@0 | 102 | "It is not recommended to use this flag w/o valgrind though it will " |
michael@0 | 103 | "work in 99% of the cases. Once valgrind is fixed, this flag will " |
michael@0 | 104 | "most likely be removed."); |
michael@0 | 105 | |
michael@0 | 106 | namespace internal { |
michael@0 | 107 | GTEST_DEFINE_string_( |
michael@0 | 108 | internal_run_death_test, "", |
michael@0 | 109 | "Indicates the file, line number, temporal index of " |
michael@0 | 110 | "the single death test to run, and a file descriptor to " |
michael@0 | 111 | "which a success code may be sent, all separated by " |
michael@0 | 112 | "the '|' characters. This flag is specified if and only if the current " |
michael@0 | 113 | "process is a sub-process launched for running a thread-safe " |
michael@0 | 114 | "death test. FOR INTERNAL USE ONLY."); |
michael@0 | 115 | } // namespace internal |
michael@0 | 116 | |
michael@0 | 117 | #if GTEST_HAS_DEATH_TEST |
michael@0 | 118 | |
michael@0 | 119 | namespace internal { |
michael@0 | 120 | |
michael@0 | 121 | // Valid only for fast death tests. Indicates the code is running in the |
michael@0 | 122 | // child process of a fast style death test. |
michael@0 | 123 | static bool g_in_fast_death_test_child = false; |
michael@0 | 124 | |
michael@0 | 125 | // Returns a Boolean value indicating whether the caller is currently |
michael@0 | 126 | // executing in the context of the death test child process. Tools such as |
michael@0 | 127 | // Valgrind heap checkers may need this to modify their behavior in death |
michael@0 | 128 | // tests. IMPORTANT: This is an internal utility. Using it may break the |
michael@0 | 129 | // implementation of death tests. User code MUST NOT use it. |
michael@0 | 130 | bool InDeathTestChild() { |
michael@0 | 131 | # if GTEST_OS_WINDOWS |
michael@0 | 132 | |
michael@0 | 133 | // On Windows, death tests are thread-safe regardless of the value of the |
michael@0 | 134 | // death_test_style flag. |
michael@0 | 135 | return !GTEST_FLAG(internal_run_death_test).empty(); |
michael@0 | 136 | |
michael@0 | 137 | # else |
michael@0 | 138 | |
michael@0 | 139 | if (GTEST_FLAG(death_test_style) == "threadsafe") |
michael@0 | 140 | return !GTEST_FLAG(internal_run_death_test).empty(); |
michael@0 | 141 | else |
michael@0 | 142 | return g_in_fast_death_test_child; |
michael@0 | 143 | #endif |
michael@0 | 144 | } |
michael@0 | 145 | |
michael@0 | 146 | } // namespace internal |
michael@0 | 147 | |
michael@0 | 148 | // ExitedWithCode constructor. |
michael@0 | 149 | ExitedWithCode::ExitedWithCode(int exit_code) : exit_code_(exit_code) { |
michael@0 | 150 | } |
michael@0 | 151 | |
michael@0 | 152 | // ExitedWithCode function-call operator. |
michael@0 | 153 | bool ExitedWithCode::operator()(int exit_status) const { |
michael@0 | 154 | # if GTEST_OS_WINDOWS |
michael@0 | 155 | |
michael@0 | 156 | return exit_status == exit_code_; |
michael@0 | 157 | |
michael@0 | 158 | # else |
michael@0 | 159 | |
michael@0 | 160 | return WIFEXITED(exit_status) && WEXITSTATUS(exit_status) == exit_code_; |
michael@0 | 161 | |
michael@0 | 162 | # endif // GTEST_OS_WINDOWS |
michael@0 | 163 | } |
michael@0 | 164 | |
michael@0 | 165 | # if !GTEST_OS_WINDOWS |
michael@0 | 166 | // KilledBySignal constructor. |
michael@0 | 167 | KilledBySignal::KilledBySignal(int signum) : signum_(signum) { |
michael@0 | 168 | } |
michael@0 | 169 | |
michael@0 | 170 | // KilledBySignal function-call operator. |
michael@0 | 171 | bool KilledBySignal::operator()(int exit_status) const { |
michael@0 | 172 | return WIFSIGNALED(exit_status) && WTERMSIG(exit_status) == signum_; |
michael@0 | 173 | } |
michael@0 | 174 | # endif // !GTEST_OS_WINDOWS |
michael@0 | 175 | |
michael@0 | 176 | namespace internal { |
michael@0 | 177 | |
michael@0 | 178 | // Utilities needed for death tests. |
michael@0 | 179 | |
michael@0 | 180 | // Generates a textual description of a given exit code, in the format |
michael@0 | 181 | // specified by wait(2). |
michael@0 | 182 | static String ExitSummary(int exit_code) { |
michael@0 | 183 | Message m; |
michael@0 | 184 | |
michael@0 | 185 | # if GTEST_OS_WINDOWS |
michael@0 | 186 | |
michael@0 | 187 | m << "Exited with exit status " << exit_code; |
michael@0 | 188 | |
michael@0 | 189 | # else |
michael@0 | 190 | |
michael@0 | 191 | if (WIFEXITED(exit_code)) { |
michael@0 | 192 | m << "Exited with exit status " << WEXITSTATUS(exit_code); |
michael@0 | 193 | } else if (WIFSIGNALED(exit_code)) { |
michael@0 | 194 | m << "Terminated by signal " << WTERMSIG(exit_code); |
michael@0 | 195 | } |
michael@0 | 196 | # ifdef WCOREDUMP |
michael@0 | 197 | if (WCOREDUMP(exit_code)) { |
michael@0 | 198 | m << " (core dumped)"; |
michael@0 | 199 | } |
michael@0 | 200 | # endif |
michael@0 | 201 | # endif // GTEST_OS_WINDOWS |
michael@0 | 202 | |
michael@0 | 203 | return m.GetString(); |
michael@0 | 204 | } |
michael@0 | 205 | |
michael@0 | 206 | // Returns true if exit_status describes a process that was terminated |
michael@0 | 207 | // by a signal, or exited normally with a nonzero exit code. |
michael@0 | 208 | bool ExitedUnsuccessfully(int exit_status) { |
michael@0 | 209 | return !ExitedWithCode(0)(exit_status); |
michael@0 | 210 | } |
michael@0 | 211 | |
michael@0 | 212 | # if !GTEST_OS_WINDOWS |
michael@0 | 213 | // Generates a textual failure message when a death test finds more than |
michael@0 | 214 | // one thread running, or cannot determine the number of threads, prior |
michael@0 | 215 | // to executing the given statement. It is the responsibility of the |
michael@0 | 216 | // caller not to pass a thread_count of 1. |
michael@0 | 217 | static String DeathTestThreadWarning(size_t thread_count) { |
michael@0 | 218 | Message msg; |
michael@0 | 219 | msg << "Death tests use fork(), which is unsafe particularly" |
michael@0 | 220 | << " in a threaded context. For this test, " << GTEST_NAME_ << " "; |
michael@0 | 221 | if (thread_count == 0) |
michael@0 | 222 | msg << "couldn't detect the number of threads."; |
michael@0 | 223 | else |
michael@0 | 224 | msg << "detected " << thread_count << " threads."; |
michael@0 | 225 | return msg.GetString(); |
michael@0 | 226 | } |
michael@0 | 227 | # endif // !GTEST_OS_WINDOWS |
michael@0 | 228 | |
michael@0 | 229 | // Flag characters for reporting a death test that did not die. |
michael@0 | 230 | static const char kDeathTestLived = 'L'; |
michael@0 | 231 | static const char kDeathTestReturned = 'R'; |
michael@0 | 232 | static const char kDeathTestThrew = 'T'; |
michael@0 | 233 | static const char kDeathTestInternalError = 'I'; |
michael@0 | 234 | |
michael@0 | 235 | // An enumeration describing all of the possible ways that a death test can |
michael@0 | 236 | // conclude. DIED means that the process died while executing the test |
michael@0 | 237 | // code; LIVED means that process lived beyond the end of the test code; |
michael@0 | 238 | // RETURNED means that the test statement attempted to execute a return |
michael@0 | 239 | // statement, which is not allowed; THREW means that the test statement |
michael@0 | 240 | // returned control by throwing an exception. IN_PROGRESS means the test |
michael@0 | 241 | // has not yet concluded. |
michael@0 | 242 | // TODO(vladl@google.com): Unify names and possibly values for |
michael@0 | 243 | // AbortReason, DeathTestOutcome, and flag characters above. |
michael@0 | 244 | enum DeathTestOutcome { IN_PROGRESS, DIED, LIVED, RETURNED, THREW }; |
michael@0 | 245 | |
michael@0 | 246 | // Routine for aborting the program which is safe to call from an |
michael@0 | 247 | // exec-style death test child process, in which case the error |
michael@0 | 248 | // message is propagated back to the parent process. Otherwise, the |
michael@0 | 249 | // message is simply printed to stderr. In either case, the program |
michael@0 | 250 | // then exits with status 1. |
michael@0 | 251 | void DeathTestAbort(const String& message) { |
michael@0 | 252 | // On a POSIX system, this function may be called from a threadsafe-style |
michael@0 | 253 | // death test child process, which operates on a very small stack. Use |
michael@0 | 254 | // the heap for any additional non-minuscule memory requirements. |
michael@0 | 255 | const InternalRunDeathTestFlag* const flag = |
michael@0 | 256 | GetUnitTestImpl()->internal_run_death_test_flag(); |
michael@0 | 257 | if (flag != NULL) { |
michael@0 | 258 | FILE* parent = posix::FDOpen(flag->write_fd(), "w"); |
michael@0 | 259 | fputc(kDeathTestInternalError, parent); |
michael@0 | 260 | fprintf(parent, "%s", message.c_str()); |
michael@0 | 261 | fflush(parent); |
michael@0 | 262 | _exit(1); |
michael@0 | 263 | } else { |
michael@0 | 264 | fprintf(stderr, "%s", message.c_str()); |
michael@0 | 265 | fflush(stderr); |
michael@0 | 266 | posix::Abort(); |
michael@0 | 267 | } |
michael@0 | 268 | } |
michael@0 | 269 | |
michael@0 | 270 | // A replacement for CHECK that calls DeathTestAbort if the assertion |
michael@0 | 271 | // fails. |
michael@0 | 272 | # define GTEST_DEATH_TEST_CHECK_(expression) \ |
michael@0 | 273 | do { \ |
michael@0 | 274 | if (!::testing::internal::IsTrue(expression)) { \ |
michael@0 | 275 | DeathTestAbort(::testing::internal::String::Format( \ |
michael@0 | 276 | "CHECK failed: File %s, line %d: %s", \ |
michael@0 | 277 | __FILE__, __LINE__, #expression)); \ |
michael@0 | 278 | } \ |
michael@0 | 279 | } while (::testing::internal::AlwaysFalse()) |
michael@0 | 280 | |
michael@0 | 281 | // This macro is similar to GTEST_DEATH_TEST_CHECK_, but it is meant for |
michael@0 | 282 | // evaluating any system call that fulfills two conditions: it must return |
michael@0 | 283 | // -1 on failure, and set errno to EINTR when it is interrupted and |
michael@0 | 284 | // should be tried again. The macro expands to a loop that repeatedly |
michael@0 | 285 | // evaluates the expression as long as it evaluates to -1 and sets |
michael@0 | 286 | // errno to EINTR. If the expression evaluates to -1 but errno is |
michael@0 | 287 | // something other than EINTR, DeathTestAbort is called. |
michael@0 | 288 | # define GTEST_DEATH_TEST_CHECK_SYSCALL_(expression) \ |
michael@0 | 289 | do { \ |
michael@0 | 290 | int gtest_retval; \ |
michael@0 | 291 | do { \ |
michael@0 | 292 | gtest_retval = (expression); \ |
michael@0 | 293 | } while (gtest_retval == -1 && errno == EINTR); \ |
michael@0 | 294 | if (gtest_retval == -1) { \ |
michael@0 | 295 | DeathTestAbort(::testing::internal::String::Format( \ |
michael@0 | 296 | "CHECK failed: File %s, line %d: %s != -1", \ |
michael@0 | 297 | __FILE__, __LINE__, #expression)); \ |
michael@0 | 298 | } \ |
michael@0 | 299 | } while (::testing::internal::AlwaysFalse()) |
michael@0 | 300 | |
michael@0 | 301 | // Returns the message describing the last system error in errno. |
michael@0 | 302 | String GetLastErrnoDescription() { |
michael@0 | 303 | return String(errno == 0 ? "" : posix::StrError(errno)); |
michael@0 | 304 | } |
michael@0 | 305 | |
michael@0 | 306 | // This is called from a death test parent process to read a failure |
michael@0 | 307 | // message from the death test child process and log it with the FATAL |
michael@0 | 308 | // severity. On Windows, the message is read from a pipe handle. On other |
michael@0 | 309 | // platforms, it is read from a file descriptor. |
michael@0 | 310 | static void FailFromInternalError(int fd) { |
michael@0 | 311 | Message error; |
michael@0 | 312 | char buffer[256]; |
michael@0 | 313 | int num_read; |
michael@0 | 314 | |
michael@0 | 315 | do { |
michael@0 | 316 | while ((num_read = posix::Read(fd, buffer, 255)) > 0) { |
michael@0 | 317 | buffer[num_read] = '\0'; |
michael@0 | 318 | error << buffer; |
michael@0 | 319 | } |
michael@0 | 320 | } while (num_read == -1 && errno == EINTR); |
michael@0 | 321 | |
michael@0 | 322 | if (num_read == 0) { |
michael@0 | 323 | GTEST_LOG_(FATAL) << error.GetString(); |
michael@0 | 324 | } else { |
michael@0 | 325 | const int last_error = errno; |
michael@0 | 326 | GTEST_LOG_(FATAL) << "Error while reading death test internal: " |
michael@0 | 327 | << GetLastErrnoDescription() << " [" << last_error << "]"; |
michael@0 | 328 | } |
michael@0 | 329 | } |
michael@0 | 330 | |
michael@0 | 331 | // Death test constructor. Increments the running death test count |
michael@0 | 332 | // for the current test. |
michael@0 | 333 | DeathTest::DeathTest() { |
michael@0 | 334 | TestInfo* const info = GetUnitTestImpl()->current_test_info(); |
michael@0 | 335 | if (info == NULL) { |
michael@0 | 336 | DeathTestAbort("Cannot run a death test outside of a TEST or " |
michael@0 | 337 | "TEST_F construct"); |
michael@0 | 338 | } |
michael@0 | 339 | } |
michael@0 | 340 | |
michael@0 | 341 | // Creates and returns a death test by dispatching to the current |
michael@0 | 342 | // death test factory. |
michael@0 | 343 | bool DeathTest::Create(const char* statement, const RE* regex, |
michael@0 | 344 | const char* file, int line, DeathTest** test) { |
michael@0 | 345 | return GetUnitTestImpl()->death_test_factory()->Create( |
michael@0 | 346 | statement, regex, file, line, test); |
michael@0 | 347 | } |
michael@0 | 348 | |
michael@0 | 349 | const char* DeathTest::LastMessage() { |
michael@0 | 350 | return last_death_test_message_.c_str(); |
michael@0 | 351 | } |
michael@0 | 352 | |
michael@0 | 353 | void DeathTest::set_last_death_test_message(const String& message) { |
michael@0 | 354 | last_death_test_message_ = message; |
michael@0 | 355 | } |
michael@0 | 356 | |
michael@0 | 357 | String DeathTest::last_death_test_message_; |
michael@0 | 358 | |
michael@0 | 359 | // Provides cross platform implementation for some death functionality. |
michael@0 | 360 | class DeathTestImpl : public DeathTest { |
michael@0 | 361 | protected: |
michael@0 | 362 | DeathTestImpl(const char* a_statement, const RE* a_regex) |
michael@0 | 363 | : statement_(a_statement), |
michael@0 | 364 | regex_(a_regex), |
michael@0 | 365 | spawned_(false), |
michael@0 | 366 | status_(-1), |
michael@0 | 367 | outcome_(IN_PROGRESS), |
michael@0 | 368 | read_fd_(-1), |
michael@0 | 369 | write_fd_(-1) {} |
michael@0 | 370 | |
michael@0 | 371 | // read_fd_ is expected to be closed and cleared by a derived class. |
michael@0 | 372 | ~DeathTestImpl() { GTEST_DEATH_TEST_CHECK_(read_fd_ == -1); } |
michael@0 | 373 | |
michael@0 | 374 | void Abort(AbortReason reason); |
michael@0 | 375 | virtual bool Passed(bool status_ok); |
michael@0 | 376 | |
michael@0 | 377 | const char* statement() const { return statement_; } |
michael@0 | 378 | const RE* regex() const { return regex_; } |
michael@0 | 379 | bool spawned() const { return spawned_; } |
michael@0 | 380 | void set_spawned(bool is_spawned) { spawned_ = is_spawned; } |
michael@0 | 381 | int status() const { return status_; } |
michael@0 | 382 | void set_status(int a_status) { status_ = a_status; } |
michael@0 | 383 | DeathTestOutcome outcome() const { return outcome_; } |
michael@0 | 384 | void set_outcome(DeathTestOutcome an_outcome) { outcome_ = an_outcome; } |
michael@0 | 385 | int read_fd() const { return read_fd_; } |
michael@0 | 386 | void set_read_fd(int fd) { read_fd_ = fd; } |
michael@0 | 387 | int write_fd() const { return write_fd_; } |
michael@0 | 388 | void set_write_fd(int fd) { write_fd_ = fd; } |
michael@0 | 389 | |
michael@0 | 390 | // Called in the parent process only. Reads the result code of the death |
michael@0 | 391 | // test child process via a pipe, interprets it to set the outcome_ |
michael@0 | 392 | // member, and closes read_fd_. Outputs diagnostics and terminates in |
michael@0 | 393 | // case of unexpected codes. |
michael@0 | 394 | void ReadAndInterpretStatusByte(); |
michael@0 | 395 | |
michael@0 | 396 | private: |
michael@0 | 397 | // The textual content of the code this object is testing. This class |
michael@0 | 398 | // doesn't own this string and should not attempt to delete it. |
michael@0 | 399 | const char* const statement_; |
michael@0 | 400 | // The regular expression which test output must match. DeathTestImpl |
michael@0 | 401 | // doesn't own this object and should not attempt to delete it. |
michael@0 | 402 | const RE* const regex_; |
michael@0 | 403 | // True if the death test child process has been successfully spawned. |
michael@0 | 404 | bool spawned_; |
michael@0 | 405 | // The exit status of the child process. |
michael@0 | 406 | int status_; |
michael@0 | 407 | // How the death test concluded. |
michael@0 | 408 | DeathTestOutcome outcome_; |
michael@0 | 409 | // Descriptor to the read end of the pipe to the child process. It is |
michael@0 | 410 | // always -1 in the child process. The child keeps its write end of the |
michael@0 | 411 | // pipe in write_fd_. |
michael@0 | 412 | int read_fd_; |
michael@0 | 413 | // Descriptor to the child's write end of the pipe to the parent process. |
michael@0 | 414 | // It is always -1 in the parent process. The parent keeps its end of the |
michael@0 | 415 | // pipe in read_fd_. |
michael@0 | 416 | int write_fd_; |
michael@0 | 417 | }; |
michael@0 | 418 | |
michael@0 | 419 | // Called in the parent process only. Reads the result code of the death |
michael@0 | 420 | // test child process via a pipe, interprets it to set the outcome_ |
michael@0 | 421 | // member, and closes read_fd_. Outputs diagnostics and terminates in |
michael@0 | 422 | // case of unexpected codes. |
michael@0 | 423 | void DeathTestImpl::ReadAndInterpretStatusByte() { |
michael@0 | 424 | char flag; |
michael@0 | 425 | int bytes_read; |
michael@0 | 426 | |
michael@0 | 427 | // The read() here blocks until data is available (signifying the |
michael@0 | 428 | // failure of the death test) or until the pipe is closed (signifying |
michael@0 | 429 | // its success), so it's okay to call this in the parent before |
michael@0 | 430 | // the child process has exited. |
michael@0 | 431 | do { |
michael@0 | 432 | bytes_read = posix::Read(read_fd(), &flag, 1); |
michael@0 | 433 | } while (bytes_read == -1 && errno == EINTR); |
michael@0 | 434 | |
michael@0 | 435 | if (bytes_read == 0) { |
michael@0 | 436 | set_outcome(DIED); |
michael@0 | 437 | } else if (bytes_read == 1) { |
michael@0 | 438 | switch (flag) { |
michael@0 | 439 | case kDeathTestReturned: |
michael@0 | 440 | set_outcome(RETURNED); |
michael@0 | 441 | break; |
michael@0 | 442 | case kDeathTestThrew: |
michael@0 | 443 | set_outcome(THREW); |
michael@0 | 444 | break; |
michael@0 | 445 | case kDeathTestLived: |
michael@0 | 446 | set_outcome(LIVED); |
michael@0 | 447 | break; |
michael@0 | 448 | case kDeathTestInternalError: |
michael@0 | 449 | FailFromInternalError(read_fd()); // Does not return. |
michael@0 | 450 | break; |
michael@0 | 451 | default: |
michael@0 | 452 | GTEST_LOG_(FATAL) << "Death test child process reported " |
michael@0 | 453 | << "unexpected status byte (" |
michael@0 | 454 | << static_cast<unsigned int>(flag) << ")"; |
michael@0 | 455 | } |
michael@0 | 456 | } else { |
michael@0 | 457 | GTEST_LOG_(FATAL) << "Read from death test child process failed: " |
michael@0 | 458 | << GetLastErrnoDescription(); |
michael@0 | 459 | } |
michael@0 | 460 | GTEST_DEATH_TEST_CHECK_SYSCALL_(posix::Close(read_fd())); |
michael@0 | 461 | set_read_fd(-1); |
michael@0 | 462 | } |
michael@0 | 463 | |
michael@0 | 464 | // Signals that the death test code which should have exited, didn't. |
michael@0 | 465 | // Should be called only in a death test child process. |
michael@0 | 466 | // Writes a status byte to the child's status file descriptor, then |
michael@0 | 467 | // calls _exit(1). |
michael@0 | 468 | void DeathTestImpl::Abort(AbortReason reason) { |
michael@0 | 469 | // The parent process considers the death test to be a failure if |
michael@0 | 470 | // it finds any data in our pipe. So, here we write a single flag byte |
michael@0 | 471 | // to the pipe, then exit. |
michael@0 | 472 | const char status_ch = |
michael@0 | 473 | reason == TEST_DID_NOT_DIE ? kDeathTestLived : |
michael@0 | 474 | reason == TEST_THREW_EXCEPTION ? kDeathTestThrew : kDeathTestReturned; |
michael@0 | 475 | |
michael@0 | 476 | GTEST_DEATH_TEST_CHECK_SYSCALL_(posix::Write(write_fd(), &status_ch, 1)); |
michael@0 | 477 | // We are leaking the descriptor here because on some platforms (i.e., |
michael@0 | 478 | // when built as Windows DLL), destructors of global objects will still |
michael@0 | 479 | // run after calling _exit(). On such systems, write_fd_ will be |
michael@0 | 480 | // indirectly closed from the destructor of UnitTestImpl, causing double |
michael@0 | 481 | // close if it is also closed here. On debug configurations, double close |
michael@0 | 482 | // may assert. As there are no in-process buffers to flush here, we are |
michael@0 | 483 | // relying on the OS to close the descriptor after the process terminates |
michael@0 | 484 | // when the destructors are not run. |
michael@0 | 485 | _exit(1); // Exits w/o any normal exit hooks (we were supposed to crash) |
michael@0 | 486 | } |
michael@0 | 487 | |
michael@0 | 488 | // Returns an indented copy of stderr output for a death test. |
michael@0 | 489 | // This makes distinguishing death test output lines from regular log lines |
michael@0 | 490 | // much easier. |
michael@0 | 491 | static ::std::string FormatDeathTestOutput(const ::std::string& output) { |
michael@0 | 492 | ::std::string ret; |
michael@0 | 493 | for (size_t at = 0; ; ) { |
michael@0 | 494 | const size_t line_end = output.find('\n', at); |
michael@0 | 495 | ret += "[ DEATH ] "; |
michael@0 | 496 | if (line_end == ::std::string::npos) { |
michael@0 | 497 | ret += output.substr(at); |
michael@0 | 498 | break; |
michael@0 | 499 | } |
michael@0 | 500 | ret += output.substr(at, line_end + 1 - at); |
michael@0 | 501 | at = line_end + 1; |
michael@0 | 502 | } |
michael@0 | 503 | return ret; |
michael@0 | 504 | } |
michael@0 | 505 | |
michael@0 | 506 | // Assesses the success or failure of a death test, using both private |
michael@0 | 507 | // members which have previously been set, and one argument: |
michael@0 | 508 | // |
michael@0 | 509 | // Private data members: |
michael@0 | 510 | // outcome: An enumeration describing how the death test |
michael@0 | 511 | // concluded: DIED, LIVED, THREW, or RETURNED. The death test |
michael@0 | 512 | // fails in the latter three cases. |
michael@0 | 513 | // status: The exit status of the child process. On *nix, it is in the |
michael@0 | 514 | // in the format specified by wait(2). On Windows, this is the |
michael@0 | 515 | // value supplied to the ExitProcess() API or a numeric code |
michael@0 | 516 | // of the exception that terminated the program. |
michael@0 | 517 | // regex: A regular expression object to be applied to |
michael@0 | 518 | // the test's captured standard error output; the death test |
michael@0 | 519 | // fails if it does not match. |
michael@0 | 520 | // |
michael@0 | 521 | // Argument: |
michael@0 | 522 | // status_ok: true if exit_status is acceptable in the context of |
michael@0 | 523 | // this particular death test, which fails if it is false |
michael@0 | 524 | // |
michael@0 | 525 | // Returns true iff all of the above conditions are met. Otherwise, the |
michael@0 | 526 | // first failing condition, in the order given above, is the one that is |
michael@0 | 527 | // reported. Also sets the last death test message string. |
michael@0 | 528 | bool DeathTestImpl::Passed(bool status_ok) { |
michael@0 | 529 | if (!spawned()) |
michael@0 | 530 | return false; |
michael@0 | 531 | |
michael@0 | 532 | const String error_message = GetCapturedStderr(); |
michael@0 | 533 | |
michael@0 | 534 | bool success = false; |
michael@0 | 535 | Message buffer; |
michael@0 | 536 | |
michael@0 | 537 | buffer << "Death test: " << statement() << "\n"; |
michael@0 | 538 | switch (outcome()) { |
michael@0 | 539 | case LIVED: |
michael@0 | 540 | buffer << " Result: failed to die.\n" |
michael@0 | 541 | << " Error msg:\n" << FormatDeathTestOutput(error_message); |
michael@0 | 542 | break; |
michael@0 | 543 | case THREW: |
michael@0 | 544 | buffer << " Result: threw an exception.\n" |
michael@0 | 545 | << " Error msg:\n" << FormatDeathTestOutput(error_message); |
michael@0 | 546 | break; |
michael@0 | 547 | case RETURNED: |
michael@0 | 548 | buffer << " Result: illegal return in test statement.\n" |
michael@0 | 549 | << " Error msg:\n" << FormatDeathTestOutput(error_message); |
michael@0 | 550 | break; |
michael@0 | 551 | case DIED: |
michael@0 | 552 | if (status_ok) { |
michael@0 | 553 | const bool matched = RE::PartialMatch(error_message.c_str(), *regex()); |
michael@0 | 554 | if (matched) { |
michael@0 | 555 | success = true; |
michael@0 | 556 | } else { |
michael@0 | 557 | buffer << " Result: died but not with expected error.\n" |
michael@0 | 558 | << " Expected: " << regex()->pattern() << "\n" |
michael@0 | 559 | << "Actual msg:\n" << FormatDeathTestOutput(error_message); |
michael@0 | 560 | } |
michael@0 | 561 | } else { |
michael@0 | 562 | buffer << " Result: died but not with expected exit code:\n" |
michael@0 | 563 | << " " << ExitSummary(status()) << "\n" |
michael@0 | 564 | << "Actual msg:\n" << FormatDeathTestOutput(error_message); |
michael@0 | 565 | } |
michael@0 | 566 | break; |
michael@0 | 567 | case IN_PROGRESS: |
michael@0 | 568 | default: |
michael@0 | 569 | GTEST_LOG_(FATAL) |
michael@0 | 570 | << "DeathTest::Passed somehow called before conclusion of test"; |
michael@0 | 571 | } |
michael@0 | 572 | |
michael@0 | 573 | DeathTest::set_last_death_test_message(buffer.GetString()); |
michael@0 | 574 | return success; |
michael@0 | 575 | } |
michael@0 | 576 | |
michael@0 | 577 | # if GTEST_OS_WINDOWS |
michael@0 | 578 | // WindowsDeathTest implements death tests on Windows. Due to the |
michael@0 | 579 | // specifics of starting new processes on Windows, death tests there are |
michael@0 | 580 | // always threadsafe, and Google Test considers the |
michael@0 | 581 | // --gtest_death_test_style=fast setting to be equivalent to |
michael@0 | 582 | // --gtest_death_test_style=threadsafe there. |
michael@0 | 583 | // |
michael@0 | 584 | // A few implementation notes: Like the Linux version, the Windows |
michael@0 | 585 | // implementation uses pipes for child-to-parent communication. But due to |
michael@0 | 586 | // the specifics of pipes on Windows, some extra steps are required: |
michael@0 | 587 | // |
michael@0 | 588 | // 1. The parent creates a communication pipe and stores handles to both |
michael@0 | 589 | // ends of it. |
michael@0 | 590 | // 2. The parent starts the child and provides it with the information |
michael@0 | 591 | // necessary to acquire the handle to the write end of the pipe. |
michael@0 | 592 | // 3. The child acquires the write end of the pipe and signals the parent |
michael@0 | 593 | // using a Windows event. |
michael@0 | 594 | // 4. Now the parent can release the write end of the pipe on its side. If |
michael@0 | 595 | // this is done before step 3, the object's reference count goes down to |
michael@0 | 596 | // 0 and it is destroyed, preventing the child from acquiring it. The |
michael@0 | 597 | // parent now has to release it, or read operations on the read end of |
michael@0 | 598 | // the pipe will not return when the child terminates. |
michael@0 | 599 | // 5. The parent reads child's output through the pipe (outcome code and |
michael@0 | 600 | // any possible error messages) from the pipe, and its stderr and then |
michael@0 | 601 | // determines whether to fail the test. |
michael@0 | 602 | // |
michael@0 | 603 | // Note: to distinguish Win32 API calls from the local method and function |
michael@0 | 604 | // calls, the former are explicitly resolved in the global namespace. |
michael@0 | 605 | // |
michael@0 | 606 | class WindowsDeathTest : public DeathTestImpl { |
michael@0 | 607 | public: |
michael@0 | 608 | WindowsDeathTest(const char* a_statement, |
michael@0 | 609 | const RE* a_regex, |
michael@0 | 610 | const char* file, |
michael@0 | 611 | int line) |
michael@0 | 612 | : DeathTestImpl(a_statement, a_regex), file_(file), line_(line) {} |
michael@0 | 613 | |
michael@0 | 614 | // All of these virtual functions are inherited from DeathTest. |
michael@0 | 615 | virtual int Wait(); |
michael@0 | 616 | virtual TestRole AssumeRole(); |
michael@0 | 617 | |
michael@0 | 618 | private: |
michael@0 | 619 | // The name of the file in which the death test is located. |
michael@0 | 620 | const char* const file_; |
michael@0 | 621 | // The line number on which the death test is located. |
michael@0 | 622 | const int line_; |
michael@0 | 623 | // Handle to the write end of the pipe to the child process. |
michael@0 | 624 | AutoHandle write_handle_; |
michael@0 | 625 | // Child process handle. |
michael@0 | 626 | AutoHandle child_handle_; |
michael@0 | 627 | // Event the child process uses to signal the parent that it has |
michael@0 | 628 | // acquired the handle to the write end of the pipe. After seeing this |
michael@0 | 629 | // event the parent can release its own handles to make sure its |
michael@0 | 630 | // ReadFile() calls return when the child terminates. |
michael@0 | 631 | AutoHandle event_handle_; |
michael@0 | 632 | }; |
michael@0 | 633 | |
michael@0 | 634 | // Waits for the child in a death test to exit, returning its exit |
michael@0 | 635 | // status, or 0 if no child process exists. As a side effect, sets the |
michael@0 | 636 | // outcome data member. |
michael@0 | 637 | int WindowsDeathTest::Wait() { |
michael@0 | 638 | if (!spawned()) |
michael@0 | 639 | return 0; |
michael@0 | 640 | |
michael@0 | 641 | // Wait until the child either signals that it has acquired the write end |
michael@0 | 642 | // of the pipe or it dies. |
michael@0 | 643 | const HANDLE wait_handles[2] = { child_handle_.Get(), event_handle_.Get() }; |
michael@0 | 644 | switch (::WaitForMultipleObjects(2, |
michael@0 | 645 | wait_handles, |
michael@0 | 646 | FALSE, // Waits for any of the handles. |
michael@0 | 647 | INFINITE)) { |
michael@0 | 648 | case WAIT_OBJECT_0: |
michael@0 | 649 | case WAIT_OBJECT_0 + 1: |
michael@0 | 650 | break; |
michael@0 | 651 | default: |
michael@0 | 652 | GTEST_DEATH_TEST_CHECK_(false); // Should not get here. |
michael@0 | 653 | } |
michael@0 | 654 | |
michael@0 | 655 | // The child has acquired the write end of the pipe or exited. |
michael@0 | 656 | // We release the handle on our side and continue. |
michael@0 | 657 | write_handle_.Reset(); |
michael@0 | 658 | event_handle_.Reset(); |
michael@0 | 659 | |
michael@0 | 660 | ReadAndInterpretStatusByte(); |
michael@0 | 661 | |
michael@0 | 662 | // Waits for the child process to exit if it haven't already. This |
michael@0 | 663 | // returns immediately if the child has already exited, regardless of |
michael@0 | 664 | // whether previous calls to WaitForMultipleObjects synchronized on this |
michael@0 | 665 | // handle or not. |
michael@0 | 666 | GTEST_DEATH_TEST_CHECK_( |
michael@0 | 667 | WAIT_OBJECT_0 == ::WaitForSingleObject(child_handle_.Get(), |
michael@0 | 668 | INFINITE)); |
michael@0 | 669 | DWORD status_code; |
michael@0 | 670 | GTEST_DEATH_TEST_CHECK_( |
michael@0 | 671 | ::GetExitCodeProcess(child_handle_.Get(), &status_code) != FALSE); |
michael@0 | 672 | child_handle_.Reset(); |
michael@0 | 673 | set_status(static_cast<int>(status_code)); |
michael@0 | 674 | return status(); |
michael@0 | 675 | } |
michael@0 | 676 | |
michael@0 | 677 | // The AssumeRole process for a Windows death test. It creates a child |
michael@0 | 678 | // process with the same executable as the current process to run the |
michael@0 | 679 | // death test. The child process is given the --gtest_filter and |
michael@0 | 680 | // --gtest_internal_run_death_test flags such that it knows to run the |
michael@0 | 681 | // current death test only. |
michael@0 | 682 | DeathTest::TestRole WindowsDeathTest::AssumeRole() { |
michael@0 | 683 | const UnitTestImpl* const impl = GetUnitTestImpl(); |
michael@0 | 684 | const InternalRunDeathTestFlag* const flag = |
michael@0 | 685 | impl->internal_run_death_test_flag(); |
michael@0 | 686 | const TestInfo* const info = impl->current_test_info(); |
michael@0 | 687 | const int death_test_index = info->result()->death_test_count(); |
michael@0 | 688 | |
michael@0 | 689 | if (flag != NULL) { |
michael@0 | 690 | // ParseInternalRunDeathTestFlag() has performed all the necessary |
michael@0 | 691 | // processing. |
michael@0 | 692 | set_write_fd(flag->write_fd()); |
michael@0 | 693 | return EXECUTE_TEST; |
michael@0 | 694 | } |
michael@0 | 695 | |
michael@0 | 696 | // WindowsDeathTest uses an anonymous pipe to communicate results of |
michael@0 | 697 | // a death test. |
michael@0 | 698 | SECURITY_ATTRIBUTES handles_are_inheritable = { |
michael@0 | 699 | sizeof(SECURITY_ATTRIBUTES), NULL, TRUE }; |
michael@0 | 700 | HANDLE read_handle, write_handle; |
michael@0 | 701 | GTEST_DEATH_TEST_CHECK_( |
michael@0 | 702 | ::CreatePipe(&read_handle, &write_handle, &handles_are_inheritable, |
michael@0 | 703 | 0) // Default buffer size. |
michael@0 | 704 | != FALSE); |
michael@0 | 705 | set_read_fd(::_open_osfhandle(reinterpret_cast<intptr_t>(read_handle), |
michael@0 | 706 | O_RDONLY)); |
michael@0 | 707 | write_handle_.Reset(write_handle); |
michael@0 | 708 | event_handle_.Reset(::CreateEvent( |
michael@0 | 709 | &handles_are_inheritable, |
michael@0 | 710 | TRUE, // The event will automatically reset to non-signaled state. |
michael@0 | 711 | FALSE, // The initial state is non-signalled. |
michael@0 | 712 | NULL)); // The even is unnamed. |
michael@0 | 713 | GTEST_DEATH_TEST_CHECK_(event_handle_.Get() != NULL); |
michael@0 | 714 | const String filter_flag = String::Format("--%s%s=%s.%s", |
michael@0 | 715 | GTEST_FLAG_PREFIX_, kFilterFlag, |
michael@0 | 716 | info->test_case_name(), |
michael@0 | 717 | info->name()); |
michael@0 | 718 | const String internal_flag = String::Format( |
michael@0 | 719 | "--%s%s=%s|%d|%d|%u|%Iu|%Iu", |
michael@0 | 720 | GTEST_FLAG_PREFIX_, |
michael@0 | 721 | kInternalRunDeathTestFlag, |
michael@0 | 722 | file_, line_, |
michael@0 | 723 | death_test_index, |
michael@0 | 724 | static_cast<unsigned int>(::GetCurrentProcessId()), |
michael@0 | 725 | // size_t has the same with as pointers on both 32-bit and 64-bit |
michael@0 | 726 | // Windows platforms. |
michael@0 | 727 | // See http://msdn.microsoft.com/en-us/library/tcxf1dw6.aspx. |
michael@0 | 728 | reinterpret_cast<size_t>(write_handle), |
michael@0 | 729 | reinterpret_cast<size_t>(event_handle_.Get())); |
michael@0 | 730 | |
michael@0 | 731 | char executable_path[_MAX_PATH + 1]; // NOLINT |
michael@0 | 732 | GTEST_DEATH_TEST_CHECK_( |
michael@0 | 733 | _MAX_PATH + 1 != ::GetModuleFileNameA(NULL, |
michael@0 | 734 | executable_path, |
michael@0 | 735 | _MAX_PATH)); |
michael@0 | 736 | |
michael@0 | 737 | String command_line = String::Format("%s %s \"%s\"", |
michael@0 | 738 | ::GetCommandLineA(), |
michael@0 | 739 | filter_flag.c_str(), |
michael@0 | 740 | internal_flag.c_str()); |
michael@0 | 741 | |
michael@0 | 742 | DeathTest::set_last_death_test_message(""); |
michael@0 | 743 | |
michael@0 | 744 | CaptureStderr(); |
michael@0 | 745 | // Flush the log buffers since the log streams are shared with the child. |
michael@0 | 746 | FlushInfoLog(); |
michael@0 | 747 | |
michael@0 | 748 | // The child process will share the standard handles with the parent. |
michael@0 | 749 | STARTUPINFOA startup_info; |
michael@0 | 750 | memset(&startup_info, 0, sizeof(STARTUPINFO)); |
michael@0 | 751 | startup_info.dwFlags = STARTF_USESTDHANDLES; |
michael@0 | 752 | startup_info.hStdInput = ::GetStdHandle(STD_INPUT_HANDLE); |
michael@0 | 753 | startup_info.hStdOutput = ::GetStdHandle(STD_OUTPUT_HANDLE); |
michael@0 | 754 | startup_info.hStdError = ::GetStdHandle(STD_ERROR_HANDLE); |
michael@0 | 755 | |
michael@0 | 756 | PROCESS_INFORMATION process_info; |
michael@0 | 757 | GTEST_DEATH_TEST_CHECK_(::CreateProcessA( |
michael@0 | 758 | executable_path, |
michael@0 | 759 | const_cast<char*>(command_line.c_str()), |
michael@0 | 760 | NULL, // Retuned process handle is not inheritable. |
michael@0 | 761 | NULL, // Retuned thread handle is not inheritable. |
michael@0 | 762 | TRUE, // Child inherits all inheritable handles (for write_handle_). |
michael@0 | 763 | 0x0, // Default creation flags. |
michael@0 | 764 | NULL, // Inherit the parent's environment. |
michael@0 | 765 | UnitTest::GetInstance()->original_working_dir(), |
michael@0 | 766 | &startup_info, |
michael@0 | 767 | &process_info) != FALSE); |
michael@0 | 768 | child_handle_.Reset(process_info.hProcess); |
michael@0 | 769 | ::CloseHandle(process_info.hThread); |
michael@0 | 770 | set_spawned(true); |
michael@0 | 771 | return OVERSEE_TEST; |
michael@0 | 772 | } |
michael@0 | 773 | # else // We are not on Windows. |
michael@0 | 774 | |
michael@0 | 775 | // ForkingDeathTest provides implementations for most of the abstract |
michael@0 | 776 | // methods of the DeathTest interface. Only the AssumeRole method is |
michael@0 | 777 | // left undefined. |
michael@0 | 778 | class ForkingDeathTest : public DeathTestImpl { |
michael@0 | 779 | public: |
michael@0 | 780 | ForkingDeathTest(const char* statement, const RE* regex); |
michael@0 | 781 | |
michael@0 | 782 | // All of these virtual functions are inherited from DeathTest. |
michael@0 | 783 | virtual int Wait(); |
michael@0 | 784 | |
michael@0 | 785 | protected: |
michael@0 | 786 | void set_child_pid(pid_t child_pid) { child_pid_ = child_pid; } |
michael@0 | 787 | |
michael@0 | 788 | private: |
michael@0 | 789 | // PID of child process during death test; 0 in the child process itself. |
michael@0 | 790 | pid_t child_pid_; |
michael@0 | 791 | }; |
michael@0 | 792 | |
michael@0 | 793 | // Constructs a ForkingDeathTest. |
michael@0 | 794 | ForkingDeathTest::ForkingDeathTest(const char* a_statement, const RE* a_regex) |
michael@0 | 795 | : DeathTestImpl(a_statement, a_regex), |
michael@0 | 796 | child_pid_(-1) {} |
michael@0 | 797 | |
michael@0 | 798 | // Waits for the child in a death test to exit, returning its exit |
michael@0 | 799 | // status, or 0 if no child process exists. As a side effect, sets the |
michael@0 | 800 | // outcome data member. |
michael@0 | 801 | int ForkingDeathTest::Wait() { |
michael@0 | 802 | if (!spawned()) |
michael@0 | 803 | return 0; |
michael@0 | 804 | |
michael@0 | 805 | ReadAndInterpretStatusByte(); |
michael@0 | 806 | |
michael@0 | 807 | int status_value; |
michael@0 | 808 | GTEST_DEATH_TEST_CHECK_SYSCALL_(waitpid(child_pid_, &status_value, 0)); |
michael@0 | 809 | set_status(status_value); |
michael@0 | 810 | return status_value; |
michael@0 | 811 | } |
michael@0 | 812 | |
michael@0 | 813 | // A concrete death test class that forks, then immediately runs the test |
michael@0 | 814 | // in the child process. |
michael@0 | 815 | class NoExecDeathTest : public ForkingDeathTest { |
michael@0 | 816 | public: |
michael@0 | 817 | NoExecDeathTest(const char* a_statement, const RE* a_regex) : |
michael@0 | 818 | ForkingDeathTest(a_statement, a_regex) { } |
michael@0 | 819 | virtual TestRole AssumeRole(); |
michael@0 | 820 | }; |
michael@0 | 821 | |
michael@0 | 822 | // The AssumeRole process for a fork-and-run death test. It implements a |
michael@0 | 823 | // straightforward fork, with a simple pipe to transmit the status byte. |
michael@0 | 824 | DeathTest::TestRole NoExecDeathTest::AssumeRole() { |
michael@0 | 825 | const size_t thread_count = GetThreadCount(); |
michael@0 | 826 | if (thread_count != 1) { |
michael@0 | 827 | GTEST_LOG_(WARNING) << DeathTestThreadWarning(thread_count); |
michael@0 | 828 | } |
michael@0 | 829 | |
michael@0 | 830 | int pipe_fd[2]; |
michael@0 | 831 | GTEST_DEATH_TEST_CHECK_(pipe(pipe_fd) != -1); |
michael@0 | 832 | |
michael@0 | 833 | DeathTest::set_last_death_test_message(""); |
michael@0 | 834 | CaptureStderr(); |
michael@0 | 835 | // When we fork the process below, the log file buffers are copied, but the |
michael@0 | 836 | // file descriptors are shared. We flush all log files here so that closing |
michael@0 | 837 | // the file descriptors in the child process doesn't throw off the |
michael@0 | 838 | // synchronization between descriptors and buffers in the parent process. |
michael@0 | 839 | // This is as close to the fork as possible to avoid a race condition in case |
michael@0 | 840 | // there are multiple threads running before the death test, and another |
michael@0 | 841 | // thread writes to the log file. |
michael@0 | 842 | FlushInfoLog(); |
michael@0 | 843 | |
michael@0 | 844 | const pid_t child_pid = fork(); |
michael@0 | 845 | GTEST_DEATH_TEST_CHECK_(child_pid != -1); |
michael@0 | 846 | set_child_pid(child_pid); |
michael@0 | 847 | if (child_pid == 0) { |
michael@0 | 848 | GTEST_DEATH_TEST_CHECK_SYSCALL_(close(pipe_fd[0])); |
michael@0 | 849 | set_write_fd(pipe_fd[1]); |
michael@0 | 850 | // Redirects all logging to stderr in the child process to prevent |
michael@0 | 851 | // concurrent writes to the log files. We capture stderr in the parent |
michael@0 | 852 | // process and append the child process' output to a log. |
michael@0 | 853 | LogToStderr(); |
michael@0 | 854 | // Event forwarding to the listeners of event listener API mush be shut |
michael@0 | 855 | // down in death test subprocesses. |
michael@0 | 856 | GetUnitTestImpl()->listeners()->SuppressEventForwarding(); |
michael@0 | 857 | g_in_fast_death_test_child = true; |
michael@0 | 858 | return EXECUTE_TEST; |
michael@0 | 859 | } else { |
michael@0 | 860 | GTEST_DEATH_TEST_CHECK_SYSCALL_(close(pipe_fd[1])); |
michael@0 | 861 | set_read_fd(pipe_fd[0]); |
michael@0 | 862 | set_spawned(true); |
michael@0 | 863 | return OVERSEE_TEST; |
michael@0 | 864 | } |
michael@0 | 865 | } |
michael@0 | 866 | |
michael@0 | 867 | // A concrete death test class that forks and re-executes the main |
michael@0 | 868 | // program from the beginning, with command-line flags set that cause |
michael@0 | 869 | // only this specific death test to be run. |
michael@0 | 870 | class ExecDeathTest : public ForkingDeathTest { |
michael@0 | 871 | public: |
michael@0 | 872 | ExecDeathTest(const char* a_statement, const RE* a_regex, |
michael@0 | 873 | const char* file, int line) : |
michael@0 | 874 | ForkingDeathTest(a_statement, a_regex), file_(file), line_(line) { } |
michael@0 | 875 | virtual TestRole AssumeRole(); |
michael@0 | 876 | private: |
michael@0 | 877 | static ::std::vector<testing::internal::string> |
michael@0 | 878 | GetArgvsForDeathTestChildProcess() { |
michael@0 | 879 | ::std::vector<testing::internal::string> args = GetInjectableArgvs(); |
michael@0 | 880 | return args; |
michael@0 | 881 | } |
michael@0 | 882 | // The name of the file in which the death test is located. |
michael@0 | 883 | const char* const file_; |
michael@0 | 884 | // The line number on which the death test is located. |
michael@0 | 885 | const int line_; |
michael@0 | 886 | }; |
michael@0 | 887 | |
michael@0 | 888 | // Utility class for accumulating command-line arguments. |
michael@0 | 889 | class Arguments { |
michael@0 | 890 | public: |
michael@0 | 891 | Arguments() { |
michael@0 | 892 | args_.push_back(NULL); |
michael@0 | 893 | } |
michael@0 | 894 | |
michael@0 | 895 | ~Arguments() { |
michael@0 | 896 | for (std::vector<char*>::iterator i = args_.begin(); i != args_.end(); |
michael@0 | 897 | ++i) { |
michael@0 | 898 | free(*i); |
michael@0 | 899 | } |
michael@0 | 900 | } |
michael@0 | 901 | void AddArgument(const char* argument) { |
michael@0 | 902 | args_.insert(args_.end() - 1, posix::StrDup(argument)); |
michael@0 | 903 | } |
michael@0 | 904 | |
michael@0 | 905 | template <typename Str> |
michael@0 | 906 | void AddArguments(const ::std::vector<Str>& arguments) { |
michael@0 | 907 | for (typename ::std::vector<Str>::const_iterator i = arguments.begin(); |
michael@0 | 908 | i != arguments.end(); |
michael@0 | 909 | ++i) { |
michael@0 | 910 | args_.insert(args_.end() - 1, posix::StrDup(i->c_str())); |
michael@0 | 911 | } |
michael@0 | 912 | } |
michael@0 | 913 | char* const* Argv() { |
michael@0 | 914 | return &args_[0]; |
michael@0 | 915 | } |
michael@0 | 916 | |
michael@0 | 917 | private: |
michael@0 | 918 | std::vector<char*> args_; |
michael@0 | 919 | }; |
michael@0 | 920 | |
michael@0 | 921 | // A struct that encompasses the arguments to the child process of a |
michael@0 | 922 | // threadsafe-style death test process. |
michael@0 | 923 | struct ExecDeathTestArgs { |
michael@0 | 924 | char* const* argv; // Command-line arguments for the child's call to exec |
michael@0 | 925 | int close_fd; // File descriptor to close; the read end of a pipe |
michael@0 | 926 | }; |
michael@0 | 927 | |
michael@0 | 928 | # if GTEST_OS_MAC |
michael@0 | 929 | inline char** GetEnviron() { |
michael@0 | 930 | // When Google Test is built as a framework on MacOS X, the environ variable |
michael@0 | 931 | // is unavailable. Apple's documentation (man environ) recommends using |
michael@0 | 932 | // _NSGetEnviron() instead. |
michael@0 | 933 | return *_NSGetEnviron(); |
michael@0 | 934 | } |
michael@0 | 935 | # else |
michael@0 | 936 | // Some POSIX platforms expect you to declare environ. extern "C" makes |
michael@0 | 937 | // it reside in the global namespace. |
michael@0 | 938 | extern "C" __attribute__ ((visibility ("default"))) char** environ; |
michael@0 | 939 | inline char** GetEnviron() { return environ; } |
michael@0 | 940 | # endif // GTEST_OS_MAC |
michael@0 | 941 | |
michael@0 | 942 | # if !GTEST_OS_QNX |
michael@0 | 943 | // The main function for a threadsafe-style death test child process. |
michael@0 | 944 | // This function is called in a clone()-ed process and thus must avoid |
michael@0 | 945 | // any potentially unsafe operations like malloc or libc functions. |
michael@0 | 946 | static int ExecDeathTestChildMain(void* child_arg) { |
michael@0 | 947 | ExecDeathTestArgs* const args = static_cast<ExecDeathTestArgs*>(child_arg); |
michael@0 | 948 | GTEST_DEATH_TEST_CHECK_SYSCALL_(close(args->close_fd)); |
michael@0 | 949 | |
michael@0 | 950 | // We need to execute the test program in the same environment where |
michael@0 | 951 | // it was originally invoked. Therefore we change to the original |
michael@0 | 952 | // working directory first. |
michael@0 | 953 | const char* const original_dir = |
michael@0 | 954 | UnitTest::GetInstance()->original_working_dir(); |
michael@0 | 955 | // We can safely call chdir() as it's a direct system call. |
michael@0 | 956 | if (chdir(original_dir) != 0) { |
michael@0 | 957 | DeathTestAbort(String::Format("chdir(\"%s\") failed: %s", |
michael@0 | 958 | original_dir, |
michael@0 | 959 | GetLastErrnoDescription().c_str())); |
michael@0 | 960 | return EXIT_FAILURE; |
michael@0 | 961 | } |
michael@0 | 962 | |
michael@0 | 963 | // We can safely call execve() as it's a direct system call. We |
michael@0 | 964 | // cannot use execvp() as it's a libc function and thus potentially |
michael@0 | 965 | // unsafe. Since execve() doesn't search the PATH, the user must |
michael@0 | 966 | // invoke the test program via a valid path that contains at least |
michael@0 | 967 | // one path separator. |
michael@0 | 968 | execve(args->argv[0], args->argv, GetEnviron()); |
michael@0 | 969 | DeathTestAbort(String::Format("execve(%s, ...) in %s failed: %s", |
michael@0 | 970 | args->argv[0], |
michael@0 | 971 | original_dir, |
michael@0 | 972 | GetLastErrnoDescription().c_str())); |
michael@0 | 973 | return EXIT_FAILURE; |
michael@0 | 974 | } |
michael@0 | 975 | # endif // !GTEST_OS_QNX |
michael@0 | 976 | |
michael@0 | 977 | // Two utility routines that together determine the direction the stack |
michael@0 | 978 | // grows. |
michael@0 | 979 | // This could be accomplished more elegantly by a single recursive |
michael@0 | 980 | // function, but we want to guard against the unlikely possibility of |
michael@0 | 981 | // a smart compiler optimizing the recursion away. |
michael@0 | 982 | // |
michael@0 | 983 | // GTEST_NO_INLINE_ is required to prevent GCC 4.6 from inlining |
michael@0 | 984 | // StackLowerThanAddress into StackGrowsDown, which then doesn't give |
michael@0 | 985 | // correct answer. |
michael@0 | 986 | void StackLowerThanAddress(const void* ptr, bool* result) GTEST_NO_INLINE_; |
michael@0 | 987 | void StackLowerThanAddress(const void* ptr, bool* result) { |
michael@0 | 988 | int dummy; |
michael@0 | 989 | *result = (&dummy < ptr); |
michael@0 | 990 | } |
michael@0 | 991 | |
michael@0 | 992 | bool StackGrowsDown() { |
michael@0 | 993 | int dummy; |
michael@0 | 994 | bool result; |
michael@0 | 995 | StackLowerThanAddress(&dummy, &result); |
michael@0 | 996 | return result; |
michael@0 | 997 | } |
michael@0 | 998 | |
michael@0 | 999 | // Spawns a child process with the same executable as the current process in |
michael@0 | 1000 | // a thread-safe manner and instructs it to run the death test. The |
michael@0 | 1001 | // implementation uses fork(2) + exec. On systems where clone(2) is |
michael@0 | 1002 | // available, it is used instead, being slightly more thread-safe. On QNX, |
michael@0 | 1003 | // fork supports only single-threaded environments, so this function uses |
michael@0 | 1004 | // spawn(2) there instead. The function dies with an error message if |
michael@0 | 1005 | // anything goes wrong. |
michael@0 | 1006 | static pid_t ExecDeathTestSpawnChild(char* const* argv, int close_fd) { |
michael@0 | 1007 | ExecDeathTestArgs args = { argv, close_fd }; |
michael@0 | 1008 | pid_t child_pid = -1; |
michael@0 | 1009 | |
michael@0 | 1010 | # if GTEST_OS_QNX |
michael@0 | 1011 | // Obtains the current directory and sets it to be closed in the child |
michael@0 | 1012 | // process. |
michael@0 | 1013 | const int cwd_fd = open(".", O_RDONLY); |
michael@0 | 1014 | GTEST_DEATH_TEST_CHECK_(cwd_fd != -1); |
michael@0 | 1015 | GTEST_DEATH_TEST_CHECK_SYSCALL_(fcntl(cwd_fd, F_SETFD, FD_CLOEXEC)); |
michael@0 | 1016 | // We need to execute the test program in the same environment where |
michael@0 | 1017 | // it was originally invoked. Therefore we change to the original |
michael@0 | 1018 | // working directory first. |
michael@0 | 1019 | const char* const original_dir = |
michael@0 | 1020 | UnitTest::GetInstance()->original_working_dir(); |
michael@0 | 1021 | // We can safely call chdir() as it's a direct system call. |
michael@0 | 1022 | if (chdir(original_dir) != 0) { |
michael@0 | 1023 | DeathTestAbort(String::Format("chdir(\"%s\") failed: %s", |
michael@0 | 1024 | original_dir, |
michael@0 | 1025 | GetLastErrnoDescription().c_str())); |
michael@0 | 1026 | return EXIT_FAILURE; |
michael@0 | 1027 | } |
michael@0 | 1028 | |
michael@0 | 1029 | int fd_flags; |
michael@0 | 1030 | // Set close_fd to be closed after spawn. |
michael@0 | 1031 | GTEST_DEATH_TEST_CHECK_SYSCALL_(fd_flags = fcntl(close_fd, F_GETFD)); |
michael@0 | 1032 | GTEST_DEATH_TEST_CHECK_SYSCALL_(fcntl(close_fd, F_SETFD, |
michael@0 | 1033 | fd_flags | FD_CLOEXEC)); |
michael@0 | 1034 | struct inheritance inherit = {0}; |
michael@0 | 1035 | // spawn is a system call. |
michael@0 | 1036 | child_pid = spawn(args.argv[0], 0, NULL, &inherit, args.argv, GetEnviron()); |
michael@0 | 1037 | // Restores the current working directory. |
michael@0 | 1038 | GTEST_DEATH_TEST_CHECK_(fchdir(cwd_fd) != -1); |
michael@0 | 1039 | GTEST_DEATH_TEST_CHECK_SYSCALL_(close(cwd_fd)); |
michael@0 | 1040 | |
michael@0 | 1041 | # else // GTEST_OS_QNX |
michael@0 | 1042 | # if GTEST_OS_LINUX |
michael@0 | 1043 | // When a SIGPROF signal is received while fork() or clone() are executing, |
michael@0 | 1044 | // the process may hang. To avoid this, we ignore SIGPROF here and re-enable |
michael@0 | 1045 | // it after the call to fork()/clone() is complete. |
michael@0 | 1046 | struct sigaction saved_sigprof_action; |
michael@0 | 1047 | struct sigaction ignore_sigprof_action; |
michael@0 | 1048 | memset(&ignore_sigprof_action, 0, sizeof(ignore_sigprof_action)); |
michael@0 | 1049 | sigemptyset(&ignore_sigprof_action.sa_mask); |
michael@0 | 1050 | ignore_sigprof_action.sa_handler = SIG_IGN; |
michael@0 | 1051 | GTEST_DEATH_TEST_CHECK_SYSCALL_(sigaction( |
michael@0 | 1052 | SIGPROF, &ignore_sigprof_action, &saved_sigprof_action)); |
michael@0 | 1053 | # endif // GTEST_OS_LINUX |
michael@0 | 1054 | |
michael@0 | 1055 | # if GTEST_HAS_CLONE |
michael@0 | 1056 | const bool use_fork = GTEST_FLAG(death_test_use_fork); |
michael@0 | 1057 | |
michael@0 | 1058 | if (!use_fork) { |
michael@0 | 1059 | static const bool stack_grows_down = StackGrowsDown(); |
michael@0 | 1060 | const size_t stack_size = getpagesize(); |
michael@0 | 1061 | // MMAP_ANONYMOUS is not defined on Mac, so we use MAP_ANON instead. |
michael@0 | 1062 | void* const stack = mmap(NULL, stack_size, PROT_READ | PROT_WRITE, |
michael@0 | 1063 | MAP_ANON | MAP_PRIVATE, -1, 0); |
michael@0 | 1064 | GTEST_DEATH_TEST_CHECK_(stack != MAP_FAILED); |
michael@0 | 1065 | |
michael@0 | 1066 | // Maximum stack alignment in bytes: For a downward-growing stack, this |
michael@0 | 1067 | // amount is subtracted from size of the stack space to get an address |
michael@0 | 1068 | // that is within the stack space and is aligned on all systems we care |
michael@0 | 1069 | // about. As far as I know there is no ABI with stack alignment greater |
michael@0 | 1070 | // than 64. We assume stack and stack_size already have alignment of |
michael@0 | 1071 | // kMaxStackAlignment. |
michael@0 | 1072 | const size_t kMaxStackAlignment = 64; |
michael@0 | 1073 | void* const stack_top = |
michael@0 | 1074 | static_cast<char*>(stack) + |
michael@0 | 1075 | (stack_grows_down ? stack_size - kMaxStackAlignment : 0); |
michael@0 | 1076 | GTEST_DEATH_TEST_CHECK_(stack_size > kMaxStackAlignment && |
michael@0 | 1077 | reinterpret_cast<intptr_t>(stack_top) % kMaxStackAlignment == 0); |
michael@0 | 1078 | |
michael@0 | 1079 | child_pid = clone(&ExecDeathTestChildMain, stack_top, SIGCHLD, &args); |
michael@0 | 1080 | |
michael@0 | 1081 | GTEST_DEATH_TEST_CHECK_(munmap(stack, stack_size) != -1); |
michael@0 | 1082 | } |
michael@0 | 1083 | # else |
michael@0 | 1084 | const bool use_fork = true; |
michael@0 | 1085 | # endif // GTEST_HAS_CLONE |
michael@0 | 1086 | |
michael@0 | 1087 | if (use_fork && (child_pid = fork()) == 0) { |
michael@0 | 1088 | ExecDeathTestChildMain(&args); |
michael@0 | 1089 | _exit(0); |
michael@0 | 1090 | } |
michael@0 | 1091 | # endif // GTEST_OS_QNX |
michael@0 | 1092 | # if GTEST_OS_LINUX |
michael@0 | 1093 | GTEST_DEATH_TEST_CHECK_SYSCALL_( |
michael@0 | 1094 | sigaction(SIGPROF, &saved_sigprof_action, NULL)); |
michael@0 | 1095 | # endif // GTEST_OS_LINUX |
michael@0 | 1096 | |
michael@0 | 1097 | GTEST_DEATH_TEST_CHECK_(child_pid != -1); |
michael@0 | 1098 | return child_pid; |
michael@0 | 1099 | } |
michael@0 | 1100 | |
michael@0 | 1101 | // The AssumeRole process for a fork-and-exec death test. It re-executes the |
michael@0 | 1102 | // main program from the beginning, setting the --gtest_filter |
michael@0 | 1103 | // and --gtest_internal_run_death_test flags to cause only the current |
michael@0 | 1104 | // death test to be re-run. |
michael@0 | 1105 | DeathTest::TestRole ExecDeathTest::AssumeRole() { |
michael@0 | 1106 | const UnitTestImpl* const impl = GetUnitTestImpl(); |
michael@0 | 1107 | const InternalRunDeathTestFlag* const flag = |
michael@0 | 1108 | impl->internal_run_death_test_flag(); |
michael@0 | 1109 | const TestInfo* const info = impl->current_test_info(); |
michael@0 | 1110 | const int death_test_index = info->result()->death_test_count(); |
michael@0 | 1111 | |
michael@0 | 1112 | if (flag != NULL) { |
michael@0 | 1113 | set_write_fd(flag->write_fd()); |
michael@0 | 1114 | return EXECUTE_TEST; |
michael@0 | 1115 | } |
michael@0 | 1116 | |
michael@0 | 1117 | int pipe_fd[2]; |
michael@0 | 1118 | GTEST_DEATH_TEST_CHECK_(pipe(pipe_fd) != -1); |
michael@0 | 1119 | // Clear the close-on-exec flag on the write end of the pipe, lest |
michael@0 | 1120 | // it be closed when the child process does an exec: |
michael@0 | 1121 | GTEST_DEATH_TEST_CHECK_(fcntl(pipe_fd[1], F_SETFD, 0) != -1); |
michael@0 | 1122 | |
michael@0 | 1123 | const String filter_flag = |
michael@0 | 1124 | String::Format("--%s%s=%s.%s", |
michael@0 | 1125 | GTEST_FLAG_PREFIX_, kFilterFlag, |
michael@0 | 1126 | info->test_case_name(), info->name()); |
michael@0 | 1127 | const String internal_flag = |
michael@0 | 1128 | String::Format("--%s%s=%s|%d|%d|%d", |
michael@0 | 1129 | GTEST_FLAG_PREFIX_, kInternalRunDeathTestFlag, |
michael@0 | 1130 | file_, line_, death_test_index, pipe_fd[1]); |
michael@0 | 1131 | Arguments args; |
michael@0 | 1132 | args.AddArguments(GetArgvsForDeathTestChildProcess()); |
michael@0 | 1133 | args.AddArgument(filter_flag.c_str()); |
michael@0 | 1134 | args.AddArgument(internal_flag.c_str()); |
michael@0 | 1135 | |
michael@0 | 1136 | DeathTest::set_last_death_test_message(""); |
michael@0 | 1137 | |
michael@0 | 1138 | CaptureStderr(); |
michael@0 | 1139 | // See the comment in NoExecDeathTest::AssumeRole for why the next line |
michael@0 | 1140 | // is necessary. |
michael@0 | 1141 | FlushInfoLog(); |
michael@0 | 1142 | |
michael@0 | 1143 | const pid_t child_pid = ExecDeathTestSpawnChild(args.Argv(), pipe_fd[0]); |
michael@0 | 1144 | GTEST_DEATH_TEST_CHECK_SYSCALL_(close(pipe_fd[1])); |
michael@0 | 1145 | set_child_pid(child_pid); |
michael@0 | 1146 | set_read_fd(pipe_fd[0]); |
michael@0 | 1147 | set_spawned(true); |
michael@0 | 1148 | return OVERSEE_TEST; |
michael@0 | 1149 | } |
michael@0 | 1150 | |
michael@0 | 1151 | # endif // !GTEST_OS_WINDOWS |
michael@0 | 1152 | |
michael@0 | 1153 | // Creates a concrete DeathTest-derived class that depends on the |
michael@0 | 1154 | // --gtest_death_test_style flag, and sets the pointer pointed to |
michael@0 | 1155 | // by the "test" argument to its address. If the test should be |
michael@0 | 1156 | // skipped, sets that pointer to NULL. Returns true, unless the |
michael@0 | 1157 | // flag is set to an invalid value. |
michael@0 | 1158 | bool DefaultDeathTestFactory::Create(const char* statement, const RE* regex, |
michael@0 | 1159 | const char* file, int line, |
michael@0 | 1160 | DeathTest** test) { |
michael@0 | 1161 | UnitTestImpl* const impl = GetUnitTestImpl(); |
michael@0 | 1162 | const InternalRunDeathTestFlag* const flag = |
michael@0 | 1163 | impl->internal_run_death_test_flag(); |
michael@0 | 1164 | const int death_test_index = impl->current_test_info() |
michael@0 | 1165 | ->increment_death_test_count(); |
michael@0 | 1166 | |
michael@0 | 1167 | if (flag != NULL) { |
michael@0 | 1168 | if (death_test_index > flag->index()) { |
michael@0 | 1169 | DeathTest::set_last_death_test_message(String::Format( |
michael@0 | 1170 | "Death test count (%d) somehow exceeded expected maximum (%d)", |
michael@0 | 1171 | death_test_index, flag->index())); |
michael@0 | 1172 | return false; |
michael@0 | 1173 | } |
michael@0 | 1174 | |
michael@0 | 1175 | if (!(flag->file() == file && flag->line() == line && |
michael@0 | 1176 | flag->index() == death_test_index)) { |
michael@0 | 1177 | *test = NULL; |
michael@0 | 1178 | return true; |
michael@0 | 1179 | } |
michael@0 | 1180 | } |
michael@0 | 1181 | |
michael@0 | 1182 | # if GTEST_OS_WINDOWS |
michael@0 | 1183 | |
michael@0 | 1184 | if (GTEST_FLAG(death_test_style) == "threadsafe" || |
michael@0 | 1185 | GTEST_FLAG(death_test_style) == "fast") { |
michael@0 | 1186 | *test = new WindowsDeathTest(statement, regex, file, line); |
michael@0 | 1187 | } |
michael@0 | 1188 | |
michael@0 | 1189 | # else |
michael@0 | 1190 | |
michael@0 | 1191 | if (GTEST_FLAG(death_test_style) == "threadsafe") { |
michael@0 | 1192 | *test = new ExecDeathTest(statement, regex, file, line); |
michael@0 | 1193 | } else if (GTEST_FLAG(death_test_style) == "fast") { |
michael@0 | 1194 | *test = new NoExecDeathTest(statement, regex); |
michael@0 | 1195 | } |
michael@0 | 1196 | |
michael@0 | 1197 | # endif // GTEST_OS_WINDOWS |
michael@0 | 1198 | |
michael@0 | 1199 | else { // NOLINT - this is more readable than unbalanced brackets inside #if. |
michael@0 | 1200 | DeathTest::set_last_death_test_message(String::Format( |
michael@0 | 1201 | "Unknown death test style \"%s\" encountered", |
michael@0 | 1202 | GTEST_FLAG(death_test_style).c_str())); |
michael@0 | 1203 | return false; |
michael@0 | 1204 | } |
michael@0 | 1205 | |
michael@0 | 1206 | return true; |
michael@0 | 1207 | } |
michael@0 | 1208 | |
michael@0 | 1209 | // Splits a given string on a given delimiter, populating a given |
michael@0 | 1210 | // vector with the fields. GTEST_HAS_DEATH_TEST implies that we have |
michael@0 | 1211 | // ::std::string, so we can use it here. |
michael@0 | 1212 | static void SplitString(const ::std::string& str, char delimiter, |
michael@0 | 1213 | ::std::vector< ::std::string>* dest) { |
michael@0 | 1214 | ::std::vector< ::std::string> parsed; |
michael@0 | 1215 | ::std::string::size_type pos = 0; |
michael@0 | 1216 | while (::testing::internal::AlwaysTrue()) { |
michael@0 | 1217 | const ::std::string::size_type colon = str.find(delimiter, pos); |
michael@0 | 1218 | if (colon == ::std::string::npos) { |
michael@0 | 1219 | parsed.push_back(str.substr(pos)); |
michael@0 | 1220 | break; |
michael@0 | 1221 | } else { |
michael@0 | 1222 | parsed.push_back(str.substr(pos, colon - pos)); |
michael@0 | 1223 | pos = colon + 1; |
michael@0 | 1224 | } |
michael@0 | 1225 | } |
michael@0 | 1226 | dest->swap(parsed); |
michael@0 | 1227 | } |
michael@0 | 1228 | |
michael@0 | 1229 | # if GTEST_OS_WINDOWS |
michael@0 | 1230 | // Recreates the pipe and event handles from the provided parameters, |
michael@0 | 1231 | // signals the event, and returns a file descriptor wrapped around the pipe |
michael@0 | 1232 | // handle. This function is called in the child process only. |
michael@0 | 1233 | int GetStatusFileDescriptor(unsigned int parent_process_id, |
michael@0 | 1234 | size_t write_handle_as_size_t, |
michael@0 | 1235 | size_t event_handle_as_size_t) { |
michael@0 | 1236 | AutoHandle parent_process_handle(::OpenProcess(PROCESS_DUP_HANDLE, |
michael@0 | 1237 | FALSE, // Non-inheritable. |
michael@0 | 1238 | parent_process_id)); |
michael@0 | 1239 | if (parent_process_handle.Get() == INVALID_HANDLE_VALUE) { |
michael@0 | 1240 | DeathTestAbort(String::Format("Unable to open parent process %u", |
michael@0 | 1241 | parent_process_id)); |
michael@0 | 1242 | } |
michael@0 | 1243 | |
michael@0 | 1244 | // TODO(vladl@google.com): Replace the following check with a |
michael@0 | 1245 | // compile-time assertion when available. |
michael@0 | 1246 | GTEST_CHECK_(sizeof(HANDLE) <= sizeof(size_t)); |
michael@0 | 1247 | |
michael@0 | 1248 | const HANDLE write_handle = |
michael@0 | 1249 | reinterpret_cast<HANDLE>(write_handle_as_size_t); |
michael@0 | 1250 | HANDLE dup_write_handle; |
michael@0 | 1251 | |
michael@0 | 1252 | // The newly initialized handle is accessible only in in the parent |
michael@0 | 1253 | // process. To obtain one accessible within the child, we need to use |
michael@0 | 1254 | // DuplicateHandle. |
michael@0 | 1255 | if (!::DuplicateHandle(parent_process_handle.Get(), write_handle, |
michael@0 | 1256 | ::GetCurrentProcess(), &dup_write_handle, |
michael@0 | 1257 | 0x0, // Requested privileges ignored since |
michael@0 | 1258 | // DUPLICATE_SAME_ACCESS is used. |
michael@0 | 1259 | FALSE, // Request non-inheritable handler. |
michael@0 | 1260 | DUPLICATE_SAME_ACCESS)) { |
michael@0 | 1261 | DeathTestAbort(String::Format( |
michael@0 | 1262 | "Unable to duplicate the pipe handle %Iu from the parent process %u", |
michael@0 | 1263 | write_handle_as_size_t, parent_process_id)); |
michael@0 | 1264 | } |
michael@0 | 1265 | |
michael@0 | 1266 | const HANDLE event_handle = reinterpret_cast<HANDLE>(event_handle_as_size_t); |
michael@0 | 1267 | HANDLE dup_event_handle; |
michael@0 | 1268 | |
michael@0 | 1269 | if (!::DuplicateHandle(parent_process_handle.Get(), event_handle, |
michael@0 | 1270 | ::GetCurrentProcess(), &dup_event_handle, |
michael@0 | 1271 | 0x0, |
michael@0 | 1272 | FALSE, |
michael@0 | 1273 | DUPLICATE_SAME_ACCESS)) { |
michael@0 | 1274 | DeathTestAbort(String::Format( |
michael@0 | 1275 | "Unable to duplicate the event handle %Iu from the parent process %u", |
michael@0 | 1276 | event_handle_as_size_t, parent_process_id)); |
michael@0 | 1277 | } |
michael@0 | 1278 | |
michael@0 | 1279 | const int write_fd = |
michael@0 | 1280 | ::_open_osfhandle(reinterpret_cast<intptr_t>(dup_write_handle), O_APPEND); |
michael@0 | 1281 | if (write_fd == -1) { |
michael@0 | 1282 | DeathTestAbort(String::Format( |
michael@0 | 1283 | "Unable to convert pipe handle %Iu to a file descriptor", |
michael@0 | 1284 | write_handle_as_size_t)); |
michael@0 | 1285 | } |
michael@0 | 1286 | |
michael@0 | 1287 | // Signals the parent that the write end of the pipe has been acquired |
michael@0 | 1288 | // so the parent can release its own write end. |
michael@0 | 1289 | ::SetEvent(dup_event_handle); |
michael@0 | 1290 | |
michael@0 | 1291 | return write_fd; |
michael@0 | 1292 | } |
michael@0 | 1293 | # endif // GTEST_OS_WINDOWS |
michael@0 | 1294 | |
michael@0 | 1295 | // Returns a newly created InternalRunDeathTestFlag object with fields |
michael@0 | 1296 | // initialized from the GTEST_FLAG(internal_run_death_test) flag if |
michael@0 | 1297 | // the flag is specified; otherwise returns NULL. |
michael@0 | 1298 | InternalRunDeathTestFlag* ParseInternalRunDeathTestFlag() { |
michael@0 | 1299 | if (GTEST_FLAG(internal_run_death_test) == "") return NULL; |
michael@0 | 1300 | |
michael@0 | 1301 | // GTEST_HAS_DEATH_TEST implies that we have ::std::string, so we |
michael@0 | 1302 | // can use it here. |
michael@0 | 1303 | int line = -1; |
michael@0 | 1304 | int index = -1; |
michael@0 | 1305 | ::std::vector< ::std::string> fields; |
michael@0 | 1306 | SplitString(GTEST_FLAG(internal_run_death_test).c_str(), '|', &fields); |
michael@0 | 1307 | int write_fd = -1; |
michael@0 | 1308 | |
michael@0 | 1309 | # if GTEST_OS_WINDOWS |
michael@0 | 1310 | |
michael@0 | 1311 | unsigned int parent_process_id = 0; |
michael@0 | 1312 | size_t write_handle_as_size_t = 0; |
michael@0 | 1313 | size_t event_handle_as_size_t = 0; |
michael@0 | 1314 | |
michael@0 | 1315 | if (fields.size() != 6 |
michael@0 | 1316 | || !ParseNaturalNumber(fields[1], &line) |
michael@0 | 1317 | || !ParseNaturalNumber(fields[2], &index) |
michael@0 | 1318 | || !ParseNaturalNumber(fields[3], &parent_process_id) |
michael@0 | 1319 | || !ParseNaturalNumber(fields[4], &write_handle_as_size_t) |
michael@0 | 1320 | || !ParseNaturalNumber(fields[5], &event_handle_as_size_t)) { |
michael@0 | 1321 | DeathTestAbort(String::Format( |
michael@0 | 1322 | "Bad --gtest_internal_run_death_test flag: %s", |
michael@0 | 1323 | GTEST_FLAG(internal_run_death_test).c_str())); |
michael@0 | 1324 | } |
michael@0 | 1325 | write_fd = GetStatusFileDescriptor(parent_process_id, |
michael@0 | 1326 | write_handle_as_size_t, |
michael@0 | 1327 | event_handle_as_size_t); |
michael@0 | 1328 | # else |
michael@0 | 1329 | |
michael@0 | 1330 | if (fields.size() != 4 |
michael@0 | 1331 | || !ParseNaturalNumber(fields[1], &line) |
michael@0 | 1332 | || !ParseNaturalNumber(fields[2], &index) |
michael@0 | 1333 | || !ParseNaturalNumber(fields[3], &write_fd)) { |
michael@0 | 1334 | DeathTestAbort(String::Format( |
michael@0 | 1335 | "Bad --gtest_internal_run_death_test flag: %s", |
michael@0 | 1336 | GTEST_FLAG(internal_run_death_test).c_str())); |
michael@0 | 1337 | } |
michael@0 | 1338 | |
michael@0 | 1339 | # endif // GTEST_OS_WINDOWS |
michael@0 | 1340 | |
michael@0 | 1341 | return new InternalRunDeathTestFlag(fields[0], line, index, write_fd); |
michael@0 | 1342 | } |
michael@0 | 1343 | |
michael@0 | 1344 | } // namespace internal |
michael@0 | 1345 | |
michael@0 | 1346 | #endif // GTEST_HAS_DEATH_TEST |
michael@0 | 1347 | |
michael@0 | 1348 | } // namespace testing |