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