113481Sgiacomo.travaglini@arm.com// Copyright 2005, Google Inc. 213481Sgiacomo.travaglini@arm.com// All rights reserved. 313481Sgiacomo.travaglini@arm.com// 413481Sgiacomo.travaglini@arm.com// Redistribution and use in source and binary forms, with or without 513481Sgiacomo.travaglini@arm.com// modification, are permitted provided that the following conditions are 613481Sgiacomo.travaglini@arm.com// met: 713481Sgiacomo.travaglini@arm.com// 813481Sgiacomo.travaglini@arm.com// * Redistributions of source code must retain the above copyright 913481Sgiacomo.travaglini@arm.com// notice, this list of conditions and the following disclaimer. 1013481Sgiacomo.travaglini@arm.com// * Redistributions in binary form must reproduce the above 1113481Sgiacomo.travaglini@arm.com// copyright notice, this list of conditions and the following disclaimer 1213481Sgiacomo.travaglini@arm.com// in the documentation and/or other materials provided with the 1313481Sgiacomo.travaglini@arm.com// distribution. 1413481Sgiacomo.travaglini@arm.com// * Neither the name of Google Inc. nor the names of its 1513481Sgiacomo.travaglini@arm.com// contributors may be used to endorse or promote products derived from 1613481Sgiacomo.travaglini@arm.com// this software without specific prior written permission. 1713481Sgiacomo.travaglini@arm.com// 1813481Sgiacomo.travaglini@arm.com// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 1913481Sgiacomo.travaglini@arm.com// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 2013481Sgiacomo.travaglini@arm.com// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 2113481Sgiacomo.travaglini@arm.com// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 2213481Sgiacomo.travaglini@arm.com// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 2313481Sgiacomo.travaglini@arm.com// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 2413481Sgiacomo.travaglini@arm.com// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2513481Sgiacomo.travaglini@arm.com// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2613481Sgiacomo.travaglini@arm.com// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2713481Sgiacomo.travaglini@arm.com// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 2813481Sgiacomo.travaglini@arm.com// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2913481Sgiacomo.travaglini@arm.com// 3013481Sgiacomo.travaglini@arm.com// Author: wan@google.com (Zhanyong Wan), vladl@google.com (Vlad Losev) 3113481Sgiacomo.travaglini@arm.com// 3213481Sgiacomo.travaglini@arm.com// This file implements death tests. 3313481Sgiacomo.travaglini@arm.com 3413481Sgiacomo.travaglini@arm.com#include "gtest/gtest-death-test.h" 3513481Sgiacomo.travaglini@arm.com#include "gtest/internal/gtest-port.h" 3613481Sgiacomo.travaglini@arm.com#include "gtest/internal/custom/gtest.h" 3713481Sgiacomo.travaglini@arm.com 3813481Sgiacomo.travaglini@arm.com#if GTEST_HAS_DEATH_TEST 3913481Sgiacomo.travaglini@arm.com 4013481Sgiacomo.travaglini@arm.com# if GTEST_OS_MAC 4113481Sgiacomo.travaglini@arm.com# include <crt_externs.h> 4213481Sgiacomo.travaglini@arm.com# endif // GTEST_OS_MAC 4313481Sgiacomo.travaglini@arm.com 4413481Sgiacomo.travaglini@arm.com# include <errno.h> 4513481Sgiacomo.travaglini@arm.com# include <fcntl.h> 4613481Sgiacomo.travaglini@arm.com# include <limits.h> 4713481Sgiacomo.travaglini@arm.com 4813481Sgiacomo.travaglini@arm.com# if GTEST_OS_LINUX 4913481Sgiacomo.travaglini@arm.com# include <signal.h> 5013481Sgiacomo.travaglini@arm.com# endif // GTEST_OS_LINUX 5113481Sgiacomo.travaglini@arm.com 5213481Sgiacomo.travaglini@arm.com# include <stdarg.h> 5313481Sgiacomo.travaglini@arm.com 5413481Sgiacomo.travaglini@arm.com# if GTEST_OS_WINDOWS 5513481Sgiacomo.travaglini@arm.com# include <windows.h> 5613481Sgiacomo.travaglini@arm.com# else 5713481Sgiacomo.travaglini@arm.com# include <sys/mman.h> 5813481Sgiacomo.travaglini@arm.com# include <sys/wait.h> 5913481Sgiacomo.travaglini@arm.com# endif // GTEST_OS_WINDOWS 6013481Sgiacomo.travaglini@arm.com 6113481Sgiacomo.travaglini@arm.com# if GTEST_OS_QNX 6213481Sgiacomo.travaglini@arm.com# include <spawn.h> 6313481Sgiacomo.travaglini@arm.com# endif // GTEST_OS_QNX 6413481Sgiacomo.travaglini@arm.com 6513481Sgiacomo.travaglini@arm.com#endif // GTEST_HAS_DEATH_TEST 6613481Sgiacomo.travaglini@arm.com 6713481Sgiacomo.travaglini@arm.com#include "gtest/gtest-message.h" 6813481Sgiacomo.travaglini@arm.com#include "gtest/internal/gtest-string.h" 6913481Sgiacomo.travaglini@arm.com 7013481Sgiacomo.travaglini@arm.com// Indicates that this translation unit is part of Google Test's 7113481Sgiacomo.travaglini@arm.com// implementation. It must come before gtest-internal-inl.h is 7213481Sgiacomo.travaglini@arm.com// included, or there will be a compiler error. This trick exists to 7313481Sgiacomo.travaglini@arm.com// prevent the accidental inclusion of gtest-internal-inl.h in the 7413481Sgiacomo.travaglini@arm.com// user's code. 7513481Sgiacomo.travaglini@arm.com#define GTEST_IMPLEMENTATION_ 1 7613481Sgiacomo.travaglini@arm.com#include "src/gtest-internal-inl.h" 7713481Sgiacomo.travaglini@arm.com#undef GTEST_IMPLEMENTATION_ 7813481Sgiacomo.travaglini@arm.com 7913481Sgiacomo.travaglini@arm.comnamespace testing { 8013481Sgiacomo.travaglini@arm.com 8113481Sgiacomo.travaglini@arm.com// Constants. 8213481Sgiacomo.travaglini@arm.com 8313481Sgiacomo.travaglini@arm.com// The default death test style. 8413481Sgiacomo.travaglini@arm.comstatic const char kDefaultDeathTestStyle[] = "fast"; 8513481Sgiacomo.travaglini@arm.com 8613481Sgiacomo.travaglini@arm.comGTEST_DEFINE_string_( 8713481Sgiacomo.travaglini@arm.com death_test_style, 8813481Sgiacomo.travaglini@arm.com internal::StringFromGTestEnv("death_test_style", kDefaultDeathTestStyle), 8913481Sgiacomo.travaglini@arm.com "Indicates how to run a death test in a forked child process: " 9013481Sgiacomo.travaglini@arm.com "\"threadsafe\" (child process re-executes the test binary " 9113481Sgiacomo.travaglini@arm.com "from the beginning, running only the specific death test) or " 9213481Sgiacomo.travaglini@arm.com "\"fast\" (child process runs the death test immediately " 9313481Sgiacomo.travaglini@arm.com "after forking)."); 9413481Sgiacomo.travaglini@arm.com 9513481Sgiacomo.travaglini@arm.comGTEST_DEFINE_bool_( 9613481Sgiacomo.travaglini@arm.com death_test_use_fork, 9713481Sgiacomo.travaglini@arm.com internal::BoolFromGTestEnv("death_test_use_fork", false), 9813481Sgiacomo.travaglini@arm.com "Instructs to use fork()/_exit() instead of clone() in death tests. " 9913481Sgiacomo.travaglini@arm.com "Ignored and always uses fork() on POSIX systems where clone() is not " 10013481Sgiacomo.travaglini@arm.com "implemented. Useful when running under valgrind or similar tools if " 10113481Sgiacomo.travaglini@arm.com "those do not support clone(). Valgrind 3.3.1 will just fail if " 10213481Sgiacomo.travaglini@arm.com "it sees an unsupported combination of clone() flags. " 10313481Sgiacomo.travaglini@arm.com "It is not recommended to use this flag w/o valgrind though it will " 10413481Sgiacomo.travaglini@arm.com "work in 99% of the cases. Once valgrind is fixed, this flag will " 10513481Sgiacomo.travaglini@arm.com "most likely be removed."); 10613481Sgiacomo.travaglini@arm.com 10713481Sgiacomo.travaglini@arm.comnamespace internal { 10813481Sgiacomo.travaglini@arm.comGTEST_DEFINE_string_( 10913481Sgiacomo.travaglini@arm.com internal_run_death_test, "", 11013481Sgiacomo.travaglini@arm.com "Indicates the file, line number, temporal index of " 11113481Sgiacomo.travaglini@arm.com "the single death test to run, and a file descriptor to " 11213481Sgiacomo.travaglini@arm.com "which a success code may be sent, all separated by " 11313481Sgiacomo.travaglini@arm.com "the '|' characters. This flag is specified if and only if the current " 11413481Sgiacomo.travaglini@arm.com "process is a sub-process launched for running a thread-safe " 11513481Sgiacomo.travaglini@arm.com "death test. FOR INTERNAL USE ONLY."); 11613481Sgiacomo.travaglini@arm.com} // namespace internal 11713481Sgiacomo.travaglini@arm.com 11813481Sgiacomo.travaglini@arm.com#if GTEST_HAS_DEATH_TEST 11913481Sgiacomo.travaglini@arm.com 12013481Sgiacomo.travaglini@arm.comnamespace internal { 12113481Sgiacomo.travaglini@arm.com 12213481Sgiacomo.travaglini@arm.com// Valid only for fast death tests. Indicates the code is running in the 12313481Sgiacomo.travaglini@arm.com// child process of a fast style death test. 12413481Sgiacomo.travaglini@arm.com# if !GTEST_OS_WINDOWS 12513481Sgiacomo.travaglini@arm.comstatic bool g_in_fast_death_test_child = false; 12613481Sgiacomo.travaglini@arm.com# endif 12713481Sgiacomo.travaglini@arm.com 12813481Sgiacomo.travaglini@arm.com// Returns a Boolean value indicating whether the caller is currently 12913481Sgiacomo.travaglini@arm.com// executing in the context of the death test child process. Tools such as 13013481Sgiacomo.travaglini@arm.com// Valgrind heap checkers may need this to modify their behavior in death 13113481Sgiacomo.travaglini@arm.com// tests. IMPORTANT: This is an internal utility. Using it may break the 13213481Sgiacomo.travaglini@arm.com// implementation of death tests. User code MUST NOT use it. 13313481Sgiacomo.travaglini@arm.combool InDeathTestChild() { 13413481Sgiacomo.travaglini@arm.com# if GTEST_OS_WINDOWS 13513481Sgiacomo.travaglini@arm.com 13613481Sgiacomo.travaglini@arm.com // On Windows, death tests are thread-safe regardless of the value of the 13713481Sgiacomo.travaglini@arm.com // death_test_style flag. 13813481Sgiacomo.travaglini@arm.com return !GTEST_FLAG(internal_run_death_test).empty(); 13913481Sgiacomo.travaglini@arm.com 14013481Sgiacomo.travaglini@arm.com# else 14113481Sgiacomo.travaglini@arm.com 14213481Sgiacomo.travaglini@arm.com if (GTEST_FLAG(death_test_style) == "threadsafe") 14313481Sgiacomo.travaglini@arm.com return !GTEST_FLAG(internal_run_death_test).empty(); 14413481Sgiacomo.travaglini@arm.com else 14513481Sgiacomo.travaglini@arm.com return g_in_fast_death_test_child; 14613481Sgiacomo.travaglini@arm.com#endif 14713481Sgiacomo.travaglini@arm.com} 14813481Sgiacomo.travaglini@arm.com 14913481Sgiacomo.travaglini@arm.com} // namespace internal 15013481Sgiacomo.travaglini@arm.com 15113481Sgiacomo.travaglini@arm.com// ExitedWithCode constructor. 15213481Sgiacomo.travaglini@arm.comExitedWithCode::ExitedWithCode(int exit_code) : exit_code_(exit_code) { 15313481Sgiacomo.travaglini@arm.com} 15413481Sgiacomo.travaglini@arm.com 15513481Sgiacomo.travaglini@arm.com// ExitedWithCode function-call operator. 15613481Sgiacomo.travaglini@arm.combool ExitedWithCode::operator()(int exit_status) const { 15713481Sgiacomo.travaglini@arm.com# if GTEST_OS_WINDOWS 15813481Sgiacomo.travaglini@arm.com 15913481Sgiacomo.travaglini@arm.com return exit_status == exit_code_; 16013481Sgiacomo.travaglini@arm.com 16113481Sgiacomo.travaglini@arm.com# else 16213481Sgiacomo.travaglini@arm.com 16313481Sgiacomo.travaglini@arm.com return WIFEXITED(exit_status) && WEXITSTATUS(exit_status) == exit_code_; 16413481Sgiacomo.travaglini@arm.com 16513481Sgiacomo.travaglini@arm.com# endif // GTEST_OS_WINDOWS 16613481Sgiacomo.travaglini@arm.com} 16713481Sgiacomo.travaglini@arm.com 16813481Sgiacomo.travaglini@arm.com# if !GTEST_OS_WINDOWS 16913481Sgiacomo.travaglini@arm.com// KilledBySignal constructor. 17013481Sgiacomo.travaglini@arm.comKilledBySignal::KilledBySignal(int signum) : signum_(signum) { 17113481Sgiacomo.travaglini@arm.com} 17213481Sgiacomo.travaglini@arm.com 17313481Sgiacomo.travaglini@arm.com// KilledBySignal function-call operator. 17413481Sgiacomo.travaglini@arm.combool KilledBySignal::operator()(int exit_status) const { 17513481Sgiacomo.travaglini@arm.com# if defined(GTEST_KILLED_BY_SIGNAL_OVERRIDE_) 17613481Sgiacomo.travaglini@arm.com { 17713481Sgiacomo.travaglini@arm.com bool result; 17813481Sgiacomo.travaglini@arm.com if (GTEST_KILLED_BY_SIGNAL_OVERRIDE_(signum_, exit_status, &result)) { 17913481Sgiacomo.travaglini@arm.com return result; 18013481Sgiacomo.travaglini@arm.com } 18113481Sgiacomo.travaglini@arm.com } 18213481Sgiacomo.travaglini@arm.com# endif // defined(GTEST_KILLED_BY_SIGNAL_OVERRIDE_) 18313481Sgiacomo.travaglini@arm.com return WIFSIGNALED(exit_status) && WTERMSIG(exit_status) == signum_; 18413481Sgiacomo.travaglini@arm.com} 18513481Sgiacomo.travaglini@arm.com# endif // !GTEST_OS_WINDOWS 18613481Sgiacomo.travaglini@arm.com 18713481Sgiacomo.travaglini@arm.comnamespace internal { 18813481Sgiacomo.travaglini@arm.com 18913481Sgiacomo.travaglini@arm.com// Utilities needed for death tests. 19013481Sgiacomo.travaglini@arm.com 19113481Sgiacomo.travaglini@arm.com// Generates a textual description of a given exit code, in the format 19213481Sgiacomo.travaglini@arm.com// specified by wait(2). 19313481Sgiacomo.travaglini@arm.comstatic std::string ExitSummary(int exit_code) { 19413481Sgiacomo.travaglini@arm.com Message m; 19513481Sgiacomo.travaglini@arm.com 19613481Sgiacomo.travaglini@arm.com# if GTEST_OS_WINDOWS 19713481Sgiacomo.travaglini@arm.com 19813481Sgiacomo.travaglini@arm.com m << "Exited with exit status " << exit_code; 19913481Sgiacomo.travaglini@arm.com 20013481Sgiacomo.travaglini@arm.com# else 20113481Sgiacomo.travaglini@arm.com 20213481Sgiacomo.travaglini@arm.com if (WIFEXITED(exit_code)) { 20313481Sgiacomo.travaglini@arm.com m << "Exited with exit status " << WEXITSTATUS(exit_code); 20413481Sgiacomo.travaglini@arm.com } else if (WIFSIGNALED(exit_code)) { 20513481Sgiacomo.travaglini@arm.com m << "Terminated by signal " << WTERMSIG(exit_code); 20613481Sgiacomo.travaglini@arm.com } 20713481Sgiacomo.travaglini@arm.com# ifdef WCOREDUMP 20813481Sgiacomo.travaglini@arm.com if (WCOREDUMP(exit_code)) { 20913481Sgiacomo.travaglini@arm.com m << " (core dumped)"; 21013481Sgiacomo.travaglini@arm.com } 21113481Sgiacomo.travaglini@arm.com# endif 21213481Sgiacomo.travaglini@arm.com# endif // GTEST_OS_WINDOWS 21313481Sgiacomo.travaglini@arm.com 21413481Sgiacomo.travaglini@arm.com return m.GetString(); 21513481Sgiacomo.travaglini@arm.com} 21613481Sgiacomo.travaglini@arm.com 21713481Sgiacomo.travaglini@arm.com// Returns true if exit_status describes a process that was terminated 21813481Sgiacomo.travaglini@arm.com// by a signal, or exited normally with a nonzero exit code. 21913481Sgiacomo.travaglini@arm.combool ExitedUnsuccessfully(int exit_status) { 22013481Sgiacomo.travaglini@arm.com return !ExitedWithCode(0)(exit_status); 22113481Sgiacomo.travaglini@arm.com} 22213481Sgiacomo.travaglini@arm.com 22313481Sgiacomo.travaglini@arm.com# if !GTEST_OS_WINDOWS 22413481Sgiacomo.travaglini@arm.com// Generates a textual failure message when a death test finds more than 22513481Sgiacomo.travaglini@arm.com// one thread running, or cannot determine the number of threads, prior 22613481Sgiacomo.travaglini@arm.com// to executing the given statement. It is the responsibility of the 22713481Sgiacomo.travaglini@arm.com// caller not to pass a thread_count of 1. 22813481Sgiacomo.travaglini@arm.comstatic std::string DeathTestThreadWarning(size_t thread_count) { 22913481Sgiacomo.travaglini@arm.com Message msg; 23013481Sgiacomo.travaglini@arm.com msg << "Death tests use fork(), which is unsafe particularly" 23113481Sgiacomo.travaglini@arm.com << " in a threaded context. For this test, " << GTEST_NAME_ << " "; 23213481Sgiacomo.travaglini@arm.com if (thread_count == 0) 23313481Sgiacomo.travaglini@arm.com msg << "couldn't detect the number of threads."; 23413481Sgiacomo.travaglini@arm.com else 23513481Sgiacomo.travaglini@arm.com msg << "detected " << thread_count << " threads."; 23613481Sgiacomo.travaglini@arm.com return msg.GetString(); 23713481Sgiacomo.travaglini@arm.com} 23813481Sgiacomo.travaglini@arm.com# endif // !GTEST_OS_WINDOWS 23913481Sgiacomo.travaglini@arm.com 24013481Sgiacomo.travaglini@arm.com// Flag characters for reporting a death test that did not die. 24113481Sgiacomo.travaglini@arm.comstatic const char kDeathTestLived = 'L'; 24213481Sgiacomo.travaglini@arm.comstatic const char kDeathTestReturned = 'R'; 24313481Sgiacomo.travaglini@arm.comstatic const char kDeathTestThrew = 'T'; 24413481Sgiacomo.travaglini@arm.comstatic const char kDeathTestInternalError = 'I'; 24513481Sgiacomo.travaglini@arm.com 24613481Sgiacomo.travaglini@arm.com// An enumeration describing all of the possible ways that a death test can 24713481Sgiacomo.travaglini@arm.com// conclude. DIED means that the process died while executing the test 24813481Sgiacomo.travaglini@arm.com// code; LIVED means that process lived beyond the end of the test code; 24913481Sgiacomo.travaglini@arm.com// RETURNED means that the test statement attempted to execute a return 25013481Sgiacomo.travaglini@arm.com// statement, which is not allowed; THREW means that the test statement 25113481Sgiacomo.travaglini@arm.com// returned control by throwing an exception. IN_PROGRESS means the test 25213481Sgiacomo.travaglini@arm.com// has not yet concluded. 25313481Sgiacomo.travaglini@arm.com// TODO(vladl@google.com): Unify names and possibly values for 25413481Sgiacomo.travaglini@arm.com// AbortReason, DeathTestOutcome, and flag characters above. 25513481Sgiacomo.travaglini@arm.comenum DeathTestOutcome { IN_PROGRESS, DIED, LIVED, RETURNED, THREW }; 25613481Sgiacomo.travaglini@arm.com 25713481Sgiacomo.travaglini@arm.com// Routine for aborting the program which is safe to call from an 25813481Sgiacomo.travaglini@arm.com// exec-style death test child process, in which case the error 25913481Sgiacomo.travaglini@arm.com// message is propagated back to the parent process. Otherwise, the 26013481Sgiacomo.travaglini@arm.com// message is simply printed to stderr. In either case, the program 26113481Sgiacomo.travaglini@arm.com// then exits with status 1. 26213481Sgiacomo.travaglini@arm.comvoid DeathTestAbort(const std::string& message) { 26313481Sgiacomo.travaglini@arm.com // On a POSIX system, this function may be called from a threadsafe-style 26413481Sgiacomo.travaglini@arm.com // death test child process, which operates on a very small stack. Use 26513481Sgiacomo.travaglini@arm.com // the heap for any additional non-minuscule memory requirements. 26613481Sgiacomo.travaglini@arm.com const InternalRunDeathTestFlag* const flag = 26713481Sgiacomo.travaglini@arm.com GetUnitTestImpl()->internal_run_death_test_flag(); 26813481Sgiacomo.travaglini@arm.com if (flag != NULL) { 26913481Sgiacomo.travaglini@arm.com FILE* parent = posix::FDOpen(flag->write_fd(), "w"); 27013481Sgiacomo.travaglini@arm.com fputc(kDeathTestInternalError, parent); 27113481Sgiacomo.travaglini@arm.com fprintf(parent, "%s", message.c_str()); 27213481Sgiacomo.travaglini@arm.com fflush(parent); 27313481Sgiacomo.travaglini@arm.com _exit(1); 27413481Sgiacomo.travaglini@arm.com } else { 27513481Sgiacomo.travaglini@arm.com fprintf(stderr, "%s", message.c_str()); 27613481Sgiacomo.travaglini@arm.com fflush(stderr); 27713481Sgiacomo.travaglini@arm.com posix::Abort(); 27813481Sgiacomo.travaglini@arm.com } 27913481Sgiacomo.travaglini@arm.com} 28013481Sgiacomo.travaglini@arm.com 28113481Sgiacomo.travaglini@arm.com// A replacement for CHECK that calls DeathTestAbort if the assertion 28213481Sgiacomo.travaglini@arm.com// fails. 28313481Sgiacomo.travaglini@arm.com# define GTEST_DEATH_TEST_CHECK_(expression) \ 28413481Sgiacomo.travaglini@arm.com do { \ 28513481Sgiacomo.travaglini@arm.com if (!::testing::internal::IsTrue(expression)) { \ 28613481Sgiacomo.travaglini@arm.com DeathTestAbort( \ 28713481Sgiacomo.travaglini@arm.com ::std::string("CHECK failed: File ") + __FILE__ + ", line " \ 28813481Sgiacomo.travaglini@arm.com + ::testing::internal::StreamableToString(__LINE__) + ": " \ 28913481Sgiacomo.travaglini@arm.com + #expression); \ 29013481Sgiacomo.travaglini@arm.com } \ 29113481Sgiacomo.travaglini@arm.com } while (::testing::internal::AlwaysFalse()) 29213481Sgiacomo.travaglini@arm.com 29313481Sgiacomo.travaglini@arm.com// This macro is similar to GTEST_DEATH_TEST_CHECK_, but it is meant for 29413481Sgiacomo.travaglini@arm.com// evaluating any system call that fulfills two conditions: it must return 29513481Sgiacomo.travaglini@arm.com// -1 on failure, and set errno to EINTR when it is interrupted and 29613481Sgiacomo.travaglini@arm.com// should be tried again. The macro expands to a loop that repeatedly 29713481Sgiacomo.travaglini@arm.com// evaluates the expression as long as it evaluates to -1 and sets 29813481Sgiacomo.travaglini@arm.com// errno to EINTR. If the expression evaluates to -1 but errno is 29913481Sgiacomo.travaglini@arm.com// something other than EINTR, DeathTestAbort is called. 30013481Sgiacomo.travaglini@arm.com# define GTEST_DEATH_TEST_CHECK_SYSCALL_(expression) \ 30113481Sgiacomo.travaglini@arm.com do { \ 30213481Sgiacomo.travaglini@arm.com int gtest_retval; \ 30313481Sgiacomo.travaglini@arm.com do { \ 30413481Sgiacomo.travaglini@arm.com gtest_retval = (expression); \ 30513481Sgiacomo.travaglini@arm.com } while (gtest_retval == -1 && errno == EINTR); \ 30613481Sgiacomo.travaglini@arm.com if (gtest_retval == -1) { \ 30713481Sgiacomo.travaglini@arm.com DeathTestAbort( \ 30813481Sgiacomo.travaglini@arm.com ::std::string("CHECK failed: File ") + __FILE__ + ", line " \ 30913481Sgiacomo.travaglini@arm.com + ::testing::internal::StreamableToString(__LINE__) + ": " \ 31013481Sgiacomo.travaglini@arm.com + #expression + " != -1"); \ 31113481Sgiacomo.travaglini@arm.com } \ 31213481Sgiacomo.travaglini@arm.com } while (::testing::internal::AlwaysFalse()) 31313481Sgiacomo.travaglini@arm.com 31413481Sgiacomo.travaglini@arm.com// Returns the message describing the last system error in errno. 31513481Sgiacomo.travaglini@arm.comstd::string GetLastErrnoDescription() { 31613481Sgiacomo.travaglini@arm.com return errno == 0 ? "" : posix::StrError(errno); 31713481Sgiacomo.travaglini@arm.com} 31813481Sgiacomo.travaglini@arm.com 31913481Sgiacomo.travaglini@arm.com// This is called from a death test parent process to read a failure 32013481Sgiacomo.travaglini@arm.com// message from the death test child process and log it with the FATAL 32113481Sgiacomo.travaglini@arm.com// severity. On Windows, the message is read from a pipe handle. On other 32213481Sgiacomo.travaglini@arm.com// platforms, it is read from a file descriptor. 32313481Sgiacomo.travaglini@arm.comstatic void FailFromInternalError(int fd) { 32413481Sgiacomo.travaglini@arm.com Message error; 32513481Sgiacomo.travaglini@arm.com char buffer[256]; 32613481Sgiacomo.travaglini@arm.com int num_read; 32713481Sgiacomo.travaglini@arm.com 32813481Sgiacomo.travaglini@arm.com do { 32913481Sgiacomo.travaglini@arm.com while ((num_read = posix::Read(fd, buffer, 255)) > 0) { 33013481Sgiacomo.travaglini@arm.com buffer[num_read] = '\0'; 33113481Sgiacomo.travaglini@arm.com error << buffer; 33213481Sgiacomo.travaglini@arm.com } 33313481Sgiacomo.travaglini@arm.com } while (num_read == -1 && errno == EINTR); 33413481Sgiacomo.travaglini@arm.com 33513481Sgiacomo.travaglini@arm.com if (num_read == 0) { 33613481Sgiacomo.travaglini@arm.com GTEST_LOG_(FATAL) << error.GetString(); 33713481Sgiacomo.travaglini@arm.com } else { 33813481Sgiacomo.travaglini@arm.com const int last_error = errno; 33913481Sgiacomo.travaglini@arm.com GTEST_LOG_(FATAL) << "Error while reading death test internal: " 34013481Sgiacomo.travaglini@arm.com << GetLastErrnoDescription() << " [" << last_error << "]"; 34113481Sgiacomo.travaglini@arm.com } 34213481Sgiacomo.travaglini@arm.com} 34313481Sgiacomo.travaglini@arm.com 34413481Sgiacomo.travaglini@arm.com// Death test constructor. Increments the running death test count 34513481Sgiacomo.travaglini@arm.com// for the current test. 34613481Sgiacomo.travaglini@arm.comDeathTest::DeathTest() { 34713481Sgiacomo.travaglini@arm.com TestInfo* const info = GetUnitTestImpl()->current_test_info(); 34813481Sgiacomo.travaglini@arm.com if (info == NULL) { 34913481Sgiacomo.travaglini@arm.com DeathTestAbort("Cannot run a death test outside of a TEST or " 35013481Sgiacomo.travaglini@arm.com "TEST_F construct"); 35113481Sgiacomo.travaglini@arm.com } 35213481Sgiacomo.travaglini@arm.com} 35313481Sgiacomo.travaglini@arm.com 35413481Sgiacomo.travaglini@arm.com// Creates and returns a death test by dispatching to the current 35513481Sgiacomo.travaglini@arm.com// death test factory. 35613481Sgiacomo.travaglini@arm.combool DeathTest::Create(const char* statement, const RE* regex, 35713481Sgiacomo.travaglini@arm.com const char* file, int line, DeathTest** test) { 35813481Sgiacomo.travaglini@arm.com return GetUnitTestImpl()->death_test_factory()->Create( 35913481Sgiacomo.travaglini@arm.com statement, regex, file, line, test); 36013481Sgiacomo.travaglini@arm.com} 36113481Sgiacomo.travaglini@arm.com 36213481Sgiacomo.travaglini@arm.comconst char* DeathTest::LastMessage() { 36313481Sgiacomo.travaglini@arm.com return last_death_test_message_.c_str(); 36413481Sgiacomo.travaglini@arm.com} 36513481Sgiacomo.travaglini@arm.com 36613481Sgiacomo.travaglini@arm.comvoid DeathTest::set_last_death_test_message(const std::string& message) { 36713481Sgiacomo.travaglini@arm.com last_death_test_message_ = message; 36813481Sgiacomo.travaglini@arm.com} 36913481Sgiacomo.travaglini@arm.com 37013481Sgiacomo.travaglini@arm.comstd::string DeathTest::last_death_test_message_; 37113481Sgiacomo.travaglini@arm.com 37213481Sgiacomo.travaglini@arm.com// Provides cross platform implementation for some death functionality. 37313481Sgiacomo.travaglini@arm.comclass DeathTestImpl : public DeathTest { 37413481Sgiacomo.travaglini@arm.com protected: 37513481Sgiacomo.travaglini@arm.com DeathTestImpl(const char* a_statement, const RE* a_regex) 37613481Sgiacomo.travaglini@arm.com : statement_(a_statement), 37713481Sgiacomo.travaglini@arm.com regex_(a_regex), 37813481Sgiacomo.travaglini@arm.com spawned_(false), 37913481Sgiacomo.travaglini@arm.com status_(-1), 38013481Sgiacomo.travaglini@arm.com outcome_(IN_PROGRESS), 38113481Sgiacomo.travaglini@arm.com read_fd_(-1), 38213481Sgiacomo.travaglini@arm.com write_fd_(-1) {} 38313481Sgiacomo.travaglini@arm.com 38413481Sgiacomo.travaglini@arm.com // read_fd_ is expected to be closed and cleared by a derived class. 38513481Sgiacomo.travaglini@arm.com ~DeathTestImpl() { GTEST_DEATH_TEST_CHECK_(read_fd_ == -1); } 38613481Sgiacomo.travaglini@arm.com 38713481Sgiacomo.travaglini@arm.com void Abort(AbortReason reason); 38813481Sgiacomo.travaglini@arm.com virtual bool Passed(bool status_ok); 38913481Sgiacomo.travaglini@arm.com 39013481Sgiacomo.travaglini@arm.com const char* statement() const { return statement_; } 39113481Sgiacomo.travaglini@arm.com const RE* regex() const { return regex_; } 39213481Sgiacomo.travaglini@arm.com bool spawned() const { return spawned_; } 39313481Sgiacomo.travaglini@arm.com void set_spawned(bool is_spawned) { spawned_ = is_spawned; } 39413481Sgiacomo.travaglini@arm.com int status() const { return status_; } 39513481Sgiacomo.travaglini@arm.com void set_status(int a_status) { status_ = a_status; } 39613481Sgiacomo.travaglini@arm.com DeathTestOutcome outcome() const { return outcome_; } 39713481Sgiacomo.travaglini@arm.com void set_outcome(DeathTestOutcome an_outcome) { outcome_ = an_outcome; } 39813481Sgiacomo.travaglini@arm.com int read_fd() const { return read_fd_; } 39913481Sgiacomo.travaglini@arm.com void set_read_fd(int fd) { read_fd_ = fd; } 40013481Sgiacomo.travaglini@arm.com int write_fd() const { return write_fd_; } 40113481Sgiacomo.travaglini@arm.com void set_write_fd(int fd) { write_fd_ = fd; } 40213481Sgiacomo.travaglini@arm.com 40313481Sgiacomo.travaglini@arm.com // Called in the parent process only. Reads the result code of the death 40413481Sgiacomo.travaglini@arm.com // test child process via a pipe, interprets it to set the outcome_ 40513481Sgiacomo.travaglini@arm.com // member, and closes read_fd_. Outputs diagnostics and terminates in 40613481Sgiacomo.travaglini@arm.com // case of unexpected codes. 40713481Sgiacomo.travaglini@arm.com void ReadAndInterpretStatusByte(); 40813481Sgiacomo.travaglini@arm.com 40913481Sgiacomo.travaglini@arm.com private: 41013481Sgiacomo.travaglini@arm.com // The textual content of the code this object is testing. This class 41113481Sgiacomo.travaglini@arm.com // doesn't own this string and should not attempt to delete it. 41213481Sgiacomo.travaglini@arm.com const char* const statement_; 41313481Sgiacomo.travaglini@arm.com // The regular expression which test output must match. DeathTestImpl 41413481Sgiacomo.travaglini@arm.com // doesn't own this object and should not attempt to delete it. 41513481Sgiacomo.travaglini@arm.com const RE* const regex_; 41613481Sgiacomo.travaglini@arm.com // True if the death test child process has been successfully spawned. 41713481Sgiacomo.travaglini@arm.com bool spawned_; 41813481Sgiacomo.travaglini@arm.com // The exit status of the child process. 41913481Sgiacomo.travaglini@arm.com int status_; 42013481Sgiacomo.travaglini@arm.com // How the death test concluded. 42113481Sgiacomo.travaglini@arm.com DeathTestOutcome outcome_; 42213481Sgiacomo.travaglini@arm.com // Descriptor to the read end of the pipe to the child process. It is 42313481Sgiacomo.travaglini@arm.com // always -1 in the child process. The child keeps its write end of the 42413481Sgiacomo.travaglini@arm.com // pipe in write_fd_. 42513481Sgiacomo.travaglini@arm.com int read_fd_; 42613481Sgiacomo.travaglini@arm.com // Descriptor to the child's write end of the pipe to the parent process. 42713481Sgiacomo.travaglini@arm.com // It is always -1 in the parent process. The parent keeps its end of the 42813481Sgiacomo.travaglini@arm.com // pipe in read_fd_. 42913481Sgiacomo.travaglini@arm.com int write_fd_; 43013481Sgiacomo.travaglini@arm.com}; 43113481Sgiacomo.travaglini@arm.com 43213481Sgiacomo.travaglini@arm.com// Called in the parent process only. Reads the result code of the death 43313481Sgiacomo.travaglini@arm.com// test child process via a pipe, interprets it to set the outcome_ 43413481Sgiacomo.travaglini@arm.com// member, and closes read_fd_. Outputs diagnostics and terminates in 43513481Sgiacomo.travaglini@arm.com// case of unexpected codes. 43613481Sgiacomo.travaglini@arm.comvoid DeathTestImpl::ReadAndInterpretStatusByte() { 43713481Sgiacomo.travaglini@arm.com char flag; 43813481Sgiacomo.travaglini@arm.com int bytes_read; 43913481Sgiacomo.travaglini@arm.com 44013481Sgiacomo.travaglini@arm.com // The read() here blocks until data is available (signifying the 44113481Sgiacomo.travaglini@arm.com // failure of the death test) or until the pipe is closed (signifying 44213481Sgiacomo.travaglini@arm.com // its success), so it's okay to call this in the parent before 44313481Sgiacomo.travaglini@arm.com // the child process has exited. 44413481Sgiacomo.travaglini@arm.com do { 44513481Sgiacomo.travaglini@arm.com bytes_read = posix::Read(read_fd(), &flag, 1); 44613481Sgiacomo.travaglini@arm.com } while (bytes_read == -1 && errno == EINTR); 44713481Sgiacomo.travaglini@arm.com 44813481Sgiacomo.travaglini@arm.com if (bytes_read == 0) { 44913481Sgiacomo.travaglini@arm.com set_outcome(DIED); 45013481Sgiacomo.travaglini@arm.com } else if (bytes_read == 1) { 45113481Sgiacomo.travaglini@arm.com switch (flag) { 45213481Sgiacomo.travaglini@arm.com case kDeathTestReturned: 45313481Sgiacomo.travaglini@arm.com set_outcome(RETURNED); 45413481Sgiacomo.travaglini@arm.com break; 45513481Sgiacomo.travaglini@arm.com case kDeathTestThrew: 45613481Sgiacomo.travaglini@arm.com set_outcome(THREW); 45713481Sgiacomo.travaglini@arm.com break; 45813481Sgiacomo.travaglini@arm.com case kDeathTestLived: 45913481Sgiacomo.travaglini@arm.com set_outcome(LIVED); 46013481Sgiacomo.travaglini@arm.com break; 46113481Sgiacomo.travaglini@arm.com case kDeathTestInternalError: 46213481Sgiacomo.travaglini@arm.com FailFromInternalError(read_fd()); // Does not return. 46313481Sgiacomo.travaglini@arm.com break; 46413481Sgiacomo.travaglini@arm.com default: 46513481Sgiacomo.travaglini@arm.com GTEST_LOG_(FATAL) << "Death test child process reported " 46613481Sgiacomo.travaglini@arm.com << "unexpected status byte (" 46713481Sgiacomo.travaglini@arm.com << static_cast<unsigned int>(flag) << ")"; 46813481Sgiacomo.travaglini@arm.com } 46913481Sgiacomo.travaglini@arm.com } else { 47013481Sgiacomo.travaglini@arm.com GTEST_LOG_(FATAL) << "Read from death test child process failed: " 47113481Sgiacomo.travaglini@arm.com << GetLastErrnoDescription(); 47213481Sgiacomo.travaglini@arm.com } 47313481Sgiacomo.travaglini@arm.com GTEST_DEATH_TEST_CHECK_SYSCALL_(posix::Close(read_fd())); 47413481Sgiacomo.travaglini@arm.com set_read_fd(-1); 47513481Sgiacomo.travaglini@arm.com} 47613481Sgiacomo.travaglini@arm.com 47713481Sgiacomo.travaglini@arm.com// Signals that the death test code which should have exited, didn't. 47813481Sgiacomo.travaglini@arm.com// Should be called only in a death test child process. 47913481Sgiacomo.travaglini@arm.com// Writes a status byte to the child's status file descriptor, then 48013481Sgiacomo.travaglini@arm.com// calls _exit(1). 48113481Sgiacomo.travaglini@arm.comvoid DeathTestImpl::Abort(AbortReason reason) { 48213481Sgiacomo.travaglini@arm.com // The parent process considers the death test to be a failure if 48313481Sgiacomo.travaglini@arm.com // it finds any data in our pipe. So, here we write a single flag byte 48413481Sgiacomo.travaglini@arm.com // to the pipe, then exit. 48513481Sgiacomo.travaglini@arm.com const char status_ch = 48613481Sgiacomo.travaglini@arm.com reason == TEST_DID_NOT_DIE ? kDeathTestLived : 48713481Sgiacomo.travaglini@arm.com reason == TEST_THREW_EXCEPTION ? kDeathTestThrew : kDeathTestReturned; 48813481Sgiacomo.travaglini@arm.com 48913481Sgiacomo.travaglini@arm.com GTEST_DEATH_TEST_CHECK_SYSCALL_(posix::Write(write_fd(), &status_ch, 1)); 49013481Sgiacomo.travaglini@arm.com // We are leaking the descriptor here because on some platforms (i.e., 49113481Sgiacomo.travaglini@arm.com // when built as Windows DLL), destructors of global objects will still 49213481Sgiacomo.travaglini@arm.com // run after calling _exit(). On such systems, write_fd_ will be 49313481Sgiacomo.travaglini@arm.com // indirectly closed from the destructor of UnitTestImpl, causing double 49413481Sgiacomo.travaglini@arm.com // close if it is also closed here. On debug configurations, double close 49513481Sgiacomo.travaglini@arm.com // may assert. As there are no in-process buffers to flush here, we are 49613481Sgiacomo.travaglini@arm.com // relying on the OS to close the descriptor after the process terminates 49713481Sgiacomo.travaglini@arm.com // when the destructors are not run. 49813481Sgiacomo.travaglini@arm.com _exit(1); // Exits w/o any normal exit hooks (we were supposed to crash) 49913481Sgiacomo.travaglini@arm.com} 50013481Sgiacomo.travaglini@arm.com 50113481Sgiacomo.travaglini@arm.com// Returns an indented copy of stderr output for a death test. 50213481Sgiacomo.travaglini@arm.com// This makes distinguishing death test output lines from regular log lines 50313481Sgiacomo.travaglini@arm.com// much easier. 50413481Sgiacomo.travaglini@arm.comstatic ::std::string FormatDeathTestOutput(const ::std::string& output) { 50513481Sgiacomo.travaglini@arm.com ::std::string ret; 50613481Sgiacomo.travaglini@arm.com for (size_t at = 0; ; ) { 50713481Sgiacomo.travaglini@arm.com const size_t line_end = output.find('\n', at); 50813481Sgiacomo.travaglini@arm.com ret += "[ DEATH ] "; 50913481Sgiacomo.travaglini@arm.com if (line_end == ::std::string::npos) { 51013481Sgiacomo.travaglini@arm.com ret += output.substr(at); 51113481Sgiacomo.travaglini@arm.com break; 51213481Sgiacomo.travaglini@arm.com } 51313481Sgiacomo.travaglini@arm.com ret += output.substr(at, line_end + 1 - at); 51413481Sgiacomo.travaglini@arm.com at = line_end + 1; 51513481Sgiacomo.travaglini@arm.com } 51613481Sgiacomo.travaglini@arm.com return ret; 51713481Sgiacomo.travaglini@arm.com} 51813481Sgiacomo.travaglini@arm.com 51913481Sgiacomo.travaglini@arm.com// Assesses the success or failure of a death test, using both private 52013481Sgiacomo.travaglini@arm.com// members which have previously been set, and one argument: 52113481Sgiacomo.travaglini@arm.com// 52213481Sgiacomo.travaglini@arm.com// Private data members: 52313481Sgiacomo.travaglini@arm.com// outcome: An enumeration describing how the death test 52413481Sgiacomo.travaglini@arm.com// concluded: DIED, LIVED, THREW, or RETURNED. The death test 52513481Sgiacomo.travaglini@arm.com// fails in the latter three cases. 52613481Sgiacomo.travaglini@arm.com// status: The exit status of the child process. On *nix, it is in the 52713481Sgiacomo.travaglini@arm.com// in the format specified by wait(2). On Windows, this is the 52813481Sgiacomo.travaglini@arm.com// value supplied to the ExitProcess() API or a numeric code 52913481Sgiacomo.travaglini@arm.com// of the exception that terminated the program. 53013481Sgiacomo.travaglini@arm.com// regex: A regular expression object to be applied to 53113481Sgiacomo.travaglini@arm.com// the test's captured standard error output; the death test 53213481Sgiacomo.travaglini@arm.com// fails if it does not match. 53313481Sgiacomo.travaglini@arm.com// 53413481Sgiacomo.travaglini@arm.com// Argument: 53513481Sgiacomo.travaglini@arm.com// status_ok: true if exit_status is acceptable in the context of 53613481Sgiacomo.travaglini@arm.com// this particular death test, which fails if it is false 53713481Sgiacomo.travaglini@arm.com// 53813481Sgiacomo.travaglini@arm.com// Returns true iff all of the above conditions are met. Otherwise, the 53913481Sgiacomo.travaglini@arm.com// first failing condition, in the order given above, is the one that is 54013481Sgiacomo.travaglini@arm.com// reported. Also sets the last death test message string. 54113481Sgiacomo.travaglini@arm.combool DeathTestImpl::Passed(bool status_ok) { 54213481Sgiacomo.travaglini@arm.com if (!spawned()) 54313481Sgiacomo.travaglini@arm.com return false; 54413481Sgiacomo.travaglini@arm.com 54513481Sgiacomo.travaglini@arm.com const std::string error_message = GetCapturedStderr(); 54613481Sgiacomo.travaglini@arm.com 54713481Sgiacomo.travaglini@arm.com bool success = false; 54813481Sgiacomo.travaglini@arm.com Message buffer; 54913481Sgiacomo.travaglini@arm.com 55013481Sgiacomo.travaglini@arm.com buffer << "Death test: " << statement() << "\n"; 55113481Sgiacomo.travaglini@arm.com switch (outcome()) { 55213481Sgiacomo.travaglini@arm.com case LIVED: 55313481Sgiacomo.travaglini@arm.com buffer << " Result: failed to die.\n" 55413481Sgiacomo.travaglini@arm.com << " Error msg:\n" << FormatDeathTestOutput(error_message); 55513481Sgiacomo.travaglini@arm.com break; 55613481Sgiacomo.travaglini@arm.com case THREW: 55713481Sgiacomo.travaglini@arm.com buffer << " Result: threw an exception.\n" 55813481Sgiacomo.travaglini@arm.com << " Error msg:\n" << FormatDeathTestOutput(error_message); 55913481Sgiacomo.travaglini@arm.com break; 56013481Sgiacomo.travaglini@arm.com case RETURNED: 56113481Sgiacomo.travaglini@arm.com buffer << " Result: illegal return in test statement.\n" 56213481Sgiacomo.travaglini@arm.com << " Error msg:\n" << FormatDeathTestOutput(error_message); 56313481Sgiacomo.travaglini@arm.com break; 56413481Sgiacomo.travaglini@arm.com case DIED: 56513481Sgiacomo.travaglini@arm.com if (status_ok) { 56613481Sgiacomo.travaglini@arm.com const bool matched = RE::PartialMatch(error_message.c_str(), *regex()); 56713481Sgiacomo.travaglini@arm.com if (matched) { 56813481Sgiacomo.travaglini@arm.com success = true; 56913481Sgiacomo.travaglini@arm.com } else { 57013481Sgiacomo.travaglini@arm.com buffer << " Result: died but not with expected error.\n" 57113481Sgiacomo.travaglini@arm.com << " Expected: " << regex()->pattern() << "\n" 57213481Sgiacomo.travaglini@arm.com << "Actual msg:\n" << FormatDeathTestOutput(error_message); 57313481Sgiacomo.travaglini@arm.com } 57413481Sgiacomo.travaglini@arm.com } else { 57513481Sgiacomo.travaglini@arm.com buffer << " Result: died but not with expected exit code:\n" 57613481Sgiacomo.travaglini@arm.com << " " << ExitSummary(status()) << "\n" 57713481Sgiacomo.travaglini@arm.com << "Actual msg:\n" << FormatDeathTestOutput(error_message); 57813481Sgiacomo.travaglini@arm.com } 57913481Sgiacomo.travaglini@arm.com break; 58013481Sgiacomo.travaglini@arm.com case IN_PROGRESS: 58113481Sgiacomo.travaglini@arm.com default: 58213481Sgiacomo.travaglini@arm.com GTEST_LOG_(FATAL) 58313481Sgiacomo.travaglini@arm.com << "DeathTest::Passed somehow called before conclusion of test"; 58413481Sgiacomo.travaglini@arm.com } 58513481Sgiacomo.travaglini@arm.com 58613481Sgiacomo.travaglini@arm.com DeathTest::set_last_death_test_message(buffer.GetString()); 58713481Sgiacomo.travaglini@arm.com return success; 58813481Sgiacomo.travaglini@arm.com} 58913481Sgiacomo.travaglini@arm.com 59013481Sgiacomo.travaglini@arm.com# if GTEST_OS_WINDOWS 59113481Sgiacomo.travaglini@arm.com// WindowsDeathTest implements death tests on Windows. Due to the 59213481Sgiacomo.travaglini@arm.com// specifics of starting new processes on Windows, death tests there are 59313481Sgiacomo.travaglini@arm.com// always threadsafe, and Google Test considers the 59413481Sgiacomo.travaglini@arm.com// --gtest_death_test_style=fast setting to be equivalent to 59513481Sgiacomo.travaglini@arm.com// --gtest_death_test_style=threadsafe there. 59613481Sgiacomo.travaglini@arm.com// 59713481Sgiacomo.travaglini@arm.com// A few implementation notes: Like the Linux version, the Windows 59813481Sgiacomo.travaglini@arm.com// implementation uses pipes for child-to-parent communication. But due to 59913481Sgiacomo.travaglini@arm.com// the specifics of pipes on Windows, some extra steps are required: 60013481Sgiacomo.travaglini@arm.com// 60113481Sgiacomo.travaglini@arm.com// 1. The parent creates a communication pipe and stores handles to both 60213481Sgiacomo.travaglini@arm.com// ends of it. 60313481Sgiacomo.travaglini@arm.com// 2. The parent starts the child and provides it with the information 60413481Sgiacomo.travaglini@arm.com// necessary to acquire the handle to the write end of the pipe. 60513481Sgiacomo.travaglini@arm.com// 3. The child acquires the write end of the pipe and signals the parent 60613481Sgiacomo.travaglini@arm.com// using a Windows event. 60713481Sgiacomo.travaglini@arm.com// 4. Now the parent can release the write end of the pipe on its side. If 60813481Sgiacomo.travaglini@arm.com// this is done before step 3, the object's reference count goes down to 60913481Sgiacomo.travaglini@arm.com// 0 and it is destroyed, preventing the child from acquiring it. The 61013481Sgiacomo.travaglini@arm.com// parent now has to release it, or read operations on the read end of 61113481Sgiacomo.travaglini@arm.com// the pipe will not return when the child terminates. 61213481Sgiacomo.travaglini@arm.com// 5. The parent reads child's output through the pipe (outcome code and 61313481Sgiacomo.travaglini@arm.com// any possible error messages) from the pipe, and its stderr and then 61413481Sgiacomo.travaglini@arm.com// determines whether to fail the test. 61513481Sgiacomo.travaglini@arm.com// 61613481Sgiacomo.travaglini@arm.com// Note: to distinguish Win32 API calls from the local method and function 61713481Sgiacomo.travaglini@arm.com// calls, the former are explicitly resolved in the global namespace. 61813481Sgiacomo.travaglini@arm.com// 61913481Sgiacomo.travaglini@arm.comclass WindowsDeathTest : public DeathTestImpl { 62013481Sgiacomo.travaglini@arm.com public: 62113481Sgiacomo.travaglini@arm.com WindowsDeathTest(const char* a_statement, 62213481Sgiacomo.travaglini@arm.com const RE* a_regex, 62313481Sgiacomo.travaglini@arm.com const char* file, 62413481Sgiacomo.travaglini@arm.com int line) 62513481Sgiacomo.travaglini@arm.com : DeathTestImpl(a_statement, a_regex), file_(file), line_(line) {} 62613481Sgiacomo.travaglini@arm.com 62713481Sgiacomo.travaglini@arm.com // All of these virtual functions are inherited from DeathTest. 62813481Sgiacomo.travaglini@arm.com virtual int Wait(); 62913481Sgiacomo.travaglini@arm.com virtual TestRole AssumeRole(); 63013481Sgiacomo.travaglini@arm.com 63113481Sgiacomo.travaglini@arm.com private: 63213481Sgiacomo.travaglini@arm.com // The name of the file in which the death test is located. 63313481Sgiacomo.travaglini@arm.com const char* const file_; 63413481Sgiacomo.travaglini@arm.com // The line number on which the death test is located. 63513481Sgiacomo.travaglini@arm.com const int line_; 63613481Sgiacomo.travaglini@arm.com // Handle to the write end of the pipe to the child process. 63713481Sgiacomo.travaglini@arm.com AutoHandle write_handle_; 63813481Sgiacomo.travaglini@arm.com // Child process handle. 63913481Sgiacomo.travaglini@arm.com AutoHandle child_handle_; 64013481Sgiacomo.travaglini@arm.com // Event the child process uses to signal the parent that it has 64113481Sgiacomo.travaglini@arm.com // acquired the handle to the write end of the pipe. After seeing this 64213481Sgiacomo.travaglini@arm.com // event the parent can release its own handles to make sure its 64313481Sgiacomo.travaglini@arm.com // ReadFile() calls return when the child terminates. 64413481Sgiacomo.travaglini@arm.com AutoHandle event_handle_; 64513481Sgiacomo.travaglini@arm.com}; 64613481Sgiacomo.travaglini@arm.com 64713481Sgiacomo.travaglini@arm.com// Waits for the child in a death test to exit, returning its exit 64813481Sgiacomo.travaglini@arm.com// status, or 0 if no child process exists. As a side effect, sets the 64913481Sgiacomo.travaglini@arm.com// outcome data member. 65013481Sgiacomo.travaglini@arm.comint WindowsDeathTest::Wait() { 65113481Sgiacomo.travaglini@arm.com if (!spawned()) 65213481Sgiacomo.travaglini@arm.com return 0; 65313481Sgiacomo.travaglini@arm.com 65413481Sgiacomo.travaglini@arm.com // Wait until the child either signals that it has acquired the write end 65513481Sgiacomo.travaglini@arm.com // of the pipe or it dies. 65613481Sgiacomo.travaglini@arm.com const HANDLE wait_handles[2] = { child_handle_.Get(), event_handle_.Get() }; 65713481Sgiacomo.travaglini@arm.com switch (::WaitForMultipleObjects(2, 65813481Sgiacomo.travaglini@arm.com wait_handles, 65913481Sgiacomo.travaglini@arm.com FALSE, // Waits for any of the handles. 66013481Sgiacomo.travaglini@arm.com INFINITE)) { 66113481Sgiacomo.travaglini@arm.com case WAIT_OBJECT_0: 66213481Sgiacomo.travaglini@arm.com case WAIT_OBJECT_0 + 1: 66313481Sgiacomo.travaglini@arm.com break; 66413481Sgiacomo.travaglini@arm.com default: 66513481Sgiacomo.travaglini@arm.com GTEST_DEATH_TEST_CHECK_(false); // Should not get here. 66613481Sgiacomo.travaglini@arm.com } 66713481Sgiacomo.travaglini@arm.com 66813481Sgiacomo.travaglini@arm.com // The child has acquired the write end of the pipe or exited. 66913481Sgiacomo.travaglini@arm.com // We release the handle on our side and continue. 67013481Sgiacomo.travaglini@arm.com write_handle_.Reset(); 67113481Sgiacomo.travaglini@arm.com event_handle_.Reset(); 67213481Sgiacomo.travaglini@arm.com 67313481Sgiacomo.travaglini@arm.com ReadAndInterpretStatusByte(); 67413481Sgiacomo.travaglini@arm.com 67513481Sgiacomo.travaglini@arm.com // Waits for the child process to exit if it haven't already. This 67613481Sgiacomo.travaglini@arm.com // returns immediately if the child has already exited, regardless of 67713481Sgiacomo.travaglini@arm.com // whether previous calls to WaitForMultipleObjects synchronized on this 67813481Sgiacomo.travaglini@arm.com // handle or not. 67913481Sgiacomo.travaglini@arm.com GTEST_DEATH_TEST_CHECK_( 68013481Sgiacomo.travaglini@arm.com WAIT_OBJECT_0 == ::WaitForSingleObject(child_handle_.Get(), 68113481Sgiacomo.travaglini@arm.com INFINITE)); 68213481Sgiacomo.travaglini@arm.com DWORD status_code; 68313481Sgiacomo.travaglini@arm.com GTEST_DEATH_TEST_CHECK_( 68413481Sgiacomo.travaglini@arm.com ::GetExitCodeProcess(child_handle_.Get(), &status_code) != FALSE); 68513481Sgiacomo.travaglini@arm.com child_handle_.Reset(); 68613481Sgiacomo.travaglini@arm.com set_status(static_cast<int>(status_code)); 68713481Sgiacomo.travaglini@arm.com return status(); 68813481Sgiacomo.travaglini@arm.com} 68913481Sgiacomo.travaglini@arm.com 69013481Sgiacomo.travaglini@arm.com// The AssumeRole process for a Windows death test. It creates a child 69113481Sgiacomo.travaglini@arm.com// process with the same executable as the current process to run the 69213481Sgiacomo.travaglini@arm.com// death test. The child process is given the --gtest_filter and 69313481Sgiacomo.travaglini@arm.com// --gtest_internal_run_death_test flags such that it knows to run the 69413481Sgiacomo.travaglini@arm.com// current death test only. 69513481Sgiacomo.travaglini@arm.comDeathTest::TestRole WindowsDeathTest::AssumeRole() { 69613481Sgiacomo.travaglini@arm.com const UnitTestImpl* const impl = GetUnitTestImpl(); 69713481Sgiacomo.travaglini@arm.com const InternalRunDeathTestFlag* const flag = 69813481Sgiacomo.travaglini@arm.com impl->internal_run_death_test_flag(); 69913481Sgiacomo.travaglini@arm.com const TestInfo* const info = impl->current_test_info(); 70013481Sgiacomo.travaglini@arm.com const int death_test_index = info->result()->death_test_count(); 70113481Sgiacomo.travaglini@arm.com 70213481Sgiacomo.travaglini@arm.com if (flag != NULL) { 70313481Sgiacomo.travaglini@arm.com // ParseInternalRunDeathTestFlag() has performed all the necessary 70413481Sgiacomo.travaglini@arm.com // processing. 70513481Sgiacomo.travaglini@arm.com set_write_fd(flag->write_fd()); 70613481Sgiacomo.travaglini@arm.com return EXECUTE_TEST; 70713481Sgiacomo.travaglini@arm.com } 70813481Sgiacomo.travaglini@arm.com 70913481Sgiacomo.travaglini@arm.com // WindowsDeathTest uses an anonymous pipe to communicate results of 71013481Sgiacomo.travaglini@arm.com // a death test. 71113481Sgiacomo.travaglini@arm.com SECURITY_ATTRIBUTES handles_are_inheritable = { 71213481Sgiacomo.travaglini@arm.com sizeof(SECURITY_ATTRIBUTES), NULL, TRUE }; 71313481Sgiacomo.travaglini@arm.com HANDLE read_handle, write_handle; 71413481Sgiacomo.travaglini@arm.com GTEST_DEATH_TEST_CHECK_( 71513481Sgiacomo.travaglini@arm.com ::CreatePipe(&read_handle, &write_handle, &handles_are_inheritable, 71613481Sgiacomo.travaglini@arm.com 0) // Default buffer size. 71713481Sgiacomo.travaglini@arm.com != FALSE); 71813481Sgiacomo.travaglini@arm.com set_read_fd(::_open_osfhandle(reinterpret_cast<intptr_t>(read_handle), 71913481Sgiacomo.travaglini@arm.com O_RDONLY)); 72013481Sgiacomo.travaglini@arm.com write_handle_.Reset(write_handle); 72113481Sgiacomo.travaglini@arm.com event_handle_.Reset(::CreateEvent( 72213481Sgiacomo.travaglini@arm.com &handles_are_inheritable, 72313481Sgiacomo.travaglini@arm.com TRUE, // The event will automatically reset to non-signaled state. 72413481Sgiacomo.travaglini@arm.com FALSE, // The initial state is non-signalled. 72513481Sgiacomo.travaglini@arm.com NULL)); // The even is unnamed. 72613481Sgiacomo.travaglini@arm.com GTEST_DEATH_TEST_CHECK_(event_handle_.Get() != NULL); 72713481Sgiacomo.travaglini@arm.com const std::string filter_flag = 72813481Sgiacomo.travaglini@arm.com std::string("--") + GTEST_FLAG_PREFIX_ + kFilterFlag + "=" + 72913481Sgiacomo.travaglini@arm.com info->test_case_name() + "." + info->name(); 73013481Sgiacomo.travaglini@arm.com const std::string internal_flag = 73113481Sgiacomo.travaglini@arm.com std::string("--") + GTEST_FLAG_PREFIX_ + kInternalRunDeathTestFlag + 73213481Sgiacomo.travaglini@arm.com "=" + file_ + "|" + StreamableToString(line_) + "|" + 73313481Sgiacomo.travaglini@arm.com StreamableToString(death_test_index) + "|" + 73413481Sgiacomo.travaglini@arm.com StreamableToString(static_cast<unsigned int>(::GetCurrentProcessId())) + 73513481Sgiacomo.travaglini@arm.com // size_t has the same width as pointers on both 32-bit and 64-bit 73613481Sgiacomo.travaglini@arm.com // Windows platforms. 73713481Sgiacomo.travaglini@arm.com // See http://msdn.microsoft.com/en-us/library/tcxf1dw6.aspx. 73813481Sgiacomo.travaglini@arm.com "|" + StreamableToString(reinterpret_cast<size_t>(write_handle)) + 73913481Sgiacomo.travaglini@arm.com "|" + StreamableToString(reinterpret_cast<size_t>(event_handle_.Get())); 74013481Sgiacomo.travaglini@arm.com 74113481Sgiacomo.travaglini@arm.com char executable_path[_MAX_PATH + 1]; // NOLINT 74213481Sgiacomo.travaglini@arm.com GTEST_DEATH_TEST_CHECK_( 74313481Sgiacomo.travaglini@arm.com _MAX_PATH + 1 != ::GetModuleFileNameA(NULL, 74413481Sgiacomo.travaglini@arm.com executable_path, 74513481Sgiacomo.travaglini@arm.com _MAX_PATH)); 74613481Sgiacomo.travaglini@arm.com 74713481Sgiacomo.travaglini@arm.com std::string command_line = 74813481Sgiacomo.travaglini@arm.com std::string(::GetCommandLineA()) + " " + filter_flag + " \"" + 74913481Sgiacomo.travaglini@arm.com internal_flag + "\""; 75013481Sgiacomo.travaglini@arm.com 75113481Sgiacomo.travaglini@arm.com DeathTest::set_last_death_test_message(""); 75213481Sgiacomo.travaglini@arm.com 75313481Sgiacomo.travaglini@arm.com CaptureStderr(); 75413481Sgiacomo.travaglini@arm.com // Flush the log buffers since the log streams are shared with the child. 75513481Sgiacomo.travaglini@arm.com FlushInfoLog(); 75613481Sgiacomo.travaglini@arm.com 75713481Sgiacomo.travaglini@arm.com // The child process will share the standard handles with the parent. 75813481Sgiacomo.travaglini@arm.com STARTUPINFOA startup_info; 75913481Sgiacomo.travaglini@arm.com memset(&startup_info, 0, sizeof(STARTUPINFO)); 76013481Sgiacomo.travaglini@arm.com startup_info.dwFlags = STARTF_USESTDHANDLES; 76113481Sgiacomo.travaglini@arm.com startup_info.hStdInput = ::GetStdHandle(STD_INPUT_HANDLE); 76213481Sgiacomo.travaglini@arm.com startup_info.hStdOutput = ::GetStdHandle(STD_OUTPUT_HANDLE); 76313481Sgiacomo.travaglini@arm.com startup_info.hStdError = ::GetStdHandle(STD_ERROR_HANDLE); 76413481Sgiacomo.travaglini@arm.com 76513481Sgiacomo.travaglini@arm.com PROCESS_INFORMATION process_info; 76613481Sgiacomo.travaglini@arm.com GTEST_DEATH_TEST_CHECK_(::CreateProcessA( 76713481Sgiacomo.travaglini@arm.com executable_path, 76813481Sgiacomo.travaglini@arm.com const_cast<char*>(command_line.c_str()), 76913481Sgiacomo.travaglini@arm.com NULL, // Retuned process handle is not inheritable. 77013481Sgiacomo.travaglini@arm.com NULL, // Retuned thread handle is not inheritable. 77113481Sgiacomo.travaglini@arm.com TRUE, // Child inherits all inheritable handles (for write_handle_). 77213481Sgiacomo.travaglini@arm.com 0x0, // Default creation flags. 77313481Sgiacomo.travaglini@arm.com NULL, // Inherit the parent's environment. 77413481Sgiacomo.travaglini@arm.com UnitTest::GetInstance()->original_working_dir(), 77513481Sgiacomo.travaglini@arm.com &startup_info, 77613481Sgiacomo.travaglini@arm.com &process_info) != FALSE); 77713481Sgiacomo.travaglini@arm.com child_handle_.Reset(process_info.hProcess); 77813481Sgiacomo.travaglini@arm.com ::CloseHandle(process_info.hThread); 77913481Sgiacomo.travaglini@arm.com set_spawned(true); 78013481Sgiacomo.travaglini@arm.com return OVERSEE_TEST; 78113481Sgiacomo.travaglini@arm.com} 78213481Sgiacomo.travaglini@arm.com# else // We are not on Windows. 78313481Sgiacomo.travaglini@arm.com 78413481Sgiacomo.travaglini@arm.com// ForkingDeathTest provides implementations for most of the abstract 78513481Sgiacomo.travaglini@arm.com// methods of the DeathTest interface. Only the AssumeRole method is 78613481Sgiacomo.travaglini@arm.com// left undefined. 78713481Sgiacomo.travaglini@arm.comclass ForkingDeathTest : public DeathTestImpl { 78813481Sgiacomo.travaglini@arm.com public: 78913481Sgiacomo.travaglini@arm.com ForkingDeathTest(const char* statement, const RE* regex); 79013481Sgiacomo.travaglini@arm.com 79113481Sgiacomo.travaglini@arm.com // All of these virtual functions are inherited from DeathTest. 79213481Sgiacomo.travaglini@arm.com virtual int Wait(); 79313481Sgiacomo.travaglini@arm.com 79413481Sgiacomo.travaglini@arm.com protected: 79513481Sgiacomo.travaglini@arm.com void set_child_pid(pid_t child_pid) { child_pid_ = child_pid; } 79613481Sgiacomo.travaglini@arm.com 79713481Sgiacomo.travaglini@arm.com private: 79813481Sgiacomo.travaglini@arm.com // PID of child process during death test; 0 in the child process itself. 79913481Sgiacomo.travaglini@arm.com pid_t child_pid_; 80013481Sgiacomo.travaglini@arm.com}; 80113481Sgiacomo.travaglini@arm.com 80213481Sgiacomo.travaglini@arm.com// Constructs a ForkingDeathTest. 80313481Sgiacomo.travaglini@arm.comForkingDeathTest::ForkingDeathTest(const char* a_statement, const RE* a_regex) 80413481Sgiacomo.travaglini@arm.com : DeathTestImpl(a_statement, a_regex), 80513481Sgiacomo.travaglini@arm.com child_pid_(-1) {} 80613481Sgiacomo.travaglini@arm.com 80713481Sgiacomo.travaglini@arm.com// Waits for the child in a death test to exit, returning its exit 80813481Sgiacomo.travaglini@arm.com// status, or 0 if no child process exists. As a side effect, sets the 80913481Sgiacomo.travaglini@arm.com// outcome data member. 81013481Sgiacomo.travaglini@arm.comint ForkingDeathTest::Wait() { 81113481Sgiacomo.travaglini@arm.com if (!spawned()) 81213481Sgiacomo.travaglini@arm.com return 0; 81313481Sgiacomo.travaglini@arm.com 81413481Sgiacomo.travaglini@arm.com ReadAndInterpretStatusByte(); 81513481Sgiacomo.travaglini@arm.com 81613481Sgiacomo.travaglini@arm.com int status_value; 81713481Sgiacomo.travaglini@arm.com GTEST_DEATH_TEST_CHECK_SYSCALL_(waitpid(child_pid_, &status_value, 0)); 81813481Sgiacomo.travaglini@arm.com set_status(status_value); 81913481Sgiacomo.travaglini@arm.com return status_value; 82013481Sgiacomo.travaglini@arm.com} 82113481Sgiacomo.travaglini@arm.com 82213481Sgiacomo.travaglini@arm.com// A concrete death test class that forks, then immediately runs the test 82313481Sgiacomo.travaglini@arm.com// in the child process. 82413481Sgiacomo.travaglini@arm.comclass NoExecDeathTest : public ForkingDeathTest { 82513481Sgiacomo.travaglini@arm.com public: 82613481Sgiacomo.travaglini@arm.com NoExecDeathTest(const char* a_statement, const RE* a_regex) : 82713481Sgiacomo.travaglini@arm.com ForkingDeathTest(a_statement, a_regex) { } 82813481Sgiacomo.travaglini@arm.com virtual TestRole AssumeRole(); 82913481Sgiacomo.travaglini@arm.com}; 83013481Sgiacomo.travaglini@arm.com 83113481Sgiacomo.travaglini@arm.com// The AssumeRole process for a fork-and-run death test. It implements a 83213481Sgiacomo.travaglini@arm.com// straightforward fork, with a simple pipe to transmit the status byte. 83313481Sgiacomo.travaglini@arm.comDeathTest::TestRole NoExecDeathTest::AssumeRole() { 83413481Sgiacomo.travaglini@arm.com const size_t thread_count = GetThreadCount(); 83513481Sgiacomo.travaglini@arm.com if (thread_count != 1) { 83613481Sgiacomo.travaglini@arm.com GTEST_LOG_(WARNING) << DeathTestThreadWarning(thread_count); 83713481Sgiacomo.travaglini@arm.com } 83813481Sgiacomo.travaglini@arm.com 83913481Sgiacomo.travaglini@arm.com int pipe_fd[2]; 84013481Sgiacomo.travaglini@arm.com GTEST_DEATH_TEST_CHECK_(pipe(pipe_fd) != -1); 84113481Sgiacomo.travaglini@arm.com 84213481Sgiacomo.travaglini@arm.com DeathTest::set_last_death_test_message(""); 84313481Sgiacomo.travaglini@arm.com CaptureStderr(); 84413481Sgiacomo.travaglini@arm.com // When we fork the process below, the log file buffers are copied, but the 84513481Sgiacomo.travaglini@arm.com // file descriptors are shared. We flush all log files here so that closing 84613481Sgiacomo.travaglini@arm.com // the file descriptors in the child process doesn't throw off the 84713481Sgiacomo.travaglini@arm.com // synchronization between descriptors and buffers in the parent process. 84813481Sgiacomo.travaglini@arm.com // This is as close to the fork as possible to avoid a race condition in case 84913481Sgiacomo.travaglini@arm.com // there are multiple threads running before the death test, and another 85013481Sgiacomo.travaglini@arm.com // thread writes to the log file. 85113481Sgiacomo.travaglini@arm.com FlushInfoLog(); 85213481Sgiacomo.travaglini@arm.com 85313481Sgiacomo.travaglini@arm.com const pid_t child_pid = fork(); 85413481Sgiacomo.travaglini@arm.com GTEST_DEATH_TEST_CHECK_(child_pid != -1); 85513481Sgiacomo.travaglini@arm.com set_child_pid(child_pid); 85613481Sgiacomo.travaglini@arm.com if (child_pid == 0) { 85713481Sgiacomo.travaglini@arm.com GTEST_DEATH_TEST_CHECK_SYSCALL_(close(pipe_fd[0])); 85813481Sgiacomo.travaglini@arm.com set_write_fd(pipe_fd[1]); 85913481Sgiacomo.travaglini@arm.com // Redirects all logging to stderr in the child process to prevent 86013481Sgiacomo.travaglini@arm.com // concurrent writes to the log files. We capture stderr in the parent 86113481Sgiacomo.travaglini@arm.com // process and append the child process' output to a log. 86213481Sgiacomo.travaglini@arm.com LogToStderr(); 86313481Sgiacomo.travaglini@arm.com // Event forwarding to the listeners of event listener API mush be shut 86413481Sgiacomo.travaglini@arm.com // down in death test subprocesses. 86513481Sgiacomo.travaglini@arm.com GetUnitTestImpl()->listeners()->SuppressEventForwarding(); 86613481Sgiacomo.travaglini@arm.com g_in_fast_death_test_child = true; 86713481Sgiacomo.travaglini@arm.com return EXECUTE_TEST; 86813481Sgiacomo.travaglini@arm.com } else { 86913481Sgiacomo.travaglini@arm.com GTEST_DEATH_TEST_CHECK_SYSCALL_(close(pipe_fd[1])); 87013481Sgiacomo.travaglini@arm.com set_read_fd(pipe_fd[0]); 87113481Sgiacomo.travaglini@arm.com set_spawned(true); 87213481Sgiacomo.travaglini@arm.com return OVERSEE_TEST; 87313481Sgiacomo.travaglini@arm.com } 87413481Sgiacomo.travaglini@arm.com} 87513481Sgiacomo.travaglini@arm.com 87613481Sgiacomo.travaglini@arm.com// A concrete death test class that forks and re-executes the main 87713481Sgiacomo.travaglini@arm.com// program from the beginning, with command-line flags set that cause 87813481Sgiacomo.travaglini@arm.com// only this specific death test to be run. 87913481Sgiacomo.travaglini@arm.comclass ExecDeathTest : public ForkingDeathTest { 88013481Sgiacomo.travaglini@arm.com public: 88113481Sgiacomo.travaglini@arm.com ExecDeathTest(const char* a_statement, const RE* a_regex, 88213481Sgiacomo.travaglini@arm.com const char* file, int line) : 88313481Sgiacomo.travaglini@arm.com ForkingDeathTest(a_statement, a_regex), file_(file), line_(line) { } 88413481Sgiacomo.travaglini@arm.com virtual TestRole AssumeRole(); 88513481Sgiacomo.travaglini@arm.com private: 88613481Sgiacomo.travaglini@arm.com static ::std::vector<testing::internal::string> 88713481Sgiacomo.travaglini@arm.com GetArgvsForDeathTestChildProcess() { 88813481Sgiacomo.travaglini@arm.com ::std::vector<testing::internal::string> args = GetInjectableArgvs(); 88913481Sgiacomo.travaglini@arm.com# if defined(GTEST_EXTRA_DEATH_TEST_COMMAND_LINE_ARGS_) 89013481Sgiacomo.travaglini@arm.com ::std::vector<testing::internal::string> extra_args = 89113481Sgiacomo.travaglini@arm.com GTEST_EXTRA_DEATH_TEST_COMMAND_LINE_ARGS_(); 89213481Sgiacomo.travaglini@arm.com args.insert(args.end(), extra_args.begin(), extra_args.end()); 89313481Sgiacomo.travaglini@arm.com# endif // defined(GTEST_EXTRA_DEATH_TEST_COMMAND_LINE_ARGS_) 89413481Sgiacomo.travaglini@arm.com return args; 89513481Sgiacomo.travaglini@arm.com } 89613481Sgiacomo.travaglini@arm.com // The name of the file in which the death test is located. 89713481Sgiacomo.travaglini@arm.com const char* const file_; 89813481Sgiacomo.travaglini@arm.com // The line number on which the death test is located. 89913481Sgiacomo.travaglini@arm.com const int line_; 90013481Sgiacomo.travaglini@arm.com}; 90113481Sgiacomo.travaglini@arm.com 90213481Sgiacomo.travaglini@arm.com// Utility class for accumulating command-line arguments. 90313481Sgiacomo.travaglini@arm.comclass Arguments { 90413481Sgiacomo.travaglini@arm.com public: 90513481Sgiacomo.travaglini@arm.com Arguments() { 90613481Sgiacomo.travaglini@arm.com args_.push_back(NULL); 90713481Sgiacomo.travaglini@arm.com } 90813481Sgiacomo.travaglini@arm.com 90913481Sgiacomo.travaglini@arm.com ~Arguments() { 91013481Sgiacomo.travaglini@arm.com for (std::vector<char*>::iterator i = args_.begin(); i != args_.end(); 91113481Sgiacomo.travaglini@arm.com ++i) { 91213481Sgiacomo.travaglini@arm.com free(*i); 91313481Sgiacomo.travaglini@arm.com } 91413481Sgiacomo.travaglini@arm.com } 91513481Sgiacomo.travaglini@arm.com void AddArgument(const char* argument) { 91613481Sgiacomo.travaglini@arm.com args_.insert(args_.end() - 1, posix::StrDup(argument)); 91713481Sgiacomo.travaglini@arm.com } 91813481Sgiacomo.travaglini@arm.com 91913481Sgiacomo.travaglini@arm.com template <typename Str> 92013481Sgiacomo.travaglini@arm.com void AddArguments(const ::std::vector<Str>& arguments) { 92113481Sgiacomo.travaglini@arm.com for (typename ::std::vector<Str>::const_iterator i = arguments.begin(); 92213481Sgiacomo.travaglini@arm.com i != arguments.end(); 92313481Sgiacomo.travaglini@arm.com ++i) { 92413481Sgiacomo.travaglini@arm.com args_.insert(args_.end() - 1, posix::StrDup(i->c_str())); 92513481Sgiacomo.travaglini@arm.com } 92613481Sgiacomo.travaglini@arm.com } 92713481Sgiacomo.travaglini@arm.com char* const* Argv() { 92813481Sgiacomo.travaglini@arm.com return &args_[0]; 92913481Sgiacomo.travaglini@arm.com } 93013481Sgiacomo.travaglini@arm.com 93113481Sgiacomo.travaglini@arm.com private: 93213481Sgiacomo.travaglini@arm.com std::vector<char*> args_; 93313481Sgiacomo.travaglini@arm.com}; 93413481Sgiacomo.travaglini@arm.com 93513481Sgiacomo.travaglini@arm.com// A struct that encompasses the arguments to the child process of a 93613481Sgiacomo.travaglini@arm.com// threadsafe-style death test process. 93713481Sgiacomo.travaglini@arm.comstruct ExecDeathTestArgs { 93813481Sgiacomo.travaglini@arm.com char* const* argv; // Command-line arguments for the child's call to exec 93913481Sgiacomo.travaglini@arm.com int close_fd; // File descriptor to close; the read end of a pipe 94013481Sgiacomo.travaglini@arm.com}; 94113481Sgiacomo.travaglini@arm.com 94213481Sgiacomo.travaglini@arm.com# if GTEST_OS_MAC 94313481Sgiacomo.travaglini@arm.cominline char** GetEnviron() { 94413481Sgiacomo.travaglini@arm.com // When Google Test is built as a framework on MacOS X, the environ variable 94513481Sgiacomo.travaglini@arm.com // is unavailable. Apple's documentation (man environ) recommends using 94613481Sgiacomo.travaglini@arm.com // _NSGetEnviron() instead. 94713481Sgiacomo.travaglini@arm.com return *_NSGetEnviron(); 94813481Sgiacomo.travaglini@arm.com} 94913481Sgiacomo.travaglini@arm.com# else 95013481Sgiacomo.travaglini@arm.com// Some POSIX platforms expect you to declare environ. extern "C" makes 95113481Sgiacomo.travaglini@arm.com// it reside in the global namespace. 95213481Sgiacomo.travaglini@arm.comextern "C" char** environ; 95313481Sgiacomo.travaglini@arm.cominline char** GetEnviron() { return environ; } 95413481Sgiacomo.travaglini@arm.com# endif // GTEST_OS_MAC 95513481Sgiacomo.travaglini@arm.com 95613481Sgiacomo.travaglini@arm.com# if !GTEST_OS_QNX 95713481Sgiacomo.travaglini@arm.com// The main function for a threadsafe-style death test child process. 95813481Sgiacomo.travaglini@arm.com// This function is called in a clone()-ed process and thus must avoid 95913481Sgiacomo.travaglini@arm.com// any potentially unsafe operations like malloc or libc functions. 96013481Sgiacomo.travaglini@arm.comstatic int ExecDeathTestChildMain(void* child_arg) { 96113481Sgiacomo.travaglini@arm.com ExecDeathTestArgs* const args = static_cast<ExecDeathTestArgs*>(child_arg); 96213481Sgiacomo.travaglini@arm.com GTEST_DEATH_TEST_CHECK_SYSCALL_(close(args->close_fd)); 96313481Sgiacomo.travaglini@arm.com 96413481Sgiacomo.travaglini@arm.com // We need to execute the test program in the same environment where 96513481Sgiacomo.travaglini@arm.com // it was originally invoked. Therefore we change to the original 96613481Sgiacomo.travaglini@arm.com // working directory first. 96713481Sgiacomo.travaglini@arm.com const char* const original_dir = 96813481Sgiacomo.travaglini@arm.com UnitTest::GetInstance()->original_working_dir(); 96913481Sgiacomo.travaglini@arm.com // We can safely call chdir() as it's a direct system call. 97013481Sgiacomo.travaglini@arm.com if (chdir(original_dir) != 0) { 97113481Sgiacomo.travaglini@arm.com DeathTestAbort(std::string("chdir(\"") + original_dir + "\") failed: " + 97213481Sgiacomo.travaglini@arm.com GetLastErrnoDescription()); 97313481Sgiacomo.travaglini@arm.com return EXIT_FAILURE; 97413481Sgiacomo.travaglini@arm.com } 97513481Sgiacomo.travaglini@arm.com 97613481Sgiacomo.travaglini@arm.com // We can safely call execve() as it's a direct system call. We 97713481Sgiacomo.travaglini@arm.com // cannot use execvp() as it's a libc function and thus potentially 97813481Sgiacomo.travaglini@arm.com // unsafe. Since execve() doesn't search the PATH, the user must 97913481Sgiacomo.travaglini@arm.com // invoke the test program via a valid path that contains at least 98013481Sgiacomo.travaglini@arm.com // one path separator. 98113481Sgiacomo.travaglini@arm.com execve(args->argv[0], args->argv, GetEnviron()); 98213481Sgiacomo.travaglini@arm.com DeathTestAbort(std::string("execve(") + args->argv[0] + ", ...) in " + 98313481Sgiacomo.travaglini@arm.com original_dir + " failed: " + 98413481Sgiacomo.travaglini@arm.com GetLastErrnoDescription()); 98513481Sgiacomo.travaglini@arm.com return EXIT_FAILURE; 98613481Sgiacomo.travaglini@arm.com} 98713481Sgiacomo.travaglini@arm.com# endif // !GTEST_OS_QNX 98813481Sgiacomo.travaglini@arm.com 98913481Sgiacomo.travaglini@arm.com// Two utility routines that together determine the direction the stack 99013481Sgiacomo.travaglini@arm.com// grows. 99113481Sgiacomo.travaglini@arm.com// This could be accomplished more elegantly by a single recursive 99213481Sgiacomo.travaglini@arm.com// function, but we want to guard against the unlikely possibility of 99313481Sgiacomo.travaglini@arm.com// a smart compiler optimizing the recursion away. 99413481Sgiacomo.travaglini@arm.com// 99513481Sgiacomo.travaglini@arm.com// GTEST_NO_INLINE_ is required to prevent GCC 4.6 from inlining 99613481Sgiacomo.travaglini@arm.com// StackLowerThanAddress into StackGrowsDown, which then doesn't give 99713481Sgiacomo.travaglini@arm.com// correct answer. 99813481Sgiacomo.travaglini@arm.comvoid StackLowerThanAddress(const void* ptr, bool* result) GTEST_NO_INLINE_; 99913481Sgiacomo.travaglini@arm.comvoid StackLowerThanAddress(const void* ptr, bool* result) { 100013481Sgiacomo.travaglini@arm.com int dummy; 100113481Sgiacomo.travaglini@arm.com *result = (&dummy < ptr); 100213481Sgiacomo.travaglini@arm.com} 100313481Sgiacomo.travaglini@arm.com 100413481Sgiacomo.travaglini@arm.com// Make sure AddressSanitizer does not tamper with the stack here. 100513481Sgiacomo.travaglini@arm.comGTEST_ATTRIBUTE_NO_SANITIZE_ADDRESS_ 100613481Sgiacomo.travaglini@arm.combool StackGrowsDown() { 100713481Sgiacomo.travaglini@arm.com int dummy; 100813481Sgiacomo.travaglini@arm.com bool result; 100913481Sgiacomo.travaglini@arm.com StackLowerThanAddress(&dummy, &result); 101013481Sgiacomo.travaglini@arm.com return result; 101113481Sgiacomo.travaglini@arm.com} 101213481Sgiacomo.travaglini@arm.com 101313481Sgiacomo.travaglini@arm.com// Spawns a child process with the same executable as the current process in 101413481Sgiacomo.travaglini@arm.com// a thread-safe manner and instructs it to run the death test. The 101513481Sgiacomo.travaglini@arm.com// implementation uses fork(2) + exec. On systems where clone(2) is 101613481Sgiacomo.travaglini@arm.com// available, it is used instead, being slightly more thread-safe. On QNX, 101713481Sgiacomo.travaglini@arm.com// fork supports only single-threaded environments, so this function uses 101813481Sgiacomo.travaglini@arm.com// spawn(2) there instead. The function dies with an error message if 101913481Sgiacomo.travaglini@arm.com// anything goes wrong. 102013481Sgiacomo.travaglini@arm.comstatic pid_t ExecDeathTestSpawnChild(char* const* argv, int close_fd) { 102113481Sgiacomo.travaglini@arm.com ExecDeathTestArgs args = { argv, close_fd }; 102213481Sgiacomo.travaglini@arm.com pid_t child_pid = -1; 102313481Sgiacomo.travaglini@arm.com 102413481Sgiacomo.travaglini@arm.com# if GTEST_OS_QNX 102513481Sgiacomo.travaglini@arm.com // Obtains the current directory and sets it to be closed in the child 102613481Sgiacomo.travaglini@arm.com // process. 102713481Sgiacomo.travaglini@arm.com const int cwd_fd = open(".", O_RDONLY); 102813481Sgiacomo.travaglini@arm.com GTEST_DEATH_TEST_CHECK_(cwd_fd != -1); 102913481Sgiacomo.travaglini@arm.com GTEST_DEATH_TEST_CHECK_SYSCALL_(fcntl(cwd_fd, F_SETFD, FD_CLOEXEC)); 103013481Sgiacomo.travaglini@arm.com // We need to execute the test program in the same environment where 103113481Sgiacomo.travaglini@arm.com // it was originally invoked. Therefore we change to the original 103213481Sgiacomo.travaglini@arm.com // working directory first. 103313481Sgiacomo.travaglini@arm.com const char* const original_dir = 103413481Sgiacomo.travaglini@arm.com UnitTest::GetInstance()->original_working_dir(); 103513481Sgiacomo.travaglini@arm.com // We can safely call chdir() as it's a direct system call. 103613481Sgiacomo.travaglini@arm.com if (chdir(original_dir) != 0) { 103713481Sgiacomo.travaglini@arm.com DeathTestAbort(std::string("chdir(\"") + original_dir + "\") failed: " + 103813481Sgiacomo.travaglini@arm.com GetLastErrnoDescription()); 103913481Sgiacomo.travaglini@arm.com return EXIT_FAILURE; 104013481Sgiacomo.travaglini@arm.com } 104113481Sgiacomo.travaglini@arm.com 104213481Sgiacomo.travaglini@arm.com int fd_flags; 104313481Sgiacomo.travaglini@arm.com // Set close_fd to be closed after spawn. 104413481Sgiacomo.travaglini@arm.com GTEST_DEATH_TEST_CHECK_SYSCALL_(fd_flags = fcntl(close_fd, F_GETFD)); 104513481Sgiacomo.travaglini@arm.com GTEST_DEATH_TEST_CHECK_SYSCALL_(fcntl(close_fd, F_SETFD, 104613481Sgiacomo.travaglini@arm.com fd_flags | FD_CLOEXEC)); 104713481Sgiacomo.travaglini@arm.com struct inheritance inherit = {0}; 104813481Sgiacomo.travaglini@arm.com // spawn is a system call. 104913481Sgiacomo.travaglini@arm.com child_pid = spawn(args.argv[0], 0, NULL, &inherit, args.argv, GetEnviron()); 105013481Sgiacomo.travaglini@arm.com // Restores the current working directory. 105113481Sgiacomo.travaglini@arm.com GTEST_DEATH_TEST_CHECK_(fchdir(cwd_fd) != -1); 105213481Sgiacomo.travaglini@arm.com GTEST_DEATH_TEST_CHECK_SYSCALL_(close(cwd_fd)); 105313481Sgiacomo.travaglini@arm.com 105413481Sgiacomo.travaglini@arm.com# else // GTEST_OS_QNX 105513481Sgiacomo.travaglini@arm.com# if GTEST_OS_LINUX 105613481Sgiacomo.travaglini@arm.com // When a SIGPROF signal is received while fork() or clone() are executing, 105713481Sgiacomo.travaglini@arm.com // the process may hang. To avoid this, we ignore SIGPROF here and re-enable 105813481Sgiacomo.travaglini@arm.com // it after the call to fork()/clone() is complete. 105913481Sgiacomo.travaglini@arm.com struct sigaction saved_sigprof_action; 106013481Sgiacomo.travaglini@arm.com struct sigaction ignore_sigprof_action; 106113481Sgiacomo.travaglini@arm.com memset(&ignore_sigprof_action, 0, sizeof(ignore_sigprof_action)); 106213481Sgiacomo.travaglini@arm.com sigemptyset(&ignore_sigprof_action.sa_mask); 106313481Sgiacomo.travaglini@arm.com ignore_sigprof_action.sa_handler = SIG_IGN; 106413481Sgiacomo.travaglini@arm.com GTEST_DEATH_TEST_CHECK_SYSCALL_(sigaction( 106513481Sgiacomo.travaglini@arm.com SIGPROF, &ignore_sigprof_action, &saved_sigprof_action)); 106613481Sgiacomo.travaglini@arm.com# endif // GTEST_OS_LINUX 106713481Sgiacomo.travaglini@arm.com 106813481Sgiacomo.travaglini@arm.com# if GTEST_HAS_CLONE 106913481Sgiacomo.travaglini@arm.com const bool use_fork = GTEST_FLAG(death_test_use_fork); 107013481Sgiacomo.travaglini@arm.com 107113481Sgiacomo.travaglini@arm.com if (!use_fork) { 107213481Sgiacomo.travaglini@arm.com static const bool stack_grows_down = StackGrowsDown(); 107313481Sgiacomo.travaglini@arm.com const size_t stack_size = getpagesize(); 107413481Sgiacomo.travaglini@arm.com // MMAP_ANONYMOUS is not defined on Mac, so we use MAP_ANON instead. 107513481Sgiacomo.travaglini@arm.com void* const stack = mmap(NULL, stack_size, PROT_READ | PROT_WRITE, 107613481Sgiacomo.travaglini@arm.com MAP_ANON | MAP_PRIVATE, -1, 0); 107713481Sgiacomo.travaglini@arm.com GTEST_DEATH_TEST_CHECK_(stack != MAP_FAILED); 107813481Sgiacomo.travaglini@arm.com 107913481Sgiacomo.travaglini@arm.com // Maximum stack alignment in bytes: For a downward-growing stack, this 108013481Sgiacomo.travaglini@arm.com // amount is subtracted from size of the stack space to get an address 108113481Sgiacomo.travaglini@arm.com // that is within the stack space and is aligned on all systems we care 108213481Sgiacomo.travaglini@arm.com // about. As far as I know there is no ABI with stack alignment greater 108313481Sgiacomo.travaglini@arm.com // than 64. We assume stack and stack_size already have alignment of 108413481Sgiacomo.travaglini@arm.com // kMaxStackAlignment. 108513481Sgiacomo.travaglini@arm.com const size_t kMaxStackAlignment = 64; 108613481Sgiacomo.travaglini@arm.com void* const stack_top = 108713481Sgiacomo.travaglini@arm.com static_cast<char*>(stack) + 108813481Sgiacomo.travaglini@arm.com (stack_grows_down ? stack_size - kMaxStackAlignment : 0); 108913481Sgiacomo.travaglini@arm.com GTEST_DEATH_TEST_CHECK_(stack_size > kMaxStackAlignment && 109013481Sgiacomo.travaglini@arm.com reinterpret_cast<intptr_t>(stack_top) % kMaxStackAlignment == 0); 109113481Sgiacomo.travaglini@arm.com 109213481Sgiacomo.travaglini@arm.com child_pid = clone(&ExecDeathTestChildMain, stack_top, SIGCHLD, &args); 109313481Sgiacomo.travaglini@arm.com 109413481Sgiacomo.travaglini@arm.com GTEST_DEATH_TEST_CHECK_(munmap(stack, stack_size) != -1); 109513481Sgiacomo.travaglini@arm.com } 109613481Sgiacomo.travaglini@arm.com# else 109713481Sgiacomo.travaglini@arm.com const bool use_fork = true; 109813481Sgiacomo.travaglini@arm.com# endif // GTEST_HAS_CLONE 109913481Sgiacomo.travaglini@arm.com 110013481Sgiacomo.travaglini@arm.com if (use_fork && (child_pid = fork()) == 0) { 110113481Sgiacomo.travaglini@arm.com ExecDeathTestChildMain(&args); 110213481Sgiacomo.travaglini@arm.com _exit(0); 110313481Sgiacomo.travaglini@arm.com } 110413481Sgiacomo.travaglini@arm.com# endif // GTEST_OS_QNX 110513481Sgiacomo.travaglini@arm.com# if GTEST_OS_LINUX 110613481Sgiacomo.travaglini@arm.com GTEST_DEATH_TEST_CHECK_SYSCALL_( 110713481Sgiacomo.travaglini@arm.com sigaction(SIGPROF, &saved_sigprof_action, NULL)); 110813481Sgiacomo.travaglini@arm.com# endif // GTEST_OS_LINUX 110913481Sgiacomo.travaglini@arm.com 111013481Sgiacomo.travaglini@arm.com GTEST_DEATH_TEST_CHECK_(child_pid != -1); 111113481Sgiacomo.travaglini@arm.com return child_pid; 111213481Sgiacomo.travaglini@arm.com} 111313481Sgiacomo.travaglini@arm.com 111413481Sgiacomo.travaglini@arm.com// The AssumeRole process for a fork-and-exec death test. It re-executes the 111513481Sgiacomo.travaglini@arm.com// main program from the beginning, setting the --gtest_filter 111613481Sgiacomo.travaglini@arm.com// and --gtest_internal_run_death_test flags to cause only the current 111713481Sgiacomo.travaglini@arm.com// death test to be re-run. 111813481Sgiacomo.travaglini@arm.comDeathTest::TestRole ExecDeathTest::AssumeRole() { 111913481Sgiacomo.travaglini@arm.com const UnitTestImpl* const impl = GetUnitTestImpl(); 112013481Sgiacomo.travaglini@arm.com const InternalRunDeathTestFlag* const flag = 112113481Sgiacomo.travaglini@arm.com impl->internal_run_death_test_flag(); 112213481Sgiacomo.travaglini@arm.com const TestInfo* const info = impl->current_test_info(); 112313481Sgiacomo.travaglini@arm.com const int death_test_index = info->result()->death_test_count(); 112413481Sgiacomo.travaglini@arm.com 112513481Sgiacomo.travaglini@arm.com if (flag != NULL) { 112613481Sgiacomo.travaglini@arm.com set_write_fd(flag->write_fd()); 112713481Sgiacomo.travaglini@arm.com return EXECUTE_TEST; 112813481Sgiacomo.travaglini@arm.com } 112913481Sgiacomo.travaglini@arm.com 113013481Sgiacomo.travaglini@arm.com int pipe_fd[2]; 113113481Sgiacomo.travaglini@arm.com GTEST_DEATH_TEST_CHECK_(pipe(pipe_fd) != -1); 113213481Sgiacomo.travaglini@arm.com // Clear the close-on-exec flag on the write end of the pipe, lest 113313481Sgiacomo.travaglini@arm.com // it be closed when the child process does an exec: 113413481Sgiacomo.travaglini@arm.com GTEST_DEATH_TEST_CHECK_(fcntl(pipe_fd[1], F_SETFD, 0) != -1); 113513481Sgiacomo.travaglini@arm.com 113613481Sgiacomo.travaglini@arm.com const std::string filter_flag = 113713481Sgiacomo.travaglini@arm.com std::string("--") + GTEST_FLAG_PREFIX_ + kFilterFlag + "=" 113813481Sgiacomo.travaglini@arm.com + info->test_case_name() + "." + info->name(); 113913481Sgiacomo.travaglini@arm.com const std::string internal_flag = 114013481Sgiacomo.travaglini@arm.com std::string("--") + GTEST_FLAG_PREFIX_ + kInternalRunDeathTestFlag + "=" 114113481Sgiacomo.travaglini@arm.com + file_ + "|" + StreamableToString(line_) + "|" 114213481Sgiacomo.travaglini@arm.com + StreamableToString(death_test_index) + "|" 114313481Sgiacomo.travaglini@arm.com + StreamableToString(pipe_fd[1]); 114413481Sgiacomo.travaglini@arm.com Arguments args; 114513481Sgiacomo.travaglini@arm.com args.AddArguments(GetArgvsForDeathTestChildProcess()); 114613481Sgiacomo.travaglini@arm.com args.AddArgument(filter_flag.c_str()); 114713481Sgiacomo.travaglini@arm.com args.AddArgument(internal_flag.c_str()); 114813481Sgiacomo.travaglini@arm.com 114913481Sgiacomo.travaglini@arm.com DeathTest::set_last_death_test_message(""); 115013481Sgiacomo.travaglini@arm.com 115113481Sgiacomo.travaglini@arm.com CaptureStderr(); 115213481Sgiacomo.travaglini@arm.com // See the comment in NoExecDeathTest::AssumeRole for why the next line 115313481Sgiacomo.travaglini@arm.com // is necessary. 115413481Sgiacomo.travaglini@arm.com FlushInfoLog(); 115513481Sgiacomo.travaglini@arm.com 115613481Sgiacomo.travaglini@arm.com const pid_t child_pid = ExecDeathTestSpawnChild(args.Argv(), pipe_fd[0]); 115713481Sgiacomo.travaglini@arm.com GTEST_DEATH_TEST_CHECK_SYSCALL_(close(pipe_fd[1])); 115813481Sgiacomo.travaglini@arm.com set_child_pid(child_pid); 115913481Sgiacomo.travaglini@arm.com set_read_fd(pipe_fd[0]); 116013481Sgiacomo.travaglini@arm.com set_spawned(true); 116113481Sgiacomo.travaglini@arm.com return OVERSEE_TEST; 116213481Sgiacomo.travaglini@arm.com} 116313481Sgiacomo.travaglini@arm.com 116413481Sgiacomo.travaglini@arm.com# endif // !GTEST_OS_WINDOWS 116513481Sgiacomo.travaglini@arm.com 116613481Sgiacomo.travaglini@arm.com// Creates a concrete DeathTest-derived class that depends on the 116713481Sgiacomo.travaglini@arm.com// --gtest_death_test_style flag, and sets the pointer pointed to 116813481Sgiacomo.travaglini@arm.com// by the "test" argument to its address. If the test should be 116913481Sgiacomo.travaglini@arm.com// skipped, sets that pointer to NULL. Returns true, unless the 117013481Sgiacomo.travaglini@arm.com// flag is set to an invalid value. 117113481Sgiacomo.travaglini@arm.combool DefaultDeathTestFactory::Create(const char* statement, const RE* regex, 117213481Sgiacomo.travaglini@arm.com const char* file, int line, 117313481Sgiacomo.travaglini@arm.com DeathTest** test) { 117413481Sgiacomo.travaglini@arm.com UnitTestImpl* const impl = GetUnitTestImpl(); 117513481Sgiacomo.travaglini@arm.com const InternalRunDeathTestFlag* const flag = 117613481Sgiacomo.travaglini@arm.com impl->internal_run_death_test_flag(); 117713481Sgiacomo.travaglini@arm.com const int death_test_index = impl->current_test_info() 117813481Sgiacomo.travaglini@arm.com ->increment_death_test_count(); 117913481Sgiacomo.travaglini@arm.com 118013481Sgiacomo.travaglini@arm.com if (flag != NULL) { 118113481Sgiacomo.travaglini@arm.com if (death_test_index > flag->index()) { 118213481Sgiacomo.travaglini@arm.com DeathTest::set_last_death_test_message( 118313481Sgiacomo.travaglini@arm.com "Death test count (" + StreamableToString(death_test_index) 118413481Sgiacomo.travaglini@arm.com + ") somehow exceeded expected maximum (" 118513481Sgiacomo.travaglini@arm.com + StreamableToString(flag->index()) + ")"); 118613481Sgiacomo.travaglini@arm.com return false; 118713481Sgiacomo.travaglini@arm.com } 118813481Sgiacomo.travaglini@arm.com 118913481Sgiacomo.travaglini@arm.com if (!(flag->file() == file && flag->line() == line && 119013481Sgiacomo.travaglini@arm.com flag->index() == death_test_index)) { 119113481Sgiacomo.travaglini@arm.com *test = NULL; 119213481Sgiacomo.travaglini@arm.com return true; 119313481Sgiacomo.travaglini@arm.com } 119413481Sgiacomo.travaglini@arm.com } 119513481Sgiacomo.travaglini@arm.com 119613481Sgiacomo.travaglini@arm.com# if GTEST_OS_WINDOWS 119713481Sgiacomo.travaglini@arm.com 119813481Sgiacomo.travaglini@arm.com if (GTEST_FLAG(death_test_style) == "threadsafe" || 119913481Sgiacomo.travaglini@arm.com GTEST_FLAG(death_test_style) == "fast") { 120013481Sgiacomo.travaglini@arm.com *test = new WindowsDeathTest(statement, regex, file, line); 120113481Sgiacomo.travaglini@arm.com } 120213481Sgiacomo.travaglini@arm.com 120313481Sgiacomo.travaglini@arm.com# else 120413481Sgiacomo.travaglini@arm.com 120513481Sgiacomo.travaglini@arm.com if (GTEST_FLAG(death_test_style) == "threadsafe") { 120613481Sgiacomo.travaglini@arm.com *test = new ExecDeathTest(statement, regex, file, line); 120713481Sgiacomo.travaglini@arm.com } else if (GTEST_FLAG(death_test_style) == "fast") { 120813481Sgiacomo.travaglini@arm.com *test = new NoExecDeathTest(statement, regex); 120913481Sgiacomo.travaglini@arm.com } 121013481Sgiacomo.travaglini@arm.com 121113481Sgiacomo.travaglini@arm.com# endif // GTEST_OS_WINDOWS 121213481Sgiacomo.travaglini@arm.com 121313481Sgiacomo.travaglini@arm.com else { // NOLINT - this is more readable than unbalanced brackets inside #if. 121413481Sgiacomo.travaglini@arm.com DeathTest::set_last_death_test_message( 121513481Sgiacomo.travaglini@arm.com "Unknown death test style \"" + GTEST_FLAG(death_test_style) 121613481Sgiacomo.travaglini@arm.com + "\" encountered"); 121713481Sgiacomo.travaglini@arm.com return false; 121813481Sgiacomo.travaglini@arm.com } 121913481Sgiacomo.travaglini@arm.com 122013481Sgiacomo.travaglini@arm.com return true; 122113481Sgiacomo.travaglini@arm.com} 122213481Sgiacomo.travaglini@arm.com 122313481Sgiacomo.travaglini@arm.com# if GTEST_OS_WINDOWS 122413481Sgiacomo.travaglini@arm.com// Recreates the pipe and event handles from the provided parameters, 122513481Sgiacomo.travaglini@arm.com// signals the event, and returns a file descriptor wrapped around the pipe 122613481Sgiacomo.travaglini@arm.com// handle. This function is called in the child process only. 122713481Sgiacomo.travaglini@arm.comint GetStatusFileDescriptor(unsigned int parent_process_id, 122813481Sgiacomo.travaglini@arm.com size_t write_handle_as_size_t, 122913481Sgiacomo.travaglini@arm.com size_t event_handle_as_size_t) { 123013481Sgiacomo.travaglini@arm.com AutoHandle parent_process_handle(::OpenProcess(PROCESS_DUP_HANDLE, 123113481Sgiacomo.travaglini@arm.com FALSE, // Non-inheritable. 123213481Sgiacomo.travaglini@arm.com parent_process_id)); 123313481Sgiacomo.travaglini@arm.com if (parent_process_handle.Get() == INVALID_HANDLE_VALUE) { 123413481Sgiacomo.travaglini@arm.com DeathTestAbort("Unable to open parent process " + 123513481Sgiacomo.travaglini@arm.com StreamableToString(parent_process_id)); 123613481Sgiacomo.travaglini@arm.com } 123713481Sgiacomo.travaglini@arm.com 123813481Sgiacomo.travaglini@arm.com // TODO(vladl@google.com): Replace the following check with a 123913481Sgiacomo.travaglini@arm.com // compile-time assertion when available. 124013481Sgiacomo.travaglini@arm.com GTEST_CHECK_(sizeof(HANDLE) <= sizeof(size_t)); 124113481Sgiacomo.travaglini@arm.com 124213481Sgiacomo.travaglini@arm.com const HANDLE write_handle = 124313481Sgiacomo.travaglini@arm.com reinterpret_cast<HANDLE>(write_handle_as_size_t); 124413481Sgiacomo.travaglini@arm.com HANDLE dup_write_handle; 124513481Sgiacomo.travaglini@arm.com 124613481Sgiacomo.travaglini@arm.com // The newly initialized handle is accessible only in in the parent 124713481Sgiacomo.travaglini@arm.com // process. To obtain one accessible within the child, we need to use 124813481Sgiacomo.travaglini@arm.com // DuplicateHandle. 124913481Sgiacomo.travaglini@arm.com if (!::DuplicateHandle(parent_process_handle.Get(), write_handle, 125013481Sgiacomo.travaglini@arm.com ::GetCurrentProcess(), &dup_write_handle, 125113481Sgiacomo.travaglini@arm.com 0x0, // Requested privileges ignored since 125213481Sgiacomo.travaglini@arm.com // DUPLICATE_SAME_ACCESS is used. 125313481Sgiacomo.travaglini@arm.com FALSE, // Request non-inheritable handler. 125413481Sgiacomo.travaglini@arm.com DUPLICATE_SAME_ACCESS)) { 125513481Sgiacomo.travaglini@arm.com DeathTestAbort("Unable to duplicate the pipe handle " + 125613481Sgiacomo.travaglini@arm.com StreamableToString(write_handle_as_size_t) + 125713481Sgiacomo.travaglini@arm.com " from the parent process " + 125813481Sgiacomo.travaglini@arm.com StreamableToString(parent_process_id)); 125913481Sgiacomo.travaglini@arm.com } 126013481Sgiacomo.travaglini@arm.com 126113481Sgiacomo.travaglini@arm.com const HANDLE event_handle = reinterpret_cast<HANDLE>(event_handle_as_size_t); 126213481Sgiacomo.travaglini@arm.com HANDLE dup_event_handle; 126313481Sgiacomo.travaglini@arm.com 126413481Sgiacomo.travaglini@arm.com if (!::DuplicateHandle(parent_process_handle.Get(), event_handle, 126513481Sgiacomo.travaglini@arm.com ::GetCurrentProcess(), &dup_event_handle, 126613481Sgiacomo.travaglini@arm.com 0x0, 126713481Sgiacomo.travaglini@arm.com FALSE, 126813481Sgiacomo.travaglini@arm.com DUPLICATE_SAME_ACCESS)) { 126913481Sgiacomo.travaglini@arm.com DeathTestAbort("Unable to duplicate the event handle " + 127013481Sgiacomo.travaglini@arm.com StreamableToString(event_handle_as_size_t) + 127113481Sgiacomo.travaglini@arm.com " from the parent process " + 127213481Sgiacomo.travaglini@arm.com StreamableToString(parent_process_id)); 127313481Sgiacomo.travaglini@arm.com } 127413481Sgiacomo.travaglini@arm.com 127513481Sgiacomo.travaglini@arm.com const int write_fd = 127613481Sgiacomo.travaglini@arm.com ::_open_osfhandle(reinterpret_cast<intptr_t>(dup_write_handle), O_APPEND); 127713481Sgiacomo.travaglini@arm.com if (write_fd == -1) { 127813481Sgiacomo.travaglini@arm.com DeathTestAbort("Unable to convert pipe handle " + 127913481Sgiacomo.travaglini@arm.com StreamableToString(write_handle_as_size_t) + 128013481Sgiacomo.travaglini@arm.com " to a file descriptor"); 128113481Sgiacomo.travaglini@arm.com } 128213481Sgiacomo.travaglini@arm.com 128313481Sgiacomo.travaglini@arm.com // Signals the parent that the write end of the pipe has been acquired 128413481Sgiacomo.travaglini@arm.com // so the parent can release its own write end. 128513481Sgiacomo.travaglini@arm.com ::SetEvent(dup_event_handle); 128613481Sgiacomo.travaglini@arm.com 128713481Sgiacomo.travaglini@arm.com return write_fd; 128813481Sgiacomo.travaglini@arm.com} 128913481Sgiacomo.travaglini@arm.com# endif // GTEST_OS_WINDOWS 129013481Sgiacomo.travaglini@arm.com 129113481Sgiacomo.travaglini@arm.com// Returns a newly created InternalRunDeathTestFlag object with fields 129213481Sgiacomo.travaglini@arm.com// initialized from the GTEST_FLAG(internal_run_death_test) flag if 129313481Sgiacomo.travaglini@arm.com// the flag is specified; otherwise returns NULL. 129413481Sgiacomo.travaglini@arm.comInternalRunDeathTestFlag* ParseInternalRunDeathTestFlag() { 129513481Sgiacomo.travaglini@arm.com if (GTEST_FLAG(internal_run_death_test) == "") return NULL; 129613481Sgiacomo.travaglini@arm.com 129713481Sgiacomo.travaglini@arm.com // GTEST_HAS_DEATH_TEST implies that we have ::std::string, so we 129813481Sgiacomo.travaglini@arm.com // can use it here. 129913481Sgiacomo.travaglini@arm.com int line = -1; 130013481Sgiacomo.travaglini@arm.com int index = -1; 130113481Sgiacomo.travaglini@arm.com ::std::vector< ::std::string> fields; 130213481Sgiacomo.travaglini@arm.com SplitString(GTEST_FLAG(internal_run_death_test).c_str(), '|', &fields); 130313481Sgiacomo.travaglini@arm.com int write_fd = -1; 130413481Sgiacomo.travaglini@arm.com 130513481Sgiacomo.travaglini@arm.com# if GTEST_OS_WINDOWS 130613481Sgiacomo.travaglini@arm.com 130713481Sgiacomo.travaglini@arm.com unsigned int parent_process_id = 0; 130813481Sgiacomo.travaglini@arm.com size_t write_handle_as_size_t = 0; 130913481Sgiacomo.travaglini@arm.com size_t event_handle_as_size_t = 0; 131013481Sgiacomo.travaglini@arm.com 131113481Sgiacomo.travaglini@arm.com if (fields.size() != 6 131213481Sgiacomo.travaglini@arm.com || !ParseNaturalNumber(fields[1], &line) 131313481Sgiacomo.travaglini@arm.com || !ParseNaturalNumber(fields[2], &index) 131413481Sgiacomo.travaglini@arm.com || !ParseNaturalNumber(fields[3], &parent_process_id) 131513481Sgiacomo.travaglini@arm.com || !ParseNaturalNumber(fields[4], &write_handle_as_size_t) 131613481Sgiacomo.travaglini@arm.com || !ParseNaturalNumber(fields[5], &event_handle_as_size_t)) { 131713481Sgiacomo.travaglini@arm.com DeathTestAbort("Bad --gtest_internal_run_death_test flag: " + 131813481Sgiacomo.travaglini@arm.com GTEST_FLAG(internal_run_death_test)); 131913481Sgiacomo.travaglini@arm.com } 132013481Sgiacomo.travaglini@arm.com write_fd = GetStatusFileDescriptor(parent_process_id, 132113481Sgiacomo.travaglini@arm.com write_handle_as_size_t, 132213481Sgiacomo.travaglini@arm.com event_handle_as_size_t); 132313481Sgiacomo.travaglini@arm.com# else 132413481Sgiacomo.travaglini@arm.com 132513481Sgiacomo.travaglini@arm.com if (fields.size() != 4 132613481Sgiacomo.travaglini@arm.com || !ParseNaturalNumber(fields[1], &line) 132713481Sgiacomo.travaglini@arm.com || !ParseNaturalNumber(fields[2], &index) 132813481Sgiacomo.travaglini@arm.com || !ParseNaturalNumber(fields[3], &write_fd)) { 132913481Sgiacomo.travaglini@arm.com DeathTestAbort("Bad --gtest_internal_run_death_test flag: " 133013481Sgiacomo.travaglini@arm.com + GTEST_FLAG(internal_run_death_test)); 133113481Sgiacomo.travaglini@arm.com } 133213481Sgiacomo.travaglini@arm.com 133313481Sgiacomo.travaglini@arm.com# endif // GTEST_OS_WINDOWS 133413481Sgiacomo.travaglini@arm.com 133513481Sgiacomo.travaglini@arm.com return new InternalRunDeathTestFlag(fields[0], line, index, write_fd); 133613481Sgiacomo.travaglini@arm.com} 133713481Sgiacomo.travaglini@arm.com 133813481Sgiacomo.travaglini@arm.com} // namespace internal 133913481Sgiacomo.travaglini@arm.com 134013481Sgiacomo.travaglini@arm.com#endif // GTEST_HAS_DEATH_TEST 134113481Sgiacomo.travaglini@arm.com 134213481Sgiacomo.travaglini@arm.com} // namespace testing 1343