11be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania// Copyright 2005, Google Inc. 21be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania// All rights reserved. 31be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania// 41be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania// Redistribution and use in source and binary forms, with or without 51be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania// modification, are permitted provided that the following conditions are 61be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania// met: 71be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania// 81be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania// * Redistributions of source code must retain the above copyright 91be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania// notice, this list of conditions and the following disclaimer. 101be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania// * Redistributions in binary form must reproduce the above 111be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania// copyright notice, this list of conditions and the following disclaimer 121be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania// in the documentation and/or other materials provided with the 131be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania// distribution. 141be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania// * Neither the name of Google Inc. nor the names of its 151be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania// contributors may be used to endorse or promote products derived from 161be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania// this software without specific prior written permission. 171be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania// 181be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 191be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 201be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 211be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 221be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 231be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 241be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 251be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 261be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 271be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 281be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 291be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania// 301be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania// Author: wan@google.com (Zhanyong Wan), vladl@google.com (Vlad Losev) 311be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania// 321be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania// This file implements death tests. 331be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania 3441d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot#include "gtest/gtest-death-test.h" 3541d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot#include "gtest/internal/gtest-port.h" 361be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania 371be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania#if GTEST_HAS_DEATH_TEST 381be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania 3941d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot# if GTEST_OS_MAC 4041d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot# include <crt_externs.h> 4141d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot# endif // GTEST_OS_MAC 421be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania 4341d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot# include <errno.h> 4441d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot# include <fcntl.h> 4541d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot# include <limits.h> 46fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes 47fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes# if GTEST_OS_LINUX 48fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes# include <signal.h> 49fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes# endif // GTEST_OS_LINUX 50fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes 5141d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot# include <stdarg.h> 521be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania 5341d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot# if GTEST_OS_WINDOWS 5441d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot# include <windows.h> 5541d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot# else 5641d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot# include <sys/mman.h> 5741d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot# include <sys/wait.h> 5841d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot# endif // GTEST_OS_WINDOWS 591be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania 60fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes# if GTEST_OS_QNX 61fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes# include <spawn.h> 62fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes# endif // GTEST_OS_QNX 63fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes 641be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania#endif // GTEST_HAS_DEATH_TEST 651be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania 6641d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot#include "gtest/gtest-message.h" 6741d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot#include "gtest/internal/gtest-string.h" 681be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania 691be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania// Indicates that this translation unit is part of Google Test's 701be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania// implementation. It must come before gtest-internal-inl.h is 711be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania// included, or there will be a compiler error. This trick is to 721be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania// prevent a user from accidentally including gtest-internal-inl.h in 731be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania// his code. 741be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania#define GTEST_IMPLEMENTATION_ 1 751be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania#include "src/gtest-internal-inl.h" 761be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania#undef GTEST_IMPLEMENTATION_ 771be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania 781be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catanianamespace testing { 791be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania 801be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania// Constants. 811be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania 821be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania// The default death test style. 831be2c9def7187e4e643c00a31dd9986395795d7dNicolas Cataniastatic const char kDefaultDeathTestStyle[] = "fast"; 841be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania 851be2c9def7187e4e643c00a31dd9986395795d7dNicolas CataniaGTEST_DEFINE_string_( 861be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania death_test_style, 871be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania internal::StringFromGTestEnv("death_test_style", kDefaultDeathTestStyle), 881be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania "Indicates how to run a death test in a forked child process: " 891be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania "\"threadsafe\" (child process re-executes the test binary " 901be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania "from the beginning, running only the specific death test) or " 911be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania "\"fast\" (child process runs the death test immediately " 921be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania "after forking)."); 931be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania 941be2c9def7187e4e643c00a31dd9986395795d7dNicolas CataniaGTEST_DEFINE_bool_( 951be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania death_test_use_fork, 961be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania internal::BoolFromGTestEnv("death_test_use_fork", false), 971be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania "Instructs to use fork()/_exit() instead of clone() in death tests. " 981be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania "Ignored and always uses fork() on POSIX systems where clone() is not " 991be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania "implemented. Useful when running under valgrind or similar tools if " 1001be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania "those do not support clone(). Valgrind 3.3.1 will just fail if " 1011be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania "it sees an unsupported combination of clone() flags. " 1021be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania "It is not recommended to use this flag w/o valgrind though it will " 1031be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania "work in 99% of the cases. Once valgrind is fixed, this flag will " 1041be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania "most likely be removed."); 1051be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania 1061be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catanianamespace internal { 1071be2c9def7187e4e643c00a31dd9986395795d7dNicolas CataniaGTEST_DEFINE_string_( 1081be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania internal_run_death_test, "", 1091be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania "Indicates the file, line number, temporal index of " 1101be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania "the single death test to run, and a file descriptor to " 1111be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania "which a success code may be sent, all separated by " 112fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes "the '|' characters. This flag is specified if and only if the current " 1131be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania "process is a sub-process launched for running a thread-safe " 1141be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania "death test. FOR INTERNAL USE ONLY."); 1151be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania} // namespace internal 1161be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania 1171be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania#if GTEST_HAS_DEATH_TEST 1181be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania 119fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughesnamespace internal { 120fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes 121fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes// Valid only for fast death tests. Indicates the code is running in the 122fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes// child process of a fast style death test. 123fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughesstatic bool g_in_fast_death_test_child = false; 124fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes 125fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes// Returns a Boolean value indicating whether the caller is currently 126fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes// executing in the context of the death test child process. Tools such as 127fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes// Valgrind heap checkers may need this to modify their behavior in death 128fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes// tests. IMPORTANT: This is an internal utility. Using it may break the 129fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes// implementation of death tests. User code MUST NOT use it. 130fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughesbool InDeathTestChild() { 131fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes# if GTEST_OS_WINDOWS 132fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes 133fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes // On Windows, death tests are thread-safe regardless of the value of the 134fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes // death_test_style flag. 135fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes return !GTEST_FLAG(internal_run_death_test).empty(); 136fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes 137fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes# else 138fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes 139fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes if (GTEST_FLAG(death_test_style) == "threadsafe") 140fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes return !GTEST_FLAG(internal_run_death_test).empty(); 141fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes else 142fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes return g_in_fast_death_test_child; 143fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes#endif 144fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes} 145fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes 146fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes} // namespace internal 147fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes 1481be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania// ExitedWithCode constructor. 1491be2c9def7187e4e643c00a31dd9986395795d7dNicolas CataniaExitedWithCode::ExitedWithCode(int exit_code) : exit_code_(exit_code) { 1501be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania} 1511be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania 1521be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania// ExitedWithCode function-call operator. 1531be2c9def7187e4e643c00a31dd9986395795d7dNicolas Cataniabool ExitedWithCode::operator()(int exit_status) const { 15441d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot# if GTEST_OS_WINDOWS 15541d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot 1561be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania return exit_status == exit_code_; 15741d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot 15841d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot# else 15941d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot 1601be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania return WIFEXITED(exit_status) && WEXITSTATUS(exit_status) == exit_code_; 16141d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot 16241d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot# endif // GTEST_OS_WINDOWS 1631be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania} 1641be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania 16541d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot# if !GTEST_OS_WINDOWS 1661be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania// KilledBySignal constructor. 1671be2c9def7187e4e643c00a31dd9986395795d7dNicolas CataniaKilledBySignal::KilledBySignal(int signum) : signum_(signum) { 1681be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania} 1691be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania 1701be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania// KilledBySignal function-call operator. 1711be2c9def7187e4e643c00a31dd9986395795d7dNicolas Cataniabool KilledBySignal::operator()(int exit_status) const { 1721be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania return WIFSIGNALED(exit_status) && WTERMSIG(exit_status) == signum_; 1731be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania} 17441d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot# endif // !GTEST_OS_WINDOWS 1751be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania 1761be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catanianamespace internal { 1771be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania 1781be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania// Utilities needed for death tests. 1791be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania 1801be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania// Generates a textual description of a given exit code, in the format 1811be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania// specified by wait(2). 182fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughesstatic std::string ExitSummary(int exit_code) { 1831be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania Message m; 18441d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot 18541d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot# if GTEST_OS_WINDOWS 18641d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot 1871be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania m << "Exited with exit status " << exit_code; 18841d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot 18941d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot# else 19041d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot 1911be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania if (WIFEXITED(exit_code)) { 1921be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania m << "Exited with exit status " << WEXITSTATUS(exit_code); 1931be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania } else if (WIFSIGNALED(exit_code)) { 1941be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania m << "Terminated by signal " << WTERMSIG(exit_code); 1951be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania } 19641d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot# ifdef WCOREDUMP 1971be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania if (WCOREDUMP(exit_code)) { 1981be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania m << " (core dumped)"; 1991be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania } 20041d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot# endif 20141d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot# endif // GTEST_OS_WINDOWS 20241d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot 2031be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania return m.GetString(); 2041be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania} 2051be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania 2061be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania// Returns true if exit_status describes a process that was terminated 2071be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania// by a signal, or exited normally with a nonzero exit code. 2081be2c9def7187e4e643c00a31dd9986395795d7dNicolas Cataniabool ExitedUnsuccessfully(int exit_status) { 2091be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania return !ExitedWithCode(0)(exit_status); 2101be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania} 2111be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania 21241d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot# if !GTEST_OS_WINDOWS 2131be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania// Generates a textual failure message when a death test finds more than 2141be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania// one thread running, or cannot determine the number of threads, prior 2151be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania// to executing the given statement. It is the responsibility of the 2161be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania// caller not to pass a thread_count of 1. 217fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughesstatic std::string DeathTestThreadWarning(size_t thread_count) { 2181be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania Message msg; 2191be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania msg << "Death tests use fork(), which is unsafe particularly" 2201be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania << " in a threaded context. For this test, " << GTEST_NAME_ << " "; 2211be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania if (thread_count == 0) 2221be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania msg << "couldn't detect the number of threads."; 2231be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania else 2241be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania msg << "detected " << thread_count << " threads."; 2251be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania return msg.GetString(); 2261be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania} 22741d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot# endif // !GTEST_OS_WINDOWS 2281be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania 2291be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania// Flag characters for reporting a death test that did not die. 2301be2c9def7187e4e643c00a31dd9986395795d7dNicolas Cataniastatic const char kDeathTestLived = 'L'; 2311be2c9def7187e4e643c00a31dd9986395795d7dNicolas Cataniastatic const char kDeathTestReturned = 'R'; 23241d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabotstatic const char kDeathTestThrew = 'T'; 2331be2c9def7187e4e643c00a31dd9986395795d7dNicolas Cataniastatic const char kDeathTestInternalError = 'I'; 2341be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania 23541d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot// An enumeration describing all of the possible ways that a death test can 23641d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot// conclude. DIED means that the process died while executing the test 23741d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot// code; LIVED means that process lived beyond the end of the test code; 23841d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot// RETURNED means that the test statement attempted to execute a return 23941d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot// statement, which is not allowed; THREW means that the test statement 24041d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot// returned control by throwing an exception. IN_PROGRESS means the test 24141d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot// has not yet concluded. 24241d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot// TODO(vladl@google.com): Unify names and possibly values for 24341d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot// AbortReason, DeathTestOutcome, and flag characters above. 24441d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabotenum DeathTestOutcome { IN_PROGRESS, DIED, LIVED, RETURNED, THREW }; 2451be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania 2461be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania// Routine for aborting the program which is safe to call from an 2471be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania// exec-style death test child process, in which case the error 2481be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania// message is propagated back to the parent process. Otherwise, the 2491be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania// message is simply printed to stderr. In either case, the program 2501be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania// then exits with status 1. 251fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughesvoid DeathTestAbort(const std::string& message) { 2521be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania // On a POSIX system, this function may be called from a threadsafe-style 2531be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania // death test child process, which operates on a very small stack. Use 2541be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania // the heap for any additional non-minuscule memory requirements. 2551be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania const InternalRunDeathTestFlag* const flag = 2561be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania GetUnitTestImpl()->internal_run_death_test_flag(); 2571be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania if (flag != NULL) { 25841d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot FILE* parent = posix::FDOpen(flag->write_fd(), "w"); 2591be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania fputc(kDeathTestInternalError, parent); 2601be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania fprintf(parent, "%s", message.c_str()); 2611be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania fflush(parent); 2621be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania _exit(1); 2631be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania } else { 2641be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania fprintf(stderr, "%s", message.c_str()); 2651be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania fflush(stderr); 26641d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot posix::Abort(); 2671be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania } 2681be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania} 2691be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania 2701be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania// A replacement for CHECK that calls DeathTestAbort if the assertion 2711be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania// fails. 27241d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot# define GTEST_DEATH_TEST_CHECK_(expression) \ 2731be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania do { \ 27441d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot if (!::testing::internal::IsTrue(expression)) { \ 275fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes DeathTestAbort( \ 276fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes ::std::string("CHECK failed: File ") + __FILE__ + ", line " \ 277fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes + ::testing::internal::StreamableToString(__LINE__) + ": " \ 278fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes + #expression); \ 2791be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania } \ 28041d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot } while (::testing::internal::AlwaysFalse()) 2811be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania 2821be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania// This macro is similar to GTEST_DEATH_TEST_CHECK_, but it is meant for 2831be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania// evaluating any system call that fulfills two conditions: it must return 2841be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania// -1 on failure, and set errno to EINTR when it is interrupted and 2851be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania// should be tried again. The macro expands to a loop that repeatedly 2861be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania// evaluates the expression as long as it evaluates to -1 and sets 2871be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania// errno to EINTR. If the expression evaluates to -1 but errno is 2881be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania// something other than EINTR, DeathTestAbort is called. 28941d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot# define GTEST_DEATH_TEST_CHECK_SYSCALL_(expression) \ 2901be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania do { \ 2911be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania int gtest_retval; \ 2921be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania do { \ 2931be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania gtest_retval = (expression); \ 2941be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania } while (gtest_retval == -1 && errno == EINTR); \ 2951be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania if (gtest_retval == -1) { \ 296fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes DeathTestAbort( \ 297fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes ::std::string("CHECK failed: File ") + __FILE__ + ", line " \ 298fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes + ::testing::internal::StreamableToString(__LINE__) + ": " \ 299fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes + #expression + " != -1"); \ 3001be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania } \ 30141d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot } while (::testing::internal::AlwaysFalse()) 30241d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot 30341d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot// Returns the message describing the last system error in errno. 304fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughesstd::string GetLastErrnoDescription() { 305fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes return errno == 0 ? "" : posix::StrError(errno); 3061be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania} 3071be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania 30841d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot// This is called from a death test parent process to read a failure 30941d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot// message from the death test child process and log it with the FATAL 31041d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot// severity. On Windows, the message is read from a pipe handle. On other 31141d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot// platforms, it is read from a file descriptor. 31241d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabotstatic void FailFromInternalError(int fd) { 31341d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot Message error; 31441d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot char buffer[256]; 31541d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot int num_read; 31641d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot 31741d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot do { 31841d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot while ((num_read = posix::Read(fd, buffer, 255)) > 0) { 31941d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot buffer[num_read] = '\0'; 32041d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot error << buffer; 32141d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot } 32241d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot } while (num_read == -1 && errno == EINTR); 32341d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot 32441d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot if (num_read == 0) { 32541d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot GTEST_LOG_(FATAL) << error.GetString(); 32641d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot } else { 32741d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot const int last_error = errno; 32841d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot GTEST_LOG_(FATAL) << "Error while reading death test internal: " 32941d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot << GetLastErrnoDescription() << " [" << last_error << "]"; 33041d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot } 33141d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot} 3321be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania 3331be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania// Death test constructor. Increments the running death test count 3341be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania// for the current test. 3351be2c9def7187e4e643c00a31dd9986395795d7dNicolas CataniaDeathTest::DeathTest() { 3361be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania TestInfo* const info = GetUnitTestImpl()->current_test_info(); 3371be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania if (info == NULL) { 3381be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania DeathTestAbort("Cannot run a death test outside of a TEST or " 3391be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania "TEST_F construct"); 3401be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania } 3411be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania} 3421be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania 3431be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania// Creates and returns a death test by dispatching to the current 3441be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania// death test factory. 3451be2c9def7187e4e643c00a31dd9986395795d7dNicolas Cataniabool DeathTest::Create(const char* statement, const RE* regex, 3461be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania const char* file, int line, DeathTest** test) { 3471be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania return GetUnitTestImpl()->death_test_factory()->Create( 3481be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania statement, regex, file, line, test); 3491be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania} 3501be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania 3511be2c9def7187e4e643c00a31dd9986395795d7dNicolas Cataniaconst char* DeathTest::LastMessage() { 3521be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania return last_death_test_message_.c_str(); 3531be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania} 3541be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania 355fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughesvoid DeathTest::set_last_death_test_message(const std::string& message) { 3561be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania last_death_test_message_ = message; 3571be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania} 3581be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania 359fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughesstd::string DeathTest::last_death_test_message_; 3601be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania 3611be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania// Provides cross platform implementation for some death functionality. 3621be2c9def7187e4e643c00a31dd9986395795d7dNicolas Cataniaclass DeathTestImpl : public DeathTest { 3631be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania protected: 36441d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot DeathTestImpl(const char* a_statement, const RE* a_regex) 36541d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot : statement_(a_statement), 36641d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot regex_(a_regex), 3671be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania spawned_(false), 3681be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania status_(-1), 36941d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot outcome_(IN_PROGRESS), 37041d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot read_fd_(-1), 37141d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot write_fd_(-1) {} 37241d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot 37341d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot // read_fd_ is expected to be closed and cleared by a derived class. 37441d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot ~DeathTestImpl() { GTEST_DEATH_TEST_CHECK_(read_fd_ == -1); } 3751be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania 37641d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot void Abort(AbortReason reason); 3771be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania virtual bool Passed(bool status_ok); 3781be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania 3791be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania const char* statement() const { return statement_; } 3801be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania const RE* regex() const { return regex_; } 3811be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania bool spawned() const { return spawned_; } 38241d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot void set_spawned(bool is_spawned) { spawned_ = is_spawned; } 3831be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania int status() const { return status_; } 38441d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot void set_status(int a_status) { status_ = a_status; } 3851be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania DeathTestOutcome outcome() const { return outcome_; } 38641d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot void set_outcome(DeathTestOutcome an_outcome) { outcome_ = an_outcome; } 38741d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot int read_fd() const { return read_fd_; } 38841d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot void set_read_fd(int fd) { read_fd_ = fd; } 38941d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot int write_fd() const { return write_fd_; } 39041d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot void set_write_fd(int fd) { write_fd_ = fd; } 39141d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot 39241d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot // Called in the parent process only. Reads the result code of the death 39341d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot // test child process via a pipe, interprets it to set the outcome_ 39441d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot // member, and closes read_fd_. Outputs diagnostics and terminates in 39541d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot // case of unexpected codes. 39641d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot void ReadAndInterpretStatusByte(); 3971be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania 3981be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania private: 3991be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania // The textual content of the code this object is testing. This class 4001be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania // doesn't own this string and should not attempt to delete it. 4011be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania const char* const statement_; 4021be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania // The regular expression which test output must match. DeathTestImpl 4031be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania // doesn't own this object and should not attempt to delete it. 4041be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania const RE* const regex_; 4051be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania // True if the death test child process has been successfully spawned. 4061be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania bool spawned_; 4071be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania // The exit status of the child process. 4081be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania int status_; 4091be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania // How the death test concluded. 4101be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania DeathTestOutcome outcome_; 41141d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot // Descriptor to the read end of the pipe to the child process. It is 41241d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot // always -1 in the child process. The child keeps its write end of the 41341d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot // pipe in write_fd_. 41441d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot int read_fd_; 41541d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot // Descriptor to the child's write end of the pipe to the parent process. 41641d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot // It is always -1 in the parent process. The parent keeps its end of the 41741d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot // pipe in read_fd_. 41841d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot int write_fd_; 4191be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania}; 4201be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania 42141d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot// Called in the parent process only. Reads the result code of the death 42241d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot// test child process via a pipe, interprets it to set the outcome_ 42341d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot// member, and closes read_fd_. Outputs diagnostics and terminates in 42441d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot// case of unexpected codes. 42541d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabotvoid DeathTestImpl::ReadAndInterpretStatusByte() { 42641d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot char flag; 42741d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot int bytes_read; 42841d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot 42941d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot // The read() here blocks until data is available (signifying the 43041d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot // failure of the death test) or until the pipe is closed (signifying 43141d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot // its success), so it's okay to call this in the parent before 43241d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot // the child process has exited. 43341d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot do { 43441d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot bytes_read = posix::Read(read_fd(), &flag, 1); 43541d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot } while (bytes_read == -1 && errno == EINTR); 43641d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot 43741d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot if (bytes_read == 0) { 43841d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot set_outcome(DIED); 43941d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot } else if (bytes_read == 1) { 44041d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot switch (flag) { 44141d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot case kDeathTestReturned: 44241d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot set_outcome(RETURNED); 44341d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot break; 44441d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot case kDeathTestThrew: 44541d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot set_outcome(THREW); 44641d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot break; 44741d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot case kDeathTestLived: 44841d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot set_outcome(LIVED); 44941d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot break; 45041d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot case kDeathTestInternalError: 45141d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot FailFromInternalError(read_fd()); // Does not return. 45241d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot break; 45341d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot default: 45441d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot GTEST_LOG_(FATAL) << "Death test child process reported " 45541d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot << "unexpected status byte (" 45641d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot << static_cast<unsigned int>(flag) << ")"; 45741d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot } 45841d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot } else { 45941d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot GTEST_LOG_(FATAL) << "Read from death test child process failed: " 46041d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot << GetLastErrnoDescription(); 46141d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot } 46241d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot GTEST_DEATH_TEST_CHECK_SYSCALL_(posix::Close(read_fd())); 46341d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot set_read_fd(-1); 46441d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot} 46541d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot 46641d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot// Signals that the death test code which should have exited, didn't. 46741d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot// Should be called only in a death test child process. 46841d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot// Writes a status byte to the child's status file descriptor, then 46941d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot// calls _exit(1). 47041d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabotvoid DeathTestImpl::Abort(AbortReason reason) { 47141d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot // The parent process considers the death test to be a failure if 47241d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot // it finds any data in our pipe. So, here we write a single flag byte 47341d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot // to the pipe, then exit. 47441d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot const char status_ch = 47541d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot reason == TEST_DID_NOT_DIE ? kDeathTestLived : 47641d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot reason == TEST_THREW_EXCEPTION ? kDeathTestThrew : kDeathTestReturned; 47741d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot 47841d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot GTEST_DEATH_TEST_CHECK_SYSCALL_(posix::Write(write_fd(), &status_ch, 1)); 47941d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot // We are leaking the descriptor here because on some platforms (i.e., 48041d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot // when built as Windows DLL), destructors of global objects will still 48141d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot // run after calling _exit(). On such systems, write_fd_ will be 48241d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot // indirectly closed from the destructor of UnitTestImpl, causing double 48341d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot // close if it is also closed here. On debug configurations, double close 48441d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot // may assert. As there are no in-process buffers to flush here, we are 48541d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot // relying on the OS to close the descriptor after the process terminates 48641d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot // when the destructors are not run. 48741d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot _exit(1); // Exits w/o any normal exit hooks (we were supposed to crash) 48841d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot} 4891be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania 49041d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot// Returns an indented copy of stderr output for a death test. 49141d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot// This makes distinguishing death test output lines from regular log lines 49241d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot// much easier. 49341d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabotstatic ::std::string FormatDeathTestOutput(const ::std::string& output) { 49441d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot ::std::string ret; 49541d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot for (size_t at = 0; ; ) { 49641d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot const size_t line_end = output.find('\n', at); 49741d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot ret += "[ DEATH ] "; 49841d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot if (line_end == ::std::string::npos) { 49941d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot ret += output.substr(at); 50041d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot break; 50141d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot } 50241d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot ret += output.substr(at, line_end + 1 - at); 50341d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot at = line_end + 1; 50441d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot } 50541d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot return ret; 50641d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot} 50741d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot 50841d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot// Assesses the success or failure of a death test, using both private 50941d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot// members which have previously been set, and one argument: 51041d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot// 51141d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot// Private data members: 51241d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot// outcome: An enumeration describing how the death test 51341d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot// concluded: DIED, LIVED, THREW, or RETURNED. The death test 51441d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot// fails in the latter three cases. 51541d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot// status: The exit status of the child process. On *nix, it is in the 51641d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot// in the format specified by wait(2). On Windows, this is the 51741d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot// value supplied to the ExitProcess() API or a numeric code 51841d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot// of the exception that terminated the program. 51941d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot// regex: A regular expression object to be applied to 52041d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot// the test's captured standard error output; the death test 52141d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot// fails if it does not match. 52241d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot// 52341d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot// Argument: 52441d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot// status_ok: true if exit_status is acceptable in the context of 52541d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot// this particular death test, which fails if it is false 52641d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot// 52741d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot// Returns true iff all of the above conditions are met. Otherwise, the 52841d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot// first failing condition, in the order given above, is the one that is 52941d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot// reported. Also sets the last death test message string. 53041d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabotbool DeathTestImpl::Passed(bool status_ok) { 53141d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot if (!spawned()) 53241d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot return false; 53341d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot 534fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes const std::string error_message = GetCapturedStderr(); 53541d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot 53641d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot bool success = false; 53741d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot Message buffer; 53841d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot 53941d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot buffer << "Death test: " << statement() << "\n"; 54041d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot switch (outcome()) { 54141d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot case LIVED: 54241d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot buffer << " Result: failed to die.\n" 54341d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot << " Error msg:\n" << FormatDeathTestOutput(error_message); 54441d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot break; 54541d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot case THREW: 54641d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot buffer << " Result: threw an exception.\n" 54741d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot << " Error msg:\n" << FormatDeathTestOutput(error_message); 54841d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot break; 54941d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot case RETURNED: 55041d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot buffer << " Result: illegal return in test statement.\n" 55141d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot << " Error msg:\n" << FormatDeathTestOutput(error_message); 55241d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot break; 55341d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot case DIED: 55441d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot if (status_ok) { 55541d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot const bool matched = RE::PartialMatch(error_message.c_str(), *regex()); 55641d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot if (matched) { 55741d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot success = true; 55841d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot } else { 55941d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot buffer << " Result: died but not with expected error.\n" 56041d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot << " Expected: " << regex()->pattern() << "\n" 56141d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot << "Actual msg:\n" << FormatDeathTestOutput(error_message); 56241d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot } 56341d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot } else { 56441d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot buffer << " Result: died but not with expected exit code:\n" 56541d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot << " " << ExitSummary(status()) << "\n" 56641d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot << "Actual msg:\n" << FormatDeathTestOutput(error_message); 56741d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot } 56841d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot break; 56941d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot case IN_PROGRESS: 57041d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot default: 57141d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot GTEST_LOG_(FATAL) 57241d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot << "DeathTest::Passed somehow called before conclusion of test"; 57341d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot } 57441d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot 57541d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot DeathTest::set_last_death_test_message(buffer.GetString()); 57641d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot return success; 57741d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot} 57841d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot 57941d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot# if GTEST_OS_WINDOWS 5801be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania// WindowsDeathTest implements death tests on Windows. Due to the 5811be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania// specifics of starting new processes on Windows, death tests there are 5821be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania// always threadsafe, and Google Test considers the 5831be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania// --gtest_death_test_style=fast setting to be equivalent to 5841be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania// --gtest_death_test_style=threadsafe there. 5851be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania// 5861be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania// A few implementation notes: Like the Linux version, the Windows 5871be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania// implementation uses pipes for child-to-parent communication. But due to 5881be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania// the specifics of pipes on Windows, some extra steps are required: 5891be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania// 5901be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania// 1. The parent creates a communication pipe and stores handles to both 5911be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania// ends of it. 5921be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania// 2. The parent starts the child and provides it with the information 5931be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania// necessary to acquire the handle to the write end of the pipe. 5941be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania// 3. The child acquires the write end of the pipe and signals the parent 5951be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania// using a Windows event. 5961be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania// 4. Now the parent can release the write end of the pipe on its side. If 5971be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania// this is done before step 3, the object's reference count goes down to 5981be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania// 0 and it is destroyed, preventing the child from acquiring it. The 5991be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania// parent now has to release it, or read operations on the read end of 6001be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania// the pipe will not return when the child terminates. 6011be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania// 5. The parent reads child's output through the pipe (outcome code and 6021be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania// any possible error messages) from the pipe, and its stderr and then 6031be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania// determines whether to fail the test. 6041be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania// 6051be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania// Note: to distinguish Win32 API calls from the local method and function 6061be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania// calls, the former are explicitly resolved in the global namespace. 6071be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania// 6081be2c9def7187e4e643c00a31dd9986395795d7dNicolas Cataniaclass WindowsDeathTest : public DeathTestImpl { 6091be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania public: 61041d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot WindowsDeathTest(const char* a_statement, 61141d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot const RE* a_regex, 6121be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania const char* file, 6131be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania int line) 61441d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot : DeathTestImpl(a_statement, a_regex), file_(file), line_(line) {} 6151be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania 6161be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania // All of these virtual functions are inherited from DeathTest. 6171be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania virtual int Wait(); 6181be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania virtual TestRole AssumeRole(); 6191be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania 6201be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania private: 6211be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania // The name of the file in which the death test is located. 6221be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania const char* const file_; 6231be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania // The line number on which the death test is located. 6241be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania const int line_; 6251be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania // Handle to the write end of the pipe to the child process. 6261be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania AutoHandle write_handle_; 6271be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania // Child process handle. 6281be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania AutoHandle child_handle_; 6291be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania // Event the child process uses to signal the parent that it has 6301be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania // acquired the handle to the write end of the pipe. After seeing this 6311be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania // event the parent can release its own handles to make sure its 6321be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania // ReadFile() calls return when the child terminates. 6331be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania AutoHandle event_handle_; 6341be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania}; 6351be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania 6361be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania// Waits for the child in a death test to exit, returning its exit 6371be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania// status, or 0 if no child process exists. As a side effect, sets the 6381be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania// outcome data member. 6391be2c9def7187e4e643c00a31dd9986395795d7dNicolas Cataniaint WindowsDeathTest::Wait() { 6401be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania if (!spawned()) 6411be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania return 0; 6421be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania 6431be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania // Wait until the child either signals that it has acquired the write end 6441be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania // of the pipe or it dies. 6451be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania const HANDLE wait_handles[2] = { child_handle_.Get(), event_handle_.Get() }; 6461be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania switch (::WaitForMultipleObjects(2, 6471be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania wait_handles, 6481be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania FALSE, // Waits for any of the handles. 6491be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania INFINITE)) { 6501be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania case WAIT_OBJECT_0: 6511be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania case WAIT_OBJECT_0 + 1: 6521be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania break; 6531be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania default: 6541be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania GTEST_DEATH_TEST_CHECK_(false); // Should not get here. 6551be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania } 6561be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania 6571be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania // The child has acquired the write end of the pipe or exited. 6581be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania // We release the handle on our side and continue. 6591be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania write_handle_.Reset(); 6601be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania event_handle_.Reset(); 6611be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania 66241d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot ReadAndInterpretStatusByte(); 6631be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania 6641be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania // Waits for the child process to exit if it haven't already. This 6651be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania // returns immediately if the child has already exited, regardless of 6661be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania // whether previous calls to WaitForMultipleObjects synchronized on this 6671be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania // handle or not. 6681be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania GTEST_DEATH_TEST_CHECK_( 6691be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania WAIT_OBJECT_0 == ::WaitForSingleObject(child_handle_.Get(), 6701be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania INFINITE)); 67141d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot DWORD status_code; 67241d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot GTEST_DEATH_TEST_CHECK_( 67341d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot ::GetExitCodeProcess(child_handle_.Get(), &status_code) != FALSE); 6741be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania child_handle_.Reset(); 67541d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot set_status(static_cast<int>(status_code)); 67641d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot return status(); 6771be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania} 6781be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania 6791be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania// The AssumeRole process for a Windows death test. It creates a child 6801be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania// process with the same executable as the current process to run the 6811be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania// death test. The child process is given the --gtest_filter and 6821be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania// --gtest_internal_run_death_test flags such that it knows to run the 6831be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania// current death test only. 6841be2c9def7187e4e643c00a31dd9986395795d7dNicolas CataniaDeathTest::TestRole WindowsDeathTest::AssumeRole() { 6851be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania const UnitTestImpl* const impl = GetUnitTestImpl(); 6861be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania const InternalRunDeathTestFlag* const flag = 6871be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania impl->internal_run_death_test_flag(); 6881be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania const TestInfo* const info = impl->current_test_info(); 6891be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania const int death_test_index = info->result()->death_test_count(); 6901be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania 6911be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania if (flag != NULL) { 6921be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania // ParseInternalRunDeathTestFlag() has performed all the necessary 6931be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania // processing. 69441d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot set_write_fd(flag->write_fd()); 6951be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania return EXECUTE_TEST; 6961be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania } 6971be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania 6981be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania // WindowsDeathTest uses an anonymous pipe to communicate results of 6991be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania // a death test. 7001be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania SECURITY_ATTRIBUTES handles_are_inheritable = { 7011be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania sizeof(SECURITY_ATTRIBUTES), NULL, TRUE }; 7021be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania HANDLE read_handle, write_handle; 70341d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot GTEST_DEATH_TEST_CHECK_( 70441d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot ::CreatePipe(&read_handle, &write_handle, &handles_are_inheritable, 70541d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot 0) // Default buffer size. 70641d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot != FALSE); 70741d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot set_read_fd(::_open_osfhandle(reinterpret_cast<intptr_t>(read_handle), 70841d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot O_RDONLY)); 7091be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania write_handle_.Reset(write_handle); 7101be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania event_handle_.Reset(::CreateEvent( 7111be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania &handles_are_inheritable, 7121be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania TRUE, // The event will automatically reset to non-signaled state. 7131be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania FALSE, // The initial state is non-signalled. 7141be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania NULL)); // The even is unnamed. 7151be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania GTEST_DEATH_TEST_CHECK_(event_handle_.Get() != NULL); 716fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes const std::string filter_flag = 717fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes std::string("--") + GTEST_FLAG_PREFIX_ + kFilterFlag + "=" + 718fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes info->test_case_name() + "." + info->name(); 719fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes const std::string internal_flag = 720fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes std::string("--") + GTEST_FLAG_PREFIX_ + kInternalRunDeathTestFlag + 721fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes "=" + file_ + "|" + StreamableToString(line_) + "|" + 722fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes StreamableToString(death_test_index) + "|" + 723fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes StreamableToString(static_cast<unsigned int>(::GetCurrentProcessId())) + 724fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes // size_t has the same width as pointers on both 32-bit and 64-bit 7251be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania // Windows platforms. 7261be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania // See http://msdn.microsoft.com/en-us/library/tcxf1dw6.aspx. 727fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes "|" + StreamableToString(reinterpret_cast<size_t>(write_handle)) + 728fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes "|" + StreamableToString(reinterpret_cast<size_t>(event_handle_.Get())); 7291be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania 7301be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania char executable_path[_MAX_PATH + 1]; // NOLINT 7311be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania GTEST_DEATH_TEST_CHECK_( 7321be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania _MAX_PATH + 1 != ::GetModuleFileNameA(NULL, 7331be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania executable_path, 7341be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania _MAX_PATH)); 7351be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania 736fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes std::string command_line = 737fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes std::string(::GetCommandLineA()) + " " + filter_flag + " \"" + 738fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes internal_flag + "\""; 7391be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania 7401be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania DeathTest::set_last_death_test_message(""); 7411be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania 7421be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania CaptureStderr(); 7431be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania // Flush the log buffers since the log streams are shared with the child. 7441be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania FlushInfoLog(); 7451be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania 7461be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania // The child process will share the standard handles with the parent. 7471be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania STARTUPINFOA startup_info; 7481be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania memset(&startup_info, 0, sizeof(STARTUPINFO)); 7491be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania startup_info.dwFlags = STARTF_USESTDHANDLES; 7501be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania startup_info.hStdInput = ::GetStdHandle(STD_INPUT_HANDLE); 7511be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania startup_info.hStdOutput = ::GetStdHandle(STD_OUTPUT_HANDLE); 7521be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania startup_info.hStdError = ::GetStdHandle(STD_ERROR_HANDLE); 7531be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania 7541be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania PROCESS_INFORMATION process_info; 7551be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania GTEST_DEATH_TEST_CHECK_(::CreateProcessA( 7561be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania executable_path, 7571be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania const_cast<char*>(command_line.c_str()), 7581be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania NULL, // Retuned process handle is not inheritable. 7591be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania NULL, // Retuned thread handle is not inheritable. 7601be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania TRUE, // Child inherits all inheritable handles (for write_handle_). 7611be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania 0x0, // Default creation flags. 7621be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania NULL, // Inherit the parent's environment. 7631be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania UnitTest::GetInstance()->original_working_dir(), 7641be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania &startup_info, 76541d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot &process_info) != FALSE); 7661be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania child_handle_.Reset(process_info.hProcess); 7671be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania ::CloseHandle(process_info.hThread); 7681be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania set_spawned(true); 7691be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania return OVERSEE_TEST; 7701be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania} 77141d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot# else // We are not on Windows. 7721be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania 7731be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania// ForkingDeathTest provides implementations for most of the abstract 7741be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania// methods of the DeathTest interface. Only the AssumeRole method is 7751be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania// left undefined. 7761be2c9def7187e4e643c00a31dd9986395795d7dNicolas Cataniaclass ForkingDeathTest : public DeathTestImpl { 7771be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania public: 7781be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania ForkingDeathTest(const char* statement, const RE* regex); 7791be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania 7801be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania // All of these virtual functions are inherited from DeathTest. 7811be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania virtual int Wait(); 7821be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania 7831be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania protected: 7841be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania void set_child_pid(pid_t child_pid) { child_pid_ = child_pid; } 7851be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania 7861be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania private: 7871be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania // PID of child process during death test; 0 in the child process itself. 7881be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania pid_t child_pid_; 7891be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania}; 7901be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania 7911be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania// Constructs a ForkingDeathTest. 79241d0579e8de9ef4ff178fc4991043c61a19943f7Brett ChabotForkingDeathTest::ForkingDeathTest(const char* a_statement, const RE* a_regex) 79341d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot : DeathTestImpl(a_statement, a_regex), 79441d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot child_pid_(-1) {} 7951be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania 7961be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania// Waits for the child in a death test to exit, returning its exit 7971be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania// status, or 0 if no child process exists. As a side effect, sets the 7981be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania// outcome data member. 7991be2c9def7187e4e643c00a31dd9986395795d7dNicolas Cataniaint ForkingDeathTest::Wait() { 8001be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania if (!spawned()) 8011be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania return 0; 8021be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania 80341d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot ReadAndInterpretStatusByte(); 8041be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania 80541d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot int status_value; 80641d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot GTEST_DEATH_TEST_CHECK_SYSCALL_(waitpid(child_pid_, &status_value, 0)); 80741d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot set_status(status_value); 80841d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot return status_value; 8091be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania} 8101be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania 8111be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania// A concrete death test class that forks, then immediately runs the test 8121be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania// in the child process. 8131be2c9def7187e4e643c00a31dd9986395795d7dNicolas Cataniaclass NoExecDeathTest : public ForkingDeathTest { 8141be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania public: 81541d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot NoExecDeathTest(const char* a_statement, const RE* a_regex) : 81641d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot ForkingDeathTest(a_statement, a_regex) { } 8171be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania virtual TestRole AssumeRole(); 8181be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania}; 8191be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania 8201be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania// The AssumeRole process for a fork-and-run death test. It implements a 8211be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania// straightforward fork, with a simple pipe to transmit the status byte. 8221be2c9def7187e4e643c00a31dd9986395795d7dNicolas CataniaDeathTest::TestRole NoExecDeathTest::AssumeRole() { 8231be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania const size_t thread_count = GetThreadCount(); 8241be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania if (thread_count != 1) { 82541d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot GTEST_LOG_(WARNING) << DeathTestThreadWarning(thread_count); 8261be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania } 8271be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania 8281be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania int pipe_fd[2]; 8291be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania GTEST_DEATH_TEST_CHECK_(pipe(pipe_fd) != -1); 8301be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania 8311be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania DeathTest::set_last_death_test_message(""); 8321be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania CaptureStderr(); 8331be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania // When we fork the process below, the log file buffers are copied, but the 8341be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania // file descriptors are shared. We flush all log files here so that closing 8351be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania // the file descriptors in the child process doesn't throw off the 8361be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania // synchronization between descriptors and buffers in the parent process. 8371be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania // This is as close to the fork as possible to avoid a race condition in case 8381be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania // there are multiple threads running before the death test, and another 8391be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania // thread writes to the log file. 8401be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania FlushInfoLog(); 8411be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania 8421be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania const pid_t child_pid = fork(); 8431be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania GTEST_DEATH_TEST_CHECK_(child_pid != -1); 8441be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania set_child_pid(child_pid); 8451be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania if (child_pid == 0) { 8461be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania GTEST_DEATH_TEST_CHECK_SYSCALL_(close(pipe_fd[0])); 8471be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania set_write_fd(pipe_fd[1]); 8481be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania // Redirects all logging to stderr in the child process to prevent 8491be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania // concurrent writes to the log files. We capture stderr in the parent 8501be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania // process and append the child process' output to a log. 8511be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania LogToStderr(); 85241d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot // Event forwarding to the listeners of event listener API mush be shut 85341d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot // down in death test subprocesses. 85441d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot GetUnitTestImpl()->listeners()->SuppressEventForwarding(); 855fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes g_in_fast_death_test_child = true; 8561be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania return EXECUTE_TEST; 8571be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania } else { 8581be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania GTEST_DEATH_TEST_CHECK_SYSCALL_(close(pipe_fd[1])); 8591be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania set_read_fd(pipe_fd[0]); 8601be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania set_spawned(true); 8611be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania return OVERSEE_TEST; 8621be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania } 8631be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania} 8641be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania 8651be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania// A concrete death test class that forks and re-executes the main 8661be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania// program from the beginning, with command-line flags set that cause 8671be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania// only this specific death test to be run. 8681be2c9def7187e4e643c00a31dd9986395795d7dNicolas Cataniaclass ExecDeathTest : public ForkingDeathTest { 8691be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania public: 87041d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot ExecDeathTest(const char* a_statement, const RE* a_regex, 8711be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania const char* file, int line) : 87241d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot ForkingDeathTest(a_statement, a_regex), file_(file), line_(line) { } 8731be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania virtual TestRole AssumeRole(); 8741be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania private: 875fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes static ::std::vector<testing::internal::string> 876fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes GetArgvsForDeathTestChildProcess() { 877fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes ::std::vector<testing::internal::string> args = GetInjectableArgvs(); 878fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes return args; 879fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes } 8801be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania // The name of the file in which the death test is located. 8811be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania const char* const file_; 8821be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania // The line number on which the death test is located. 8831be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania const int line_; 8841be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania}; 8851be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania 8861be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania// Utility class for accumulating command-line arguments. 8871be2c9def7187e4e643c00a31dd9986395795d7dNicolas Cataniaclass Arguments { 8881be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania public: 8891be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania Arguments() { 8901be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania args_.push_back(NULL); 8911be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania } 8921be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania 8931be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania ~Arguments() { 8941be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania for (std::vector<char*>::iterator i = args_.begin(); i != args_.end(); 8951be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania ++i) { 8961be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania free(*i); 8971be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania } 8981be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania } 8991be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania void AddArgument(const char* argument) { 90041d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot args_.insert(args_.end() - 1, posix::StrDup(argument)); 9011be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania } 9021be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania 9031be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania template <typename Str> 9041be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania void AddArguments(const ::std::vector<Str>& arguments) { 9051be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania for (typename ::std::vector<Str>::const_iterator i = arguments.begin(); 9061be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania i != arguments.end(); 9071be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania ++i) { 90841d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot args_.insert(args_.end() - 1, posix::StrDup(i->c_str())); 9091be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania } 9101be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania } 9111be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania char* const* Argv() { 9121be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania return &args_[0]; 9131be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania } 914fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes 9151be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania private: 9161be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania std::vector<char*> args_; 9171be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania}; 9181be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania 9191be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania// A struct that encompasses the arguments to the child process of a 9201be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania// threadsafe-style death test process. 9211be2c9def7187e4e643c00a31dd9986395795d7dNicolas Cataniastruct ExecDeathTestArgs { 9221be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania char* const* argv; // Command-line arguments for the child's call to exec 9231be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania int close_fd; // File descriptor to close; the read end of a pipe 9241be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania}; 9251be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania 92641d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot# if GTEST_OS_MAC 9271be2c9def7187e4e643c00a31dd9986395795d7dNicolas Cataniainline char** GetEnviron() { 9281be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania // When Google Test is built as a framework on MacOS X, the environ variable 9291be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania // is unavailable. Apple's documentation (man environ) recommends using 9301be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania // _NSGetEnviron() instead. 9311be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania return *_NSGetEnviron(); 9321be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania} 93341d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot# else 93441d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot// Some POSIX platforms expect you to declare environ. extern "C" makes 93541d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot// it reside in the global namespace. 93641d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabotextern "C" char** environ; 93741d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabotinline char** GetEnviron() { return environ; } 93841d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot# endif // GTEST_OS_MAC 9391be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania 940fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes# if !GTEST_OS_QNX 9411be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania// The main function for a threadsafe-style death test child process. 9421be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania// This function is called in a clone()-ed process and thus must avoid 9431be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania// any potentially unsafe operations like malloc or libc functions. 9441be2c9def7187e4e643c00a31dd9986395795d7dNicolas Cataniastatic int ExecDeathTestChildMain(void* child_arg) { 9451be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania ExecDeathTestArgs* const args = static_cast<ExecDeathTestArgs*>(child_arg); 9461be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania GTEST_DEATH_TEST_CHECK_SYSCALL_(close(args->close_fd)); 9471be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania 9481be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania // We need to execute the test program in the same environment where 9491be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania // it was originally invoked. Therefore we change to the original 9501be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania // working directory first. 9511be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania const char* const original_dir = 9521be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania UnitTest::GetInstance()->original_working_dir(); 9531be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania // We can safely call chdir() as it's a direct system call. 9541be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania if (chdir(original_dir) != 0) { 955fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes DeathTestAbort(std::string("chdir(\"") + original_dir + "\") failed: " + 956fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes GetLastErrnoDescription()); 9571be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania return EXIT_FAILURE; 9581be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania } 9591be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania 9601be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania // We can safely call execve() as it's a direct system call. We 9611be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania // cannot use execvp() as it's a libc function and thus potentially 9621be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania // unsafe. Since execve() doesn't search the PATH, the user must 9631be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania // invoke the test program via a valid path that contains at least 9641be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania // one path separator. 9651be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania execve(args->argv[0], args->argv, GetEnviron()); 966fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes DeathTestAbort(std::string("execve(") + args->argv[0] + ", ...) in " + 967fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes original_dir + " failed: " + 968fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes GetLastErrnoDescription()); 9691be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania return EXIT_FAILURE; 9701be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania} 971fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes# endif // !GTEST_OS_QNX 9721be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania 9731be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania// Two utility routines that together determine the direction the stack 9741be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania// grows. 9751be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania// This could be accomplished more elegantly by a single recursive 9761be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania// function, but we want to guard against the unlikely possibility of 9771be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania// a smart compiler optimizing the recursion away. 97841d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot// 97941d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot// GTEST_NO_INLINE_ is required to prevent GCC 4.6 from inlining 98041d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot// StackLowerThanAddress into StackGrowsDown, which then doesn't give 98141d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot// correct answer. 982fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughesvoid StackLowerThanAddress(const void* ptr, bool* result) GTEST_NO_INLINE_; 983fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughesvoid StackLowerThanAddress(const void* ptr, bool* result) { 9841be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania int dummy; 985fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes *result = (&dummy < ptr); 9861be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania} 9871be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania 9881be2c9def7187e4e643c00a31dd9986395795d7dNicolas Cataniabool StackGrowsDown() { 9891be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania int dummy; 990fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes bool result; 991fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes StackLowerThanAddress(&dummy, &result); 992fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes return result; 9931be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania} 9941be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania 995fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes// Spawns a child process with the same executable as the current process in 996fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes// a thread-safe manner and instructs it to run the death test. The 997fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes// implementation uses fork(2) + exec. On systems where clone(2) is 998fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes// available, it is used instead, being slightly more thread-safe. On QNX, 999fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes// fork supports only single-threaded environments, so this function uses 1000fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes// spawn(2) there instead. The function dies with an error message if 1001fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes// anything goes wrong. 1002fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughesstatic pid_t ExecDeathTestSpawnChild(char* const* argv, int close_fd) { 10031be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania ExecDeathTestArgs args = { argv, close_fd }; 100441d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot pid_t child_pid = -1; 10051be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania 1006fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes# if GTEST_OS_QNX 1007fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes // Obtains the current directory and sets it to be closed in the child 1008fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes // process. 1009fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes const int cwd_fd = open(".", O_RDONLY); 1010fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes GTEST_DEATH_TEST_CHECK_(cwd_fd != -1); 1011fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes GTEST_DEATH_TEST_CHECK_SYSCALL_(fcntl(cwd_fd, F_SETFD, FD_CLOEXEC)); 1012fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes // We need to execute the test program in the same environment where 1013fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes // it was originally invoked. Therefore we change to the original 1014fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes // working directory first. 1015fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes const char* const original_dir = 1016fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes UnitTest::GetInstance()->original_working_dir(); 1017fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes // We can safely call chdir() as it's a direct system call. 1018fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes if (chdir(original_dir) != 0) { 1019fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes DeathTestAbort(std::string("chdir(\"") + original_dir + "\") failed: " + 1020fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes GetLastErrnoDescription()); 1021fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes return EXIT_FAILURE; 1022fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes } 1023fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes 1024fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes int fd_flags; 1025fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes // Set close_fd to be closed after spawn. 1026fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes GTEST_DEATH_TEST_CHECK_SYSCALL_(fd_flags = fcntl(close_fd, F_GETFD)); 1027fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes GTEST_DEATH_TEST_CHECK_SYSCALL_(fcntl(close_fd, F_SETFD, 1028fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes fd_flags | FD_CLOEXEC)); 1029fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes struct inheritance inherit = {0}; 1030fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes // spawn is a system call. 1031fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes child_pid = spawn(args.argv[0], 0, NULL, &inherit, args.argv, GetEnviron()); 1032fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes // Restores the current working directory. 1033fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes GTEST_DEATH_TEST_CHECK_(fchdir(cwd_fd) != -1); 1034fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes GTEST_DEATH_TEST_CHECK_SYSCALL_(close(cwd_fd)); 1035fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes 1036fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes# else // GTEST_OS_QNX 1037fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes# if GTEST_OS_LINUX 1038fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes // When a SIGPROF signal is received while fork() or clone() are executing, 1039fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes // the process may hang. To avoid this, we ignore SIGPROF here and re-enable 1040fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes // it after the call to fork()/clone() is complete. 1041fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes struct sigaction saved_sigprof_action; 1042fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes struct sigaction ignore_sigprof_action; 1043fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes memset(&ignore_sigprof_action, 0, sizeof(ignore_sigprof_action)); 1044fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes sigemptyset(&ignore_sigprof_action.sa_mask); 1045fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes ignore_sigprof_action.sa_handler = SIG_IGN; 1046fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes GTEST_DEATH_TEST_CHECK_SYSCALL_(sigaction( 1047fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes SIGPROF, &ignore_sigprof_action, &saved_sigprof_action)); 1048fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes# endif // GTEST_OS_LINUX 1049fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes 1050fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes# if GTEST_HAS_CLONE 10511be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania const bool use_fork = GTEST_FLAG(death_test_use_fork); 10521be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania 10531be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania if (!use_fork) { 10541be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania static const bool stack_grows_down = StackGrowsDown(); 10551be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania const size_t stack_size = getpagesize(); 10561be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania // MMAP_ANONYMOUS is not defined on Mac, so we use MAP_ANON instead. 10571be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania void* const stack = mmap(NULL, stack_size, PROT_READ | PROT_WRITE, 10581be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania MAP_ANON | MAP_PRIVATE, -1, 0); 10591be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania GTEST_DEATH_TEST_CHECK_(stack != MAP_FAILED); 1060fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes 1061fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes // Maximum stack alignment in bytes: For a downward-growing stack, this 1062fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes // amount is subtracted from size of the stack space to get an address 1063fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes // that is within the stack space and is aligned on all systems we care 1064fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes // about. As far as I know there is no ABI with stack alignment greater 1065fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes // than 64. We assume stack and stack_size already have alignment of 1066fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes // kMaxStackAlignment. 1067fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes const size_t kMaxStackAlignment = 64; 10681be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania void* const stack_top = 1069fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes static_cast<char*>(stack) + 1070fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes (stack_grows_down ? stack_size - kMaxStackAlignment : 0); 1071fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes GTEST_DEATH_TEST_CHECK_(stack_size > kMaxStackAlignment && 1072fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes reinterpret_cast<intptr_t>(stack_top) % kMaxStackAlignment == 0); 10731be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania 10741be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania child_pid = clone(&ExecDeathTestChildMain, stack_top, SIGCHLD, &args); 10751be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania 10761be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania GTEST_DEATH_TEST_CHECK_(munmap(stack, stack_size) != -1); 10771be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania } 1078fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes# else 10791be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania const bool use_fork = true; 1080fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes# endif // GTEST_HAS_CLONE 10811be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania 10821be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania if (use_fork && (child_pid = fork()) == 0) { 10831be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania ExecDeathTestChildMain(&args); 10841be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania _exit(0); 10851be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania } 1086fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes# endif // GTEST_OS_QNX 1087fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes# if GTEST_OS_LINUX 1088fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes GTEST_DEATH_TEST_CHECK_SYSCALL_( 1089fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes sigaction(SIGPROF, &saved_sigprof_action, NULL)); 1090fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes# endif // GTEST_OS_LINUX 10911be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania 10921be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania GTEST_DEATH_TEST_CHECK_(child_pid != -1); 10931be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania return child_pid; 10941be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania} 10951be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania 10961be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania// The AssumeRole process for a fork-and-exec death test. It re-executes the 10971be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania// main program from the beginning, setting the --gtest_filter 10981be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania// and --gtest_internal_run_death_test flags to cause only the current 10991be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania// death test to be re-run. 11001be2c9def7187e4e643c00a31dd9986395795d7dNicolas CataniaDeathTest::TestRole ExecDeathTest::AssumeRole() { 11011be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania const UnitTestImpl* const impl = GetUnitTestImpl(); 11021be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania const InternalRunDeathTestFlag* const flag = 11031be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania impl->internal_run_death_test_flag(); 11041be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania const TestInfo* const info = impl->current_test_info(); 11051be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania const int death_test_index = info->result()->death_test_count(); 11061be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania 11071be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania if (flag != NULL) { 110841d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot set_write_fd(flag->write_fd()); 11091be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania return EXECUTE_TEST; 11101be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania } 11111be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania 11121be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania int pipe_fd[2]; 11131be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania GTEST_DEATH_TEST_CHECK_(pipe(pipe_fd) != -1); 11141be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania // Clear the close-on-exec flag on the write end of the pipe, lest 11151be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania // it be closed when the child process does an exec: 11161be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania GTEST_DEATH_TEST_CHECK_(fcntl(pipe_fd[1], F_SETFD, 0) != -1); 11171be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania 1118fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes const std::string filter_flag = 1119fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes std::string("--") + GTEST_FLAG_PREFIX_ + kFilterFlag + "=" 1120fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes + info->test_case_name() + "." + info->name(); 1121fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes const std::string internal_flag = 1122fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes std::string("--") + GTEST_FLAG_PREFIX_ + kInternalRunDeathTestFlag + "=" 1123fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes + file_ + "|" + StreamableToString(line_) + "|" 1124fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes + StreamableToString(death_test_index) + "|" 1125fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes + StreamableToString(pipe_fd[1]); 11261be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania Arguments args; 1127fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes args.AddArguments(GetArgvsForDeathTestChildProcess()); 11281be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania args.AddArgument(filter_flag.c_str()); 11291be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania args.AddArgument(internal_flag.c_str()); 11301be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania 11311be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania DeathTest::set_last_death_test_message(""); 11321be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania 11331be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania CaptureStderr(); 11341be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania // See the comment in NoExecDeathTest::AssumeRole for why the next line 11351be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania // is necessary. 11361be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania FlushInfoLog(); 11371be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania 1138fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes const pid_t child_pid = ExecDeathTestSpawnChild(args.Argv(), pipe_fd[0]); 11391be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania GTEST_DEATH_TEST_CHECK_SYSCALL_(close(pipe_fd[1])); 11401be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania set_child_pid(child_pid); 11411be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania set_read_fd(pipe_fd[0]); 11421be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania set_spawned(true); 11431be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania return OVERSEE_TEST; 11441be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania} 11451be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania 114641d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot# endif // !GTEST_OS_WINDOWS 11471be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania 11481be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania// Creates a concrete DeathTest-derived class that depends on the 11491be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania// --gtest_death_test_style flag, and sets the pointer pointed to 11501be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania// by the "test" argument to its address. If the test should be 11511be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania// skipped, sets that pointer to NULL. Returns true, unless the 11521be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania// flag is set to an invalid value. 11531be2c9def7187e4e643c00a31dd9986395795d7dNicolas Cataniabool DefaultDeathTestFactory::Create(const char* statement, const RE* regex, 11541be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania const char* file, int line, 11551be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania DeathTest** test) { 11561be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania UnitTestImpl* const impl = GetUnitTestImpl(); 11571be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania const InternalRunDeathTestFlag* const flag = 11581be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania impl->internal_run_death_test_flag(); 11591be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania const int death_test_index = impl->current_test_info() 11601be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania ->increment_death_test_count(); 11611be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania 11621be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania if (flag != NULL) { 11631be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania if (death_test_index > flag->index()) { 1164fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes DeathTest::set_last_death_test_message( 1165fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes "Death test count (" + StreamableToString(death_test_index) 1166fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes + ") somehow exceeded expected maximum (" 1167fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes + StreamableToString(flag->index()) + ")"); 11681be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania return false; 11691be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania } 11701be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania 11711be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania if (!(flag->file() == file && flag->line() == line && 11721be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania flag->index() == death_test_index)) { 11731be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania *test = NULL; 11741be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania return true; 11751be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania } 11761be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania } 11771be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania 117841d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot# if GTEST_OS_WINDOWS 117941d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot 11801be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania if (GTEST_FLAG(death_test_style) == "threadsafe" || 11811be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania GTEST_FLAG(death_test_style) == "fast") { 11821be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania *test = new WindowsDeathTest(statement, regex, file, line); 11831be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania } 118441d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot 118541d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot# else 118641d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot 11871be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania if (GTEST_FLAG(death_test_style) == "threadsafe") { 11881be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania *test = new ExecDeathTest(statement, regex, file, line); 11891be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania } else if (GTEST_FLAG(death_test_style) == "fast") { 11901be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania *test = new NoExecDeathTest(statement, regex); 11911be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania } 119241d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot 119341d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot# endif // GTEST_OS_WINDOWS 119441d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot 11951be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania else { // NOLINT - this is more readable than unbalanced brackets inside #if. 1196fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes DeathTest::set_last_death_test_message( 1197fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes "Unknown death test style \"" + GTEST_FLAG(death_test_style) 1198fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes + "\" encountered"); 11991be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania return false; 12001be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania } 12011be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania 12021be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania return true; 12031be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania} 12041be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania 12051be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania// Splits a given string on a given delimiter, populating a given 12061be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania// vector with the fields. GTEST_HAS_DEATH_TEST implies that we have 12071be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania// ::std::string, so we can use it here. 12081be2c9def7187e4e643c00a31dd9986395795d7dNicolas Cataniastatic void SplitString(const ::std::string& str, char delimiter, 12091be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania ::std::vector< ::std::string>* dest) { 12101be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania ::std::vector< ::std::string> parsed; 12111be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania ::std::string::size_type pos = 0; 121241d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot while (::testing::internal::AlwaysTrue()) { 12131be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania const ::std::string::size_type colon = str.find(delimiter, pos); 12141be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania if (colon == ::std::string::npos) { 12151be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania parsed.push_back(str.substr(pos)); 12161be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania break; 12171be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania } else { 12181be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania parsed.push_back(str.substr(pos, colon - pos)); 12191be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania pos = colon + 1; 12201be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania } 12211be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania } 12221be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania dest->swap(parsed); 12231be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania} 12241be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania 122541d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot# if GTEST_OS_WINDOWS 12261be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania// Recreates the pipe and event handles from the provided parameters, 12271be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania// signals the event, and returns a file descriptor wrapped around the pipe 12281be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania// handle. This function is called in the child process only. 12291be2c9def7187e4e643c00a31dd9986395795d7dNicolas Cataniaint GetStatusFileDescriptor(unsigned int parent_process_id, 123041d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot size_t write_handle_as_size_t, 12311be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania size_t event_handle_as_size_t) { 12321be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania AutoHandle parent_process_handle(::OpenProcess(PROCESS_DUP_HANDLE, 12331be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania FALSE, // Non-inheritable. 12341be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania parent_process_id)); 12351be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania if (parent_process_handle.Get() == INVALID_HANDLE_VALUE) { 1236fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes DeathTestAbort("Unable to open parent process " + 1237fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes StreamableToString(parent_process_id)); 12381be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania } 12391be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania 12401be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania // TODO(vladl@google.com): Replace the following check with a 12411be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania // compile-time assertion when available. 12421be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania GTEST_CHECK_(sizeof(HANDLE) <= sizeof(size_t)); 12431be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania 124441d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot const HANDLE write_handle = 124541d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot reinterpret_cast<HANDLE>(write_handle_as_size_t); 124641d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot HANDLE dup_write_handle; 12471be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania 12481be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania // The newly initialized handle is accessible only in in the parent 12491be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania // process. To obtain one accessible within the child, we need to use 12501be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania // DuplicateHandle. 125141d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot if (!::DuplicateHandle(parent_process_handle.Get(), write_handle, 125241d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot ::GetCurrentProcess(), &dup_write_handle, 12531be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania 0x0, // Requested privileges ignored since 12541be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania // DUPLICATE_SAME_ACCESS is used. 12551be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania FALSE, // Request non-inheritable handler. 12561be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania DUPLICATE_SAME_ACCESS)) { 1257fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes DeathTestAbort("Unable to duplicate the pipe handle " + 1258fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes StreamableToString(write_handle_as_size_t) + 1259fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes " from the parent process " + 1260fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes StreamableToString(parent_process_id)); 12611be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania } 12621be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania 12631be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania const HANDLE event_handle = reinterpret_cast<HANDLE>(event_handle_as_size_t); 12641be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania HANDLE dup_event_handle; 12651be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania 12661be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania if (!::DuplicateHandle(parent_process_handle.Get(), event_handle, 12671be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania ::GetCurrentProcess(), &dup_event_handle, 12681be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania 0x0, 12691be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania FALSE, 12701be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania DUPLICATE_SAME_ACCESS)) { 1271fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes DeathTestAbort("Unable to duplicate the event handle " + 1272fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes StreamableToString(event_handle_as_size_t) + 1273fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes " from the parent process " + 1274fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes StreamableToString(parent_process_id)); 12751be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania } 12761be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania 127741d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot const int write_fd = 127841d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot ::_open_osfhandle(reinterpret_cast<intptr_t>(dup_write_handle), O_APPEND); 127941d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot if (write_fd == -1) { 1280fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes DeathTestAbort("Unable to convert pipe handle " + 1281fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes StreamableToString(write_handle_as_size_t) + 1282fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes " to a file descriptor"); 12831be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania } 12841be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania 12851be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania // Signals the parent that the write end of the pipe has been acquired 12861be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania // so the parent can release its own write end. 12871be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania ::SetEvent(dup_event_handle); 12881be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania 128941d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot return write_fd; 12901be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania} 129141d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot# endif // GTEST_OS_WINDOWS 12921be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania 12931be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania// Returns a newly created InternalRunDeathTestFlag object with fields 12941be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania// initialized from the GTEST_FLAG(internal_run_death_test) flag if 12951be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania// the flag is specified; otherwise returns NULL. 12961be2c9def7187e4e643c00a31dd9986395795d7dNicolas CataniaInternalRunDeathTestFlag* ParseInternalRunDeathTestFlag() { 12971be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania if (GTEST_FLAG(internal_run_death_test) == "") return NULL; 12981be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania 12991be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania // GTEST_HAS_DEATH_TEST implies that we have ::std::string, so we 13001be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania // can use it here. 13011be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania int line = -1; 13021be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania int index = -1; 13031be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania ::std::vector< ::std::string> fields; 13041be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania SplitString(GTEST_FLAG(internal_run_death_test).c_str(), '|', &fields); 130541d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot int write_fd = -1; 130641d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot 130741d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot# if GTEST_OS_WINDOWS 13081be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania 13091be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania unsigned int parent_process_id = 0; 131041d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot size_t write_handle_as_size_t = 0; 13111be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania size_t event_handle_as_size_t = 0; 13121be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania 13131be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania if (fields.size() != 6 13141be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania || !ParseNaturalNumber(fields[1], &line) 13151be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania || !ParseNaturalNumber(fields[2], &index) 13161be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania || !ParseNaturalNumber(fields[3], &parent_process_id) 131741d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot || !ParseNaturalNumber(fields[4], &write_handle_as_size_t) 13181be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania || !ParseNaturalNumber(fields[5], &event_handle_as_size_t)) { 1319fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes DeathTestAbort("Bad --gtest_internal_run_death_test flag: " + 1320fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes GTEST_FLAG(internal_run_death_test)); 13211be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania } 132241d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot write_fd = GetStatusFileDescriptor(parent_process_id, 132341d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot write_handle_as_size_t, 132441d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot event_handle_as_size_t); 132541d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot# else 132641d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot 13271be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania if (fields.size() != 4 13281be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania || !ParseNaturalNumber(fields[1], &line) 13291be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania || !ParseNaturalNumber(fields[2], &index) 133041d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot || !ParseNaturalNumber(fields[3], &write_fd)) { 1331fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes DeathTestAbort("Bad --gtest_internal_run_death_test flag: " 1332fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes + GTEST_FLAG(internal_run_death_test)); 13331be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania } 133441d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot 133541d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot# endif // GTEST_OS_WINDOWS 133641d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot 133741d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot return new InternalRunDeathTestFlag(fields[0], line, index, write_fd); 13381be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania} 13391be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania 13401be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania} // namespace internal 13411be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania 13421be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania#endif // GTEST_HAS_DEATH_TEST 13431be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania 13441be2c9def7187e4e643c00a31dd9986395795d7dNicolas Catania} // namespace testing 1345