llvm.org GIT mirror llvm / 6036403
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. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@270903 91177308-0d34-0410-b5e6-96231b3b80d8 Richard Smith 4 years ago
2 changed file(s) with 35 addition(s) and 19 deletion(s). Raw diff Collapse all Expand all
2828 /// constructed and destructed, they will add their symbolic frames to a
2929 /// virtual stack trace. This gets dumped out if the program crashes.
3030 class PrettyStackTraceEntry {
31 const PrettyStackTraceEntry *NextEntry;
31 friend PrettyStackTraceEntry *ReverseStackTrace(PrettyStackTraceEntry *);
32
33 PrettyStackTraceEntry *NextEntry;
3234 PrettyStackTraceEntry(const PrettyStackTraceEntry &) = delete;
33 void operator=(const PrettyStackTraceEntry&) = delete;
35 void operator=(const PrettyStackTraceEntry &) = delete;
3436 public:
3537 PrettyStackTraceEntry();
3638 virtual ~PrettyStackTraceEntry();
6668 };
6769
6870 /// Returns the topmost element of the "pretty" stack state.
69 const void* SavePrettyStackState();
71 const void *SavePrettyStackState();
7072
7173 /// Restores the topmost element of the "pretty" stack state to State, which
7274 /// should come from a previous call to SavePrettyStackState(). This is
7577 /// happens after a crash that's been recovered by CrashRecoveryContext
7678 /// doesn't have frames on it that were added in code unwound by the
7779 /// CrashRecoveryContext.
78 void RestorePrettyStackState(const void* State);
80 void RestorePrettyStackState(const void *State);
7981
8082 } // end namespace llvm
8183
2020 #include "llvm/Support/Watchdog.h"
2121 #include "llvm/Support/raw_ostream.h"
2222
23 #include
24
2325 #ifdef HAVE_CRASHREPORTERCLIENT_H
2426 #include
2527 #endif
3537 // objects, but we *really* cannot tolerate destructors running and do not want
3638 // to pay any overhead of synchronizing. As a consequence, we use a raw
3739 // thread-local variable.
38 static LLVM_THREAD_LOCAL const PrettyStackTraceEntry *PrettyStackTraceHead =
39 nullptr;
40 static LLVM_THREAD_LOCAL PrettyStackTraceEntry *PrettyStackTraceHead = nullptr;
4041
41 static unsigned PrintStack(const PrettyStackTraceEntry *Entry, raw_ostream &OS){
42 unsigned NextID = 0;
43 if (Entry->getNextEntry())
44 NextID = PrintStack(Entry->getNextEntry(), OS);
45 OS << NextID << ".\t";
46 {
42 namespace llvm {
43 PrettyStackTraceEntry *ReverseStackTrace(PrettyStackTraceEntry *Head) {
44 PrettyStackTraceEntry *Prev = nullptr;
45 while (Head)
46 std::tie(Prev, Head, Head->NextEntry) =
47 std::make_tuple(Head, Head->NextEntry, Prev);
48 return Prev;
49 }
50 }
51
52 static void PrintStack(raw_ostream &OS) {
53 // Print out the stack in reverse order. To avoid recursion (which is likely
54 // to fail if we crashed due to stack overflow), we do an up-front pass to
55 // reverse the stack, then print it, then reverse it again.
56 unsigned ID = 0;
57 PrettyStackTraceEntry *ReversedStack =
58 llvm::ReverseStackTrace(PrettyStackTraceHead);
59 for (const PrettyStackTraceEntry *Entry = ReversedStack; Entry;
60 Entry = Entry->getNextEntry()) {
61 OS << ID++ << ".\t";
4762 sys::Watchdog W(5);
4863 Entry->print(OS);
4964 }
50
51 return NextID+1;
65 llvm::ReverseStackTrace(ReversedStack);
5266 }
5367
5468 /// PrintCurStackTrace - Print the current stack trace to the specified stream.
5973 // If there are pretty stack frames registered, walk and emit them.
6074 OS << "Stack dump:\n";
6175
62 PrintStack(PrettyStackTraceHead, OS);
76 PrintStack(OS);
6377 OS.flush();
6478 }
6579
122136 #if defined(HAVE_BACKTRACE) && defined(ENABLE_BACKTRACES)
123137 assert(PrettyStackTraceHead == this &&
124138 "Pretty stack trace entry destruction is out of order");
125 PrettyStackTraceHead = getNextEntry();
139 PrettyStackTraceHead = NextEntry;
126140 #endif
127141 }
128142
153167 #endif
154168 }
155169
156 const void* llvm::SavePrettyStackState() {
170 const void *llvm::SavePrettyStackState() {
157171 #if defined(HAVE_BACKTRACE) && defined(ENABLE_BACKTRACES)
158172 return PrettyStackTraceHead;
159173 #else
161175 #endif
162176 }
163177
164 void llvm::RestorePrettyStackState(const void* Top) {
178 void llvm::RestorePrettyStackState(const void *Top) {
165179 #if defined(HAVE_BACKTRACE) && defined(ENABLE_BACKTRACES)
166 PrettyStackTraceHead = (const PrettyStackTraceEntry*)Top;
180 PrettyStackTraceHead = (PrettyStackTraceEntry*)Top;
167181 #endif
168182 }
169183