1 //===--- ThreadCrashReporter.h - Thread local signal handling ----*- C++-*-===// 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-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_SUPPORT_THREADCRASHREPORTER_H 10 #define LLVM_CLANG_TOOLS_EXTRA_CLANGD_SUPPORT_THREADCRASHREPORTER_H 11 12 #include "llvm/ADT/FunctionExtras.h" 13 14 namespace clang { 15 namespace clangd { 16 17 /// Allows setting per-thread abort/kill signal callbacks, to print additional 18 /// information about the crash depending on which thread got signalled. 19 class ThreadCrashReporter { 20 public: 21 using SignalCallback = llvm::unique_function<void(void)>; 22 23 /// Registers the callback as the first one in thread-local callback chain. 24 /// 25 /// Asserts if the current thread's callback is already set. The callback is 26 /// likely to be invoked in a signal handler. Most LLVM signal handling is not 27 /// strictly async-signal-safe. However reporters should avoid accessing data 28 /// structures likely to be in a bad state on crash. 29 ThreadCrashReporter(SignalCallback ThreadLocalCallback); 30 /// Resets the current thread's callback to nullptr. 31 ~ThreadCrashReporter(); 32 33 /// Moves are disabled to ease nesting and escaping considerations. 34 ThreadCrashReporter(ThreadCrashReporter &&RHS) = delete; 35 ThreadCrashReporter(const ThreadCrashReporter &) = delete; 36 ThreadCrashReporter &operator=(ThreadCrashReporter &&) = delete; 37 ThreadCrashReporter &operator=(const ThreadCrashReporter &) = delete; 38 39 /// Calls all currently-active ThreadCrashReporters for the current thread. 40 /// 41 /// To be called from sys::AddSignalHandler() callback. Any signal filtering 42 /// is the responsibility of the caller. While this function is intended to be 43 /// called from signal handlers, it is not strictly async-signal-safe - see 44 /// constructor comment. 45 /// 46 /// When several reporters are nested, the callbacks are called in LIFO order. 47 static void runCrashHandlers(); 48 49 private: 50 SignalCallback Callback; 51 /// Points to the next reporter up the stack. 52 ThreadCrashReporter *Next; 53 }; 54 55 } // namespace clangd 56 } // namespace clang 57 58 #endif 59