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