llvm/llvm/unittests/Support/CrashRecoveryTest.cpp

//===- llvm/unittest/Support/CrashRecoveryTest.cpp ------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "llvm/Config/config.h"
#include "llvm/Config/llvm-config.h" // for LLVM_ON_UNIX
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/CrashRecoveryContext.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/Program.h"
#include "llvm/Support/Signals.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/TargetParser/Host.h"
#include "llvm/TargetParser/Triple.h"
#include "gtest/gtest.h"

#ifdef _WIN32
#define WIN32_LEAN_AND_MEAN
#define NOGDI
#include <windows.h>
#endif

#ifdef LLVM_ON_UNIX
#ifdef HAVE_SIGNAL_H
#include <signal.h>
#endif
#endif

usingnamespacellvm;
usingnamespacellvm::sys;

static int GlobalInt =;
static void nullDeref() {}
static void incrementGlobal() {}
static void llvmTrap() {}
static void incrementGlobalWithParam(void *) {}

TEST(CrashRecoveryTest, Basic) {}

struct IncrementGlobalCleanup : CrashRecoveryContextCleanup {};

static void noop() {}

TEST(CrashRecoveryTest, Cleanup) {}

TEST(CrashRecoveryTest, DumpStackCleanup) {}

TEST(CrashRecoveryTest, LimitedStackTrace) {}

#ifdef _WIN32
static void raiseIt() {
  RaiseException(123, EXCEPTION_NONCONTINUABLE, 0, NULL);
}

TEST(CrashRecoveryTest, RaiseException) {
  llvm::CrashRecoveryContext::Enable();
  EXPECT_FALSE(CrashRecoveryContext().RunSafely(raiseIt));
}

static void outputString() {
  OutputDebugStringA("output for debugger\n");
}

TEST(CrashRecoveryTest, CallOutputDebugString) {
  llvm::CrashRecoveryContext::Enable();
  EXPECT_TRUE(CrashRecoveryContext().RunSafely(outputString));
}

TEST(CrashRecoveryTest, Abort) {
  llvm::CrashRecoveryContext::Enable();
  auto A = []() { abort(); };
  EXPECT_FALSE(CrashRecoveryContext().RunSafely(A));
  // Test a second time to ensure we reinstall the abort signal handler.
  EXPECT_FALSE(CrashRecoveryContext().RunSafely(A));
}
#endif

// Specifically ensure that programs that signal() or abort() through the
// CrashRecoveryContext can re-throw again their signal, so that `not --crash`
// succeeds.
#ifdef LLVM_ON_UNIX
// See llvm/utils/unittest/UnitTestMain/TestMain.cpp
extern const char *TestMainArgv0;

// Just a reachable symbol to ease resolving of the executable's path.
static cl::opt<std::string> CrashTestStringArg1("crash-test-string-arg1");

TEST(CrashRecoveryTest, UnixCRCReturnCode) {}
#endif