| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159 | //// Copyright 2018 The Abseil Authors.//// Licensed under the Apache License, Version 2.0 (the "License");// you may not use this file except in compliance with the License.// You may obtain a copy of the License at////      https://www.apache.org/licenses/LICENSE-2.0//// Unless required by applicable law or agreed to in writing, software// distributed under the License is distributed on an "AS IS" BASIS,// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.// See the License for the specific language governing permissions and// limitations under the License.//#include "absl/debugging/failure_signal_handler.h"#include <csignal>#include <cstdio>#include <cstdlib>#include <cstring>#include <fstream>#include "gtest/gtest.h"#include "gmock/gmock.h"#include "absl/base/internal/raw_logging.h"#include "absl/debugging/stacktrace.h"#include "absl/debugging/symbolize.h"#include "absl/strings/match.h"#include "absl/strings/str_cat.h"namespace {using testing::StartsWith;#if GTEST_HAS_DEATH_TEST// For the parameterized death tests. GetParam() returns the signal number.using FailureSignalHandlerDeathTest = ::testing::TestWithParam<int>;// This function runs in a fork()ed process on most systems.void InstallHandlerAndRaise(int signo) {  absl::InstallFailureSignalHandler(absl::FailureSignalHandlerOptions());  raise(signo);}TEST_P(FailureSignalHandlerDeathTest, AbslFailureSignal) {  const int signo = GetParam();  std::string exit_regex = absl::StrCat(      "\\*\\*\\* ", absl::debugging_internal::FailureSignalToString(signo),      " received at time=");#ifndef _WIN32  EXPECT_EXIT(InstallHandlerAndRaise(signo), testing::KilledBySignal(signo),              exit_regex);#else  // Windows doesn't have testing::KilledBySignal().  EXPECT_DEATH_IF_SUPPORTED(InstallHandlerAndRaise(signo), exit_regex);#endif}ABSL_CONST_INIT FILE* error_file = nullptr;void WriteToErrorFile(const char* msg) {  if (msg != nullptr) {    ABSL_RAW_CHECK(fwrite(msg, strlen(msg), 1, error_file) == 1,                   "fwrite() failed");  }  ABSL_RAW_CHECK(fflush(error_file) == 0, "fflush() failed");}std::string GetTmpDir() {  // TEST_TMPDIR is set by Bazel. Try the others when not running under Bazel.  static const char* const kTmpEnvVars[] = {"TEST_TMPDIR", "TMPDIR", "TEMP",                                            "TEMPDIR", "TMP"};  for (const char* const var : kTmpEnvVars) {    const char* tmp_dir = std::getenv(var);    if (tmp_dir != nullptr) {      return tmp_dir;    }  }  // Try something reasonable.  return "/tmp";}// This function runs in a fork()ed process on most systems.void InstallHandlerWithWriteToFileAndRaise(const char* file, int signo) {  error_file = fopen(file, "w");  ABSL_RAW_CHECK(error_file != nullptr, "Failed create error_file");  absl::FailureSignalHandlerOptions options;  options.writerfn = WriteToErrorFile;  absl::InstallFailureSignalHandler(options);  raise(signo);}TEST_P(FailureSignalHandlerDeathTest, AbslFatalSignalsWithWriterFn) {  const int signo = GetParam();  std::string tmp_dir = GetTmpDir();  std::string file = absl::StrCat(tmp_dir, "/signo_", signo);  std::string exit_regex = absl::StrCat(      "\\*\\*\\* ", absl::debugging_internal::FailureSignalToString(signo),      " received at time=");#ifndef _WIN32  EXPECT_EXIT(InstallHandlerWithWriteToFileAndRaise(file.c_str(), signo),              testing::KilledBySignal(signo), exit_regex);#else  // Windows doesn't have testing::KilledBySignal().  EXPECT_DEATH_IF_SUPPORTED(      InstallHandlerWithWriteToFileAndRaise(file.c_str(), signo), exit_regex);#endif  // Open the file in this process and check its contents.  std::fstream error_output(file);  ASSERT_TRUE(error_output.is_open()) << file;  std::string error_line;  std::getline(error_output, error_line);  EXPECT_THAT(      error_line,      StartsWith(absl::StrCat(          "*** ", absl::debugging_internal::FailureSignalToString(signo),          " received at ")));  if (absl::debugging_internal::StackTraceWorksForTest()) {    std::getline(error_output, error_line);    EXPECT_THAT(error_line, StartsWith("PC: "));  }}constexpr int kFailureSignals[] = {    SIGSEGV, SIGILL,  SIGFPE, SIGABRT, SIGTERM,#ifndef _WIN32    SIGBUS,  SIGTRAP,#endif};std::string SignalParamToString(const ::testing::TestParamInfo<int>& info) {  std::string result =      absl::debugging_internal::FailureSignalToString(info.param);  if (result.empty()) {    result = absl::StrCat(info.param);  }  return result;}INSTANTIATE_TEST_SUITE_P(AbslDeathTest, FailureSignalHandlerDeathTest,                         ::testing::ValuesIn(kFailureSignals),                         SignalParamToString);#endif  // GTEST_HAS_DEATH_TEST}  // namespaceint main(int argc, char** argv) {  absl::InitializeSymbolizer(argv[0]);  testing::InitGoogleTest(&argc, argv);  return RUN_ALL_TESTS();}
 |