79 lines · cpp
1///===- ThreadCrashReporterTests.cpp - Thread local signal handling tests -===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#include "support/ThreadCrashReporter.h"10#include "support/Threading.h"11#include "llvm/Support/Signals.h"12#include "gtest/gtest.h"13#include <csignal>14#include <string>15 16namespace clang {17namespace clangd {18 19namespace {20 21static void infoSignalHandler() { ThreadCrashReporter::runCrashHandlers(); }22 23TEST(ThreadCrashReporterTest, All) {24#if defined(_WIN32)25 // Simulate signals on Windows for unit testing purposes.26 // The `crash.test` lit test checks the end-to-end integration.27 auto SignalCurrentThread = []() { infoSignalHandler(); };28#else29 llvm::sys::SetInfoSignalFunction(&infoSignalHandler);30 auto SignalCurrentThread = []() { raise(SIGUSR1); };31#endif32 33 AsyncTaskRunner Runner;34 auto SignalAnotherThread = [&]() {35 Runner.runAsync("signal another thread", SignalCurrentThread);36 Runner.wait();37 };38 39 bool Called;40 {41 ThreadCrashReporter ScopedReporter([&Called]() { Called = true; });42 // Check handler gets called when a signal gets delivered to the current43 // thread.44 Called = false;45 SignalCurrentThread();46 EXPECT_TRUE(Called);47 48 // Check handler does not get called when another thread gets signalled.49 Called = false;50 SignalAnotherThread();51 EXPECT_FALSE(Called);52 }53 // Check handler does not get called when the reporter object goes out of54 // scope.55 Called = false;56 SignalCurrentThread();57 EXPECT_FALSE(Called);58 59 std::string Order = "";60 {61 ThreadCrashReporter ScopedReporter([&Order] { Order.push_back('a'); });62 {63 ThreadCrashReporter ScopedReporter([&Order] { Order.push_back('b'); });64 SignalCurrentThread();65 }66 // Check that handlers are called in LIFO order.67 EXPECT_EQ(Order, "ba");68 69 // Check that current handler is the only one after the nested scope is70 // over.71 SignalCurrentThread();72 EXPECT_EQ(Order, "baa");73 }74}75 76} // namespace77} // namespace clangd78} // namespace clang79