[llvm] eb9ba24 - [StandardInstrumentations] Add option to dump IR to a file on crash
Arthur Eubanks via llvm-commits
llvm-commits at lists.llvm.org
Thu May 25 09:18:15 PDT 2023
Author: Arthur Eubanks
Date: 2023-05-25T09:18:01-07:00
New Revision: eb9ba243722454c186134fc83449ce69906603ae
URL: https://github.com/llvm/llvm-project/commit/eb9ba243722454c186134fc83449ce69906603ae
DIFF: https://github.com/llvm/llvm-project/commit/eb9ba243722454c186134fc83449ce69906603ae.diff
LOG: [StandardInstrumentations] Add option to dump IR to a file on crash
We already have -print-on-crash which dumps the IR to stderr on a crash, but it's more useful to dump to a file.
Introduce -print-on-crash-path to dump the IR to a file.
Making -print-on-crash a string option is confusing if you only pass -print-on-crash and it swallows up the next command line arg, which is why this is a new option.
Perhaps we could retire the dump to stderr version if people don't use it, but not sure how much people find that useful.
Reviewed By: jamieschmeiser
Differential Revision: https://reviews.llvm.org/D151170
Added:
Modified:
llvm/lib/Passes/StandardInstrumentations.cpp
llvm/test/Other/print-on-crash.ll
Removed:
################################################################################
diff --git a/llvm/lib/Passes/StandardInstrumentations.cpp b/llvm/lib/Passes/StandardInstrumentations.cpp
index 646711426bbfc..b47dd4118031d 100644
--- a/llvm/lib/Passes/StandardInstrumentations.cpp
+++ b/llvm/lib/Passes/StandardInstrumentations.cpp
@@ -96,11 +96,16 @@ static cl::opt<std::string> DotCfgDir(
cl::desc("Generate dot files into specified directory for changed IRs"),
cl::Hidden, cl::init("./"));
-// An option to print the IR that was being processed when a pass crashes.
-static cl::opt<bool>
- PrintCrashIR("print-on-crash",
- cl::desc("Print the last form of the IR before crash"),
- cl::Hidden);
+// Options to print the IR that was being processed when a pass crashes.
+static cl::opt<std::string> PrintOnCrashPath(
+ "print-on-crash-path",
+ cl::desc("Print the last form of the IR before crash to a file"),
+ cl::Hidden);
+
+static cl::opt<bool> PrintOnCrash(
+ "print-on-crash",
+ cl::desc("Print the last form of the IR before crash (use -print-on-crash-path to dump to a file)"),
+ cl::Hidden);
static cl::opt<std::string> OptBisectPrintIRPath(
"opt-bisect-print-ir-path",
@@ -2186,7 +2191,17 @@ StandardInstrumentations::StandardInstrumentations(
PrintCrashIRInstrumentation *PrintCrashIRInstrumentation::CrashReporter =
nullptr;
-void PrintCrashIRInstrumentation::reportCrashIR() { dbgs() << SavedIR; }
+void PrintCrashIRInstrumentation::reportCrashIR() {
+ if (!PrintOnCrashPath.empty()) {
+ std::error_code EC;
+ raw_fd_ostream Out(PrintOnCrashPath, EC);
+ if (EC)
+ report_fatal_error(errorCodeToError(EC));
+ Out << SavedIR;
+ } else {
+ dbgs() << SavedIR;
+ }
+}
void PrintCrashIRInstrumentation::SignalHandler(void *) {
// Called by signal handlers so do not lock here
@@ -2194,7 +2209,8 @@ void PrintCrashIRInstrumentation::SignalHandler(void *) {
if (!CrashReporter)
return;
- assert(PrintCrashIR && "Did not expect to get here without option set.");
+ assert((PrintOnCrash || !PrintOnCrashPath.empty()) &&
+ "Did not expect to get here without option set.");
CrashReporter->reportCrashIR();
}
@@ -2202,31 +2218,32 @@ PrintCrashIRInstrumentation::~PrintCrashIRInstrumentation() {
if (!CrashReporter)
return;
- assert(PrintCrashIR && "Did not expect to get here without option set.");
+ assert((PrintOnCrash || !PrintOnCrashPath.empty()) &&
+ "Did not expect to get here without option set.");
CrashReporter = nullptr;
}
void PrintCrashIRInstrumentation::registerCallbacks(
PassInstrumentationCallbacks &PIC) {
- if (!PrintCrashIR || CrashReporter)
+ if ((!PrintOnCrash && PrintOnCrashPath.empty()) || CrashReporter)
return;
sys::AddSignalHandler(SignalHandler, nullptr);
CrashReporter = this;
- PIC.registerBeforeNonSkippedPassCallback([&PIC, this](StringRef PassID,
- Any IR) {
- SavedIR.clear();
- raw_string_ostream OS(SavedIR);
- OS << formatv("*** Dump of {0}IR Before Last Pass {1}",
- llvm::forcePrintModuleIR() ? "Module " : "", PassID);
- if (!isInteresting(IR, PassID, PIC.getPassNameForClassName(PassID))) {
- OS << " Filtered Out ***\n";
- return;
- }
- OS << " Started ***\n";
- unwrapAndPrint(OS, IR);
- });
+ PIC.registerBeforeNonSkippedPassCallback(
+ [&PIC, this](StringRef PassID, Any IR) {
+ SavedIR.clear();
+ raw_string_ostream OS(SavedIR);
+ OS << formatv("*** Dump of {0}IR Before Last Pass {1}",
+ llvm::forcePrintModuleIR() ? "Module " : "", PassID);
+ if (!isInteresting(IR, PassID, PIC.getPassNameForClassName(PassID))) {
+ OS << " Filtered Out ***\n";
+ return;
+ }
+ OS << " Started ***\n";
+ unwrapAndPrint(OS, IR);
+ });
}
void StandardInstrumentations::registerCallbacks(
diff --git a/llvm/test/Other/print-on-crash.ll b/llvm/test/Other/print-on-crash.ll
index d590566430d8b..f9bf8f039c1db 100644
--- a/llvm/test/Other/print-on-crash.ll
+++ b/llvm/test/Other/print-on-crash.ll
@@ -3,10 +3,13 @@
; RUN: not --crash opt -print-on-crash -passes=trigger-crash < %s 2>&1 | FileCheck %s --check-prefix=CHECK_SIMPLE
+; RUN: not --crash opt -print-on-crash-path=%t -passes=trigger-crash < %s
+; RUN: FileCheck %s --check-prefix=CHECK_SIMPLE --input-file=%t
+
; A test that the signal handler set by the hidden option -print-on-crash
; is not called when no pass crashes.
-; RUN: opt -print-on-crash -passes="default<O2>" < %s 2>&1 | FileCheck %s --check-prefix=CHECK_NO_CRASH
+; RUN: opt -disable-output -print-on-crash -passes="default<O2>" < %s 2>&1 | FileCheck %s --check-prefix=CHECK_NO_CRASH --allow-empty
; RUN: not --crash opt -print-on-crash -print-module-scope -passes=trigger-crash < %s 2>&1 | FileCheck %s --check-prefix=CHECK_MODULE
More information about the llvm-commits
mailing list