mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-22 18:54:02 +01:00
eb66b33867
I did this a long time ago with a janky python script, but now clang-format has built-in support for this. I fed clang-format every line with a #include and let it re-sort things according to the precise LLVM rules for include ordering baked into clang-format these days. I've reverted a number of files where the results of sorting includes isn't healthy. Either places where we have legacy code relying on particular include ordering (where possible, I'll fix these separately) or where we have particular formatting around #include lines that I didn't want to disturb in this patch. This patch is *entirely* mechanical. If you get merge conflicts or anything, just ignore the changes in this patch and run clang-format over your #include lines in the files. Sorry for any noise here, but it is important to keep these things stable. I was seeing an increasing number of patches with irrelevant re-ordering of #include lines because clang-format was used. This patch at least isolates that churn, makes it easy to skip when resolving conflicts, and gets us to a clean baseline (again). llvm-svn: 304787
207 lines
6.3 KiB
C++
207 lines
6.3 KiB
C++
//===- PrettyStackTrace.cpp - Pretty Crash Handling -----------------------===//
|
|
//
|
|
// The LLVM Compiler Infrastructure
|
|
//
|
|
// This file is distributed under the University of Illinois Open Source
|
|
// License. See LICENSE.TXT for details.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
//
|
|
// This file defines some helpful functions for dealing with the possibility of
|
|
// Unix signals occurring while your program is running.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "llvm/Support/PrettyStackTrace.h"
|
|
#include "llvm-c/ErrorHandling.h"
|
|
#include "llvm/ADT/SmallString.h"
|
|
#include "llvm/Config/config.h" // Get autoconf configuration settings
|
|
#include "llvm/Support/Compiler.h"
|
|
#include "llvm/Support/Signals.h"
|
|
#include "llvm/Support/Watchdog.h"
|
|
#include "llvm/Support/raw_ostream.h"
|
|
|
|
#include <cstdarg>
|
|
#include <cstdio>
|
|
#include <tuple>
|
|
|
|
#ifdef HAVE_CRASHREPORTERCLIENT_H
|
|
#include <CrashReporterClient.h>
|
|
#endif
|
|
|
|
using namespace llvm;
|
|
|
|
// If backtrace support is not enabled, compile out support for pretty stack
|
|
// traces. This has the secondary effect of not requiring thread local storage
|
|
// when backtrace support is disabled.
|
|
#if defined(HAVE_BACKTRACE) && ENABLE_BACKTRACES
|
|
|
|
// We need a thread local pointer to manage the stack of our stack trace
|
|
// objects, but we *really* cannot tolerate destructors running and do not want
|
|
// to pay any overhead of synchronizing. As a consequence, we use a raw
|
|
// thread-local variable.
|
|
static LLVM_THREAD_LOCAL PrettyStackTraceEntry *PrettyStackTraceHead = nullptr;
|
|
|
|
namespace llvm {
|
|
PrettyStackTraceEntry *ReverseStackTrace(PrettyStackTraceEntry *Head) {
|
|
PrettyStackTraceEntry *Prev = nullptr;
|
|
while (Head)
|
|
std::tie(Prev, Head, Head->NextEntry) =
|
|
std::make_tuple(Head, Head->NextEntry, Prev);
|
|
return Prev;
|
|
}
|
|
}
|
|
|
|
static void PrintStack(raw_ostream &OS) {
|
|
// Print out the stack in reverse order. To avoid recursion (which is likely
|
|
// to fail if we crashed due to stack overflow), we do an up-front pass to
|
|
// reverse the stack, then print it, then reverse it again.
|
|
unsigned ID = 0;
|
|
PrettyStackTraceEntry *ReversedStack =
|
|
llvm::ReverseStackTrace(PrettyStackTraceHead);
|
|
for (const PrettyStackTraceEntry *Entry = ReversedStack; Entry;
|
|
Entry = Entry->getNextEntry()) {
|
|
OS << ID++ << ".\t";
|
|
sys::Watchdog W(5);
|
|
Entry->print(OS);
|
|
}
|
|
llvm::ReverseStackTrace(ReversedStack);
|
|
}
|
|
|
|
/// PrintCurStackTrace - Print the current stack trace to the specified stream.
|
|
static void PrintCurStackTrace(raw_ostream &OS) {
|
|
// Don't print an empty trace.
|
|
if (!PrettyStackTraceHead) return;
|
|
|
|
// If there are pretty stack frames registered, walk and emit them.
|
|
OS << "Stack dump:\n";
|
|
|
|
PrintStack(OS);
|
|
OS.flush();
|
|
}
|
|
|
|
// Integrate with crash reporter libraries.
|
|
#if defined (__APPLE__) && defined(HAVE_CRASHREPORTERCLIENT_H)
|
|
// If any clients of llvm try to link to libCrashReporterClient.a themselves,
|
|
// only one crash info struct will be used.
|
|
extern "C" {
|
|
CRASH_REPORTER_CLIENT_HIDDEN
|
|
struct crashreporter_annotations_t gCRAnnotations
|
|
__attribute__((section("__DATA," CRASHREPORTER_ANNOTATIONS_SECTION)))
|
|
= { CRASHREPORTER_ANNOTATIONS_VERSION, 0, 0, 0, 0, 0, 0 };
|
|
}
|
|
#elif defined(__APPLE__) && HAVE_CRASHREPORTER_INFO
|
|
extern "C" const char *__crashreporter_info__
|
|
__attribute__((visibility("hidden"))) = 0;
|
|
asm(".desc ___crashreporter_info__, 0x10");
|
|
#endif
|
|
|
|
/// CrashHandler - This callback is run if a fatal signal is delivered to the
|
|
/// process, it prints the pretty stack trace.
|
|
static void CrashHandler(void *) {
|
|
#ifndef __APPLE__
|
|
// On non-apple systems, just emit the crash stack trace to stderr.
|
|
PrintCurStackTrace(errs());
|
|
#else
|
|
// Otherwise, emit to a smallvector of chars, send *that* to stderr, but also
|
|
// put it into __crashreporter_info__.
|
|
SmallString<2048> TmpStr;
|
|
{
|
|
raw_svector_ostream Stream(TmpStr);
|
|
PrintCurStackTrace(Stream);
|
|
}
|
|
|
|
if (!TmpStr.empty()) {
|
|
#ifdef HAVE_CRASHREPORTERCLIENT_H
|
|
// Cast to void to avoid warning.
|
|
(void)CRSetCrashLogMessage(std::string(TmpStr.str()).c_str());
|
|
#elif HAVE_CRASHREPORTER_INFO
|
|
__crashreporter_info__ = strdup(std::string(TmpStr.str()).c_str());
|
|
#endif
|
|
errs() << TmpStr.str();
|
|
}
|
|
|
|
#endif
|
|
}
|
|
|
|
// defined(HAVE_BACKTRACE) && ENABLE_BACKTRACES
|
|
#endif
|
|
|
|
PrettyStackTraceEntry::PrettyStackTraceEntry() {
|
|
#if defined(HAVE_BACKTRACE) && ENABLE_BACKTRACES
|
|
// Link ourselves.
|
|
NextEntry = PrettyStackTraceHead;
|
|
PrettyStackTraceHead = this;
|
|
#endif
|
|
}
|
|
|
|
PrettyStackTraceEntry::~PrettyStackTraceEntry() {
|
|
#if defined(HAVE_BACKTRACE) && ENABLE_BACKTRACES
|
|
assert(PrettyStackTraceHead == this &&
|
|
"Pretty stack trace entry destruction is out of order");
|
|
PrettyStackTraceHead = NextEntry;
|
|
#endif
|
|
}
|
|
|
|
void PrettyStackTraceString::print(raw_ostream &OS) const { OS << Str << "\n"; }
|
|
|
|
PrettyStackTraceFormat::PrettyStackTraceFormat(const char *Format, ...) {
|
|
va_list AP;
|
|
va_start(AP, Format);
|
|
const int SizeOrError = vsnprintf(nullptr, 0, Format, AP);
|
|
va_end(AP);
|
|
if (SizeOrError < 0) {
|
|
return;
|
|
}
|
|
|
|
const int Size = SizeOrError + 1; // '\0'
|
|
Str.resize(Size);
|
|
va_start(AP, Format);
|
|
vsnprintf(Str.data(), Size, Format, AP);
|
|
va_end(AP);
|
|
}
|
|
|
|
void PrettyStackTraceFormat::print(raw_ostream &OS) const { OS << Str << "\n"; }
|
|
|
|
void PrettyStackTraceProgram::print(raw_ostream &OS) const {
|
|
OS << "Program arguments: ";
|
|
// Print the argument list.
|
|
for (unsigned i = 0, e = ArgC; i != e; ++i)
|
|
OS << ArgV[i] << ' ';
|
|
OS << '\n';
|
|
}
|
|
|
|
#if defined(HAVE_BACKTRACE) && ENABLE_BACKTRACES
|
|
static bool RegisterCrashPrinter() {
|
|
sys::AddSignalHandler(CrashHandler, nullptr);
|
|
return false;
|
|
}
|
|
#endif
|
|
|
|
void llvm::EnablePrettyStackTrace() {
|
|
#if defined(HAVE_BACKTRACE) && ENABLE_BACKTRACES
|
|
// The first time this is called, we register the crash printer.
|
|
static bool HandlerRegistered = RegisterCrashPrinter();
|
|
(void)HandlerRegistered;
|
|
#endif
|
|
}
|
|
|
|
const void *llvm::SavePrettyStackState() {
|
|
#if defined(HAVE_BACKTRACE) && ENABLE_BACKTRACES
|
|
return PrettyStackTraceHead;
|
|
#else
|
|
return nullptr;
|
|
#endif
|
|
}
|
|
|
|
void llvm::RestorePrettyStackState(const void *Top) {
|
|
#if defined(HAVE_BACKTRACE) && ENABLE_BACKTRACES
|
|
PrettyStackTraceHead =
|
|
static_cast<PrettyStackTraceEntry *>(const_cast<void *>(Top));
|
|
#endif
|
|
}
|
|
|
|
void LLVMEnablePrettyStackTrace() {
|
|
EnablePrettyStackTrace();
|
|
}
|