]> granicus.if.org Git - clang/commitdiff
Try harder to be signal-safe inside our signal handler. The most prominent behavioural
authorNick Lewycky <nicholas@mxc.ca>
Mon, 25 Mar 2013 21:24:30 +0000 (21:24 +0000)
committerNick Lewycky <nicholas@mxc.ca>
Mon, 25 Mar 2013 21:24:30 +0000 (21:24 +0000)
difference is that we no longer clean the token before emitting it. This fixes a bug where
clang hangs in the middle of crashing because the crash handler calls malloc from inside
a crash that happened inside of free.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@177919 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Parse/ParseAST.cpp
test/Parser/crash-report.c [new file with mode: 0644]

index 5e769c56916fec14e8d19b81a76ae8eed935a742..7cd8a21ac451b667bd183966513753c23f9bacbf 100644 (file)
@@ -55,10 +55,21 @@ void PrettyStackTraceParserEntry::print(raw_ostream &OS) const {
 
   const Preprocessor &PP = P.getPreprocessor();
   Tok.getLocation().print(OS, PP.getSourceManager());
-  if (Tok.isAnnotation())
-    OS << ": at annotation token \n";
-  else
-    OS << ": current parser token '" << PP.getSpelling(Tok) << "'\n";
+  if (Tok.isAnnotation()) {
+    OS << ": at annotation token\n";
+  } else {
+    // Do the equivalent of PP.getSpelling(Tok) except for the parts that would
+    // allocate memory.
+    bool Invalid = false;
+    const SourceManager &SM = P.getPreprocessor().getSourceManager();
+    unsigned Length = Tok.getLength();
+    const char *Spelling = SM.getCharacterData(Tok.getLocation(), &Invalid);
+    if (Invalid) {
+      OS << ": unknown current parser token\n";
+      return;
+    }
+    OS << ": current parser token '" << StringRef(Spelling, Length) << "'\n";
+  }
 }
 
 }  // namespace
diff --git a/test/Parser/crash-report.c b/test/Parser/crash-report.c
new file mode 100644 (file)
index 0000000..42481aa
--- /dev/null
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 %s 2>&1 | FileCheck %s
+// REQUIRES: crash-recovery
+
+#prag\
+ma clang __debug crash
+
+// CHECK: prag\
+// CHECK-NEXT: ma
+