mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-12-13 14:35:54 +00:00
Don't use recursion to print out the PrettyStackTrace after a crash. If the
crash was due to a stack overflow, chances are good that this would also cause a stack overflow. llvm-svn: 270903
This commit is contained in:
parent
f05c00c198
commit
978cfd3135
@ -29,9 +29,11 @@ namespace llvm {
|
||||
/// constructed and destructed, they will add their symbolic frames to a
|
||||
/// virtual stack trace. This gets dumped out if the program crashes.
|
||||
class PrettyStackTraceEntry {
|
||||
const PrettyStackTraceEntry *NextEntry;
|
||||
friend PrettyStackTraceEntry *ReverseStackTrace(PrettyStackTraceEntry *);
|
||||
|
||||
PrettyStackTraceEntry *NextEntry;
|
||||
PrettyStackTraceEntry(const PrettyStackTraceEntry &) = delete;
|
||||
void operator=(const PrettyStackTraceEntry&) = delete;
|
||||
void operator=(const PrettyStackTraceEntry &) = delete;
|
||||
public:
|
||||
PrettyStackTraceEntry();
|
||||
virtual ~PrettyStackTraceEntry();
|
||||
@ -67,7 +69,7 @@ namespace llvm {
|
||||
};
|
||||
|
||||
/// Returns the topmost element of the "pretty" stack state.
|
||||
const void* SavePrettyStackState();
|
||||
const void *SavePrettyStackState();
|
||||
|
||||
/// Restores the topmost element of the "pretty" stack state to State, which
|
||||
/// should come from a previous call to SavePrettyStackState(). This is
|
||||
@ -76,7 +78,7 @@ namespace llvm {
|
||||
/// happens after a crash that's been recovered by CrashRecoveryContext
|
||||
/// doesn't have frames on it that were added in code unwound by the
|
||||
/// CrashRecoveryContext.
|
||||
void RestorePrettyStackState(const void* State);
|
||||
void RestorePrettyStackState(const void *State);
|
||||
|
||||
} // end namespace llvm
|
||||
|
||||
|
@ -21,6 +21,8 @@
|
||||
#include "llvm/Support/Watchdog.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
|
||||
#include <tuple>
|
||||
|
||||
#ifdef HAVE_CRASHREPORTERCLIENT_H
|
||||
#include <CrashReporterClient.h>
|
||||
#endif
|
||||
@ -36,20 +38,32 @@ using namespace llvm;
|
||||
// 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 const PrettyStackTraceEntry *PrettyStackTraceHead =
|
||||
nullptr;
|
||||
static LLVM_THREAD_LOCAL PrettyStackTraceEntry *PrettyStackTraceHead = nullptr;
|
||||
|
||||
static unsigned PrintStack(const PrettyStackTraceEntry *Entry, raw_ostream &OS){
|
||||
unsigned NextID = 0;
|
||||
if (Entry->getNextEntry())
|
||||
NextID = PrintStack(Entry->getNextEntry(), OS);
|
||||
OS << NextID << ".\t";
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
return NextID+1;
|
||||
llvm::ReverseStackTrace(ReversedStack);
|
||||
}
|
||||
|
||||
/// PrintCurStackTrace - Print the current stack trace to the specified stream.
|
||||
@ -60,7 +74,7 @@ static void PrintCurStackTrace(raw_ostream &OS) {
|
||||
// If there are pretty stack frames registered, walk and emit them.
|
||||
OS << "Stack dump:\n";
|
||||
|
||||
PrintStack(PrettyStackTraceHead, OS);
|
||||
PrintStack(OS);
|
||||
OS.flush();
|
||||
}
|
||||
|
||||
@ -123,7 +137,7 @@ PrettyStackTraceEntry::~PrettyStackTraceEntry() {
|
||||
#if defined(HAVE_BACKTRACE) && defined(ENABLE_BACKTRACES)
|
||||
assert(PrettyStackTraceHead == this &&
|
||||
"Pretty stack trace entry destruction is out of order");
|
||||
PrettyStackTraceHead = getNextEntry();
|
||||
PrettyStackTraceHead = NextEntry;
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -154,7 +168,7 @@ void llvm::EnablePrettyStackTrace() {
|
||||
#endif
|
||||
}
|
||||
|
||||
const void* llvm::SavePrettyStackState() {
|
||||
const void *llvm::SavePrettyStackState() {
|
||||
#if defined(HAVE_BACKTRACE) && defined(ENABLE_BACKTRACES)
|
||||
return PrettyStackTraceHead;
|
||||
#else
|
||||
@ -162,9 +176,9 @@ const void* llvm::SavePrettyStackState() {
|
||||
#endif
|
||||
}
|
||||
|
||||
void llvm::RestorePrettyStackState(const void* Top) {
|
||||
void llvm::RestorePrettyStackState(const void *Top) {
|
||||
#if defined(HAVE_BACKTRACE) && defined(ENABLE_BACKTRACES)
|
||||
PrettyStackTraceHead = (const PrettyStackTraceEntry*)Top;
|
||||
PrettyStackTraceHead = (PrettyStackTraceEntry*)Top;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user