| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155 | 
							- //
 
- // 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
 
- //
 
- //      http://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 "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 {
 
- #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(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(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_TRUE(absl::StartsWith(
 
-       error_line,
 
-       absl::StrCat("*** ",
 
-                    absl::debugging_internal::FailureSignalToString(signo),
 
-                    " received at ")));
 
-   if (absl::debugging_internal::StackTraceWorksForTest()) {
 
-     std::getline(error_output, error_line);
 
-     EXPECT_TRUE(absl::StartsWith(error_line, "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_CASE_P(AbslDeathTest, FailureSignalHandlerDeathTest,
 
-                         ::testing::ValuesIn(kFailureSignals),
 
-                         SignalParamToString);
 
- #endif  // GTEST_HAS_DEATH_TEST
 
- }  // namespace
 
- int main(int argc, char** argv) {
 
-   absl::InitializeSymbolizer(argv[0]);
 
-   testing::InitGoogleTest(&argc, argv);
 
-   return RUN_ALL_TESTS();
 
- }
 
 
  |