]> granicus.if.org Git - clang/commitdiff
Driver: Include the driver arguments in crash reports
authorJustin Bogner <mail@justinbogner.com>
Thu, 9 Jul 2015 06:58:31 +0000 (06:58 +0000)
committerJustin Bogner <mail@justinbogner.com>
Thu, 9 Jul 2015 06:58:31 +0000 (06:58 +0000)
Similarly to r231989, the driver arguments can be quite helpful in
diagnosing a crash.

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

include/clang/Driver/Job.h
lib/Driver/Driver.cpp
lib/Driver/Job.cpp
test/Driver/crash-report-modules.m
test/Driver/crash-report.c

index 8fc2e8d3a5b901441a81381fa73a8b37077ec446..186244bacf317f4307943419c6b2191331377bd2 100644 (file)
@@ -106,6 +106,9 @@ public:
   const char *getExecutable() const { return Executable; }
 
   const llvm::opt::ArgStringList &getArguments() const { return Arguments; }
+
+  /// Print a command argument, and optionally quote it.
+  static void printArg(llvm::raw_ostream &OS, const char *Arg, bool Quote);
 };
 
 /// Like Command, but with a fallback which is executed in case
index 1914a33c0c8fff76bba1fa661db42e014eb79b2e..4edca261661cf7e000a18af5e4a245dbb47d7420 100644 (file)
@@ -398,6 +398,19 @@ Compilation *Driver::BuildCompilation(ArrayRef<const char *> ArgList) {
   return C;
 }
 
+static void printArgList(raw_ostream &OS, const llvm::opt::ArgList &Args) {
+  llvm::opt::ArgStringList ASL;
+  for (const auto *A : Args)
+    A->render(Args, ASL);
+
+  for (auto I = ASL.begin(), E = ASL.end(); I != E; ++I) {
+    if (I != ASL.begin())
+      OS << ' ';
+    Command::printArg(OS, *I, true);
+  }
+  OS << '\n';
+}
+
 // When clang crashes, produce diagnostic information including the fully
 // preprocessed source file(s).  Request that the developer attach the
 // diagnostic information to a bug report.
@@ -546,7 +559,9 @@ void Driver::generateCompilationDiagnostics(Compilation &C,
         << "Error generating run script: " + Script + " " + EC.message();
   } else {
     ScriptOS << "# Crash reproducer for " << getClangFullVersion() << "\n"
-             << "# Original command: ";
+             << "# Driver args: ";
+    printArgList(ScriptOS, C.getInputArgs());
+    ScriptOS << "# Original command: ";
     Cmd.Print(ScriptOS, "\n", /*Quote=*/true);
     Cmd.Print(ScriptOS, "\n", /*Quote=*/true, &CrashInfo);
     Diag(clang::diag::note_drv_command_failed_diag_msg) << Script;
index ac18e1eb56a17c5e44d5eece731ef7bacd413e86..42bba56f5d417e764661555ffd3b848b3b0d4a82 100644 (file)
@@ -71,7 +71,7 @@ static int skipArgs(const char *Flag, bool HaveCrashVFS) {
   return 0;
 }
 
-static void PrintArg(raw_ostream &OS, const char *Arg, bool Quote) {
+void Command::printArg(raw_ostream &OS, const char *Arg, bool Quote) {
   const bool Escape = std::strpbrk(Arg, "\"\\$");
 
   if (!Quote && !Escape) {
@@ -146,7 +146,7 @@ void Command::Print(raw_ostream &OS, const char *Terminator, bool Quote,
                     CrashReportInfo *CrashInfo) const {
   // Always quote the exe.
   OS << ' ';
-  PrintArg(OS, Executable, /*Quote=*/true);
+  printArg(OS, Executable, /*Quote=*/true);
 
   llvm::ArrayRef<const char *> Args = Arguments;
   llvm::SmallVector<const char *, 128> ArgsRespFile;
@@ -175,20 +175,20 @@ void Command::Print(raw_ostream &OS, const char *Terminator, bool Quote,
         // Replace the input file name with the crashinfo's file name.
         OS << ' ';
         StringRef ShortName = llvm::sys::path::filename(CrashInfo->Filename);
-        PrintArg(OS, ShortName.str().c_str(), Quote);
+        printArg(OS, ShortName.str().c_str(), Quote);
         continue;
       }
     }
 
     OS << ' ';
-    PrintArg(OS, Arg, Quote);
+    printArg(OS, Arg, Quote);
   }
 
   if (CrashInfo && HaveCrashVFS) {
     OS << ' ';
-    PrintArg(OS, "-ivfsoverlay", Quote);
+    printArg(OS, "-ivfsoverlay", Quote);
     OS << ' ';
-    PrintArg(OS, CrashInfo->VFSPath.str().c_str(), Quote);
+    printArg(OS, CrashInfo->VFSPath.str().c_str(), Quote);
   }
 
   if (ResponseFile != nullptr) {
index 66ebaa750ddca710ae1604dceeea28bfb69be9f4..0e1d81a1f34093aab4933260e757995e3f9537ec 100644 (file)
@@ -26,6 +26,8 @@ const int x = MODULE_MACRO;
 // CHECKSRC: const int x = 10;
 
 // CHECKSH: # Crash reproducer
+// CHECKSH-NEXT: # Driver args: "-fsyntax-only"
+// CHECKSH-SAME: "-D" "FOO=BAR"
 // CHECKSH-NEXT: # Original command: {{.*$}}
 // CHECKSH-NEXT: "-cc1"
 // CHECKSH: "-isysroot" "/tmp/"
index 5caad79f192bd7cb946454bb898dc3db147063f0..2ff5b44f5e5294cd41fb75428cea19de03e6d94c 100644 (file)
@@ -5,7 +5,7 @@
 // RUN:  -iprefix /the/prefix -iwithprefix /tmp -iwithprefixbefore /tmp/ \
 // RUN:  -Xclang -internal-isystem -Xclang /tmp/                         \
 // RUN:  -Xclang -internal-externc-isystem -Xclang /tmp/                 \
-// RUN:  -DFOO=BAR 2>&1 | FileCheck %s
+// RUN:  -DFOO=BAR -DBAR="BAZ QUX" 2>&1 | FileCheck %s
 // RUN: cat %t/crash-report-*.c | FileCheck --check-prefix=CHECKSRC %s
 // RUN: cat %t/crash-report-*.sh | FileCheck --check-prefix=CHECKSH %s
 // REQUIRES: crash-recovery
 FOO
 // CHECKSRC: FOO
 // CHECKSH: # Crash reproducer
+// CHECKSH-NEXT: # Driver args: "-fsyntax-only"
+// CHECKSH-SAME: "-D" "FOO=BAR"
+// CHECKSH-SAME: "-D" "BAR=BAZ QUX"
 // CHECKSH-NEXT: # Original command: {{.*$}}
 // CHECKSH-NEXT: "-cc1"
 // CHECKSH: "-main-file-name" "crash-report.c"
 // CHECKSH: "-D" "FOO=BAR"
+// CHECKSH: "-D" "BAR=BAZ QUX"
 // CHECKSH-NOT: "-F/tmp/"
 // CHECKSH-NOT: "-I" "/tmp/"
 // CHECKSH-NOT: "-idirafter" "/tmp/"