Fix pnacl-sz to return with staus 0 in report_fatal_error.
Fixes pnacl-sz to return with exit status 0 in report_fatal_error, if
command line flag --exit-status is specified. The importance of this
is that it allows afl-fuzz to not report the mutation as a crash.
In addition, afl-fuzz doesn't record crash paths in its search
history. By returning success, afl-fuzz can continue to apply
additional mutations to the bad input. This allows afl-fuzz to add
errors that require multiple changes to occur on the input.
BUG=None
R=stichnot@chromium.org
Review URL: https://codereview.chromium.org/1382653002 .
diff --git a/src/IceCompileServer.cpp b/src/IceCompileServer.cpp
index db0694b..e2d7e38 100644
--- a/src/IceCompileServer.cpp
+++ b/src/IceCompileServer.cpp
@@ -93,6 +93,33 @@
return Val;
}
+// Reports fatal error message, and then exits with success status 0.
+void reportFatalErrorThenExitSuccess(void * UserData,
+ const std::string &Reason,
+ bool GenCrashDag) {
+ (void)UserData;
+ (void)GenCrashDag;
+
+ // Note: This code is (mostly) copied from llvm/lib/Support/ErrorHandling.cpp
+
+ // Blast the result out to stderr. We don't try hard to make sure this
+ // succeeds (e.g. handling EINTR) and we can't use errs() here because
+ // raw ostreams can call report_fatal_error.
+ llvm::SmallVector<char, 64> Buffer;
+ llvm::raw_svector_ostream OS(Buffer);
+ OS << "LLVM ERROR: " << Reason << "\n";
+ llvm::StringRef MessageStr = OS.str();
+ ssize_t written = ::write(2, MessageStr.data(), MessageStr.size());
+ (void)written; // If something went wrong, we deliberately just give up.
+
+ // If we reached here, we are failing ungracefully. Run the interrupt handlers
+ // to make sure any special cleanups get done, in particular that we remove
+ // files registered with RemoveFileOnSignal.
+ llvm::sys::RunInterruptHandlers();
+
+ exit(0);
+}
+
} // end of anonymous namespace
void CLCompileServer::run() {
@@ -105,6 +132,10 @@
ClFlags::getParsedClFlags(Flags);
ClFlags::getParsedClFlagsExtra(ExtraFlags);
+ // Override report_fatal_error if we want to exit with 0 status.
+ if (ExtraFlags.getAlwaysExitSuccess())
+ llvm::install_fatal_error_handler(reportFatalErrorThenExitSuccess, this);
+
std::error_code EC;
std::unique_ptr<Ostream> Ls = makeStream(ExtraFlags.getLogFilename(), EC);
if (EC) {