1045695f8SEmma Blink //===--- ThreadCrashReporter.cpp - Thread local signal handling --*- C++-*-===// 2045695f8SEmma Blink // 3045695f8SEmma Blink // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4045695f8SEmma Blink // See https://llvm.org/LICENSE.txt for license information. 5045695f8SEmma Blink // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6045695f8SEmma Blink // 7045695f8SEmma Blink //===----------------------------------------------------------------------===// 8045695f8SEmma Blink 9045695f8SEmma Blink #include "support/ThreadCrashReporter.h" 10ba94b8bdSShoaib Meenai #include <atomic> 11045695f8SEmma Blink 12045695f8SEmma Blink namespace clang { 13045695f8SEmma Blink namespace clangd { 14045695f8SEmma Blink 15045695f8SEmma Blink static thread_local ThreadCrashReporter *CurrentReporter = nullptr; 16045695f8SEmma Blink runCrashHandlers()17045695f8SEmma Blinkvoid ThreadCrashReporter::runCrashHandlers() { 18045695f8SEmma Blink // No signal handling is done here on top of what AddSignalHandler() does: 19045695f8SEmma Blink // on Windows the signal handling is implmented via 20045695f8SEmma Blink // SetUnhandledExceptionFilter() which is thread-directed, and on Unix 21045695f8SEmma Blink // platforms the handlers are only called for KillSigs out of which only 22045695f8SEmma Blink // SIGQUIT seems to be process-directed and would be delivered to any thread 23045695f8SEmma Blink // that is not blocking it, but if the thread it gets delivered to has a 24045695f8SEmma Blink // ThreadCrashReporter installed during the interrupt — it seems reasonable to 25045695f8SEmma Blink // let it run and print the thread's context information. 26045695f8SEmma Blink 27045695f8SEmma Blink // Call the reporters in LIFO order. 28045695f8SEmma Blink ThreadCrashReporter *Reporter = CurrentReporter; 29045695f8SEmma Blink while (Reporter) { 30045695f8SEmma Blink Reporter->Callback(); 31045695f8SEmma Blink Reporter = Reporter->Next; 32045695f8SEmma Blink } 33045695f8SEmma Blink } 34045695f8SEmma Blink ThreadCrashReporter(SignalCallback ThreadLocalCallback)35045695f8SEmma BlinkThreadCrashReporter::ThreadCrashReporter(SignalCallback ThreadLocalCallback) 36045695f8SEmma Blink : Callback(std::move(ThreadLocalCallback)), Next(nullptr) { 37045695f8SEmma Blink this->Next = CurrentReporter; 38045695f8SEmma Blink CurrentReporter = this; 39045695f8SEmma Blink // Don't reorder subsequent operations: whatever comes after might crash and 40*c8f47925SRageking8 // we want the crash handler to see the reporter values we just set. 41045695f8SEmma Blink std::atomic_signal_fence(std::memory_order_seq_cst); 42045695f8SEmma Blink } 43045695f8SEmma Blink ~ThreadCrashReporter()44045695f8SEmma BlinkThreadCrashReporter::~ThreadCrashReporter() { 45045695f8SEmma Blink assert(CurrentReporter == this); 46045695f8SEmma Blink CurrentReporter = this->Next; 47045695f8SEmma Blink // Don't reorder subsequent operations: whatever comes after might crash and 48*c8f47925SRageking8 // we want the crash handler to see the reporter values we just set. 49045695f8SEmma Blink std::atomic_signal_fence(std::memory_order_seq_cst); 50045695f8SEmma Blink } 51045695f8SEmma Blink 52045695f8SEmma Blink } // namespace clangd 53045695f8SEmma Blink } // namespace clang 54