aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/main/java/com/google/devtools/build/lib/runtime/BugReport.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/com/google/devtools/build/lib/runtime/BugReport.java')
-rw-r--r--src/main/java/com/google/devtools/build/lib/runtime/BugReport.java55
1 files changed, 37 insertions, 18 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/runtime/BugReport.java b/src/main/java/com/google/devtools/build/lib/runtime/BugReport.java
index 40e869d7ae..938ba057c7 100644
--- a/src/main/java/com/google/devtools/build/lib/runtime/BugReport.java
+++ b/src/main/java/com/google/devtools/build/lib/runtime/BugReport.java
@@ -15,6 +15,7 @@ package com.google.devtools.build.lib.runtime;
import com.google.common.base.Joiner;
import com.google.common.collect.ImmutableList;
+import com.google.devtools.build.lib.Constants;
import com.google.devtools.build.lib.analysis.BlazeVersionInfo;
import com.google.devtools.build.lib.util.ExitCode;
import com.google.devtools.build.lib.util.LoggingUtil;
@@ -77,28 +78,46 @@ public abstract class BugReport {
/**
* Print and send a bug report, and exit with the proper Blaze code. Does not exit if called a
- * second time.
+ * second time. This method tries hard to catch any throwables thrown during its execution and
+ * halts the runtime in that case.
*/
public static void handleCrash(Throwable throwable, String... args) {
- if (alreadyHandlingCrash.compareAndSet(false, true)) {
- int exitCode = getExitCodeForThrowable(throwable);
- try {
- logCrash(throwable, args);
- if (runtime != null) {
- runtime.notifyCommandComplete(exitCode);
- // We don't call runtime#shutDown() here because all it does is shut down the modules, and
- // who knows if they can be trusted.
+ int exitCode = getExitCodeForThrowable(throwable);
+ try {
+ if (alreadyHandlingCrash.compareAndSet(false, true)) {
+ try {
+ logCrash(throwable, args);
+ if (runtime != null) {
+ runtime.notifyCommandComplete(exitCode);
+ // We don't call runtime#shutDown() here because all it does is shut down the modules,
+ // and who knows if they can be trusted.
+ }
+ } finally {
+ // Avoid shutdown deadlock issues: If an application shutdown hook crashes, it will
+ // trigger our Blaze crash handler (this method). Calling System#exit() here, would
+ // therefore induce a deadlock. This call would block on the shutdown sequence completing,
+ // but the shutdown sequence would in turn be blocked on this thread finishing. Instead,
+ // exit fast via halt().
+ Runtime.getRuntime().halt(exitCode);
}
- } finally {
- // Avoid shutdown deadlock issues: If an application shutdown hook crashes, it will trigger
- // our Blaze crash handler (this method). Calling System#exit() here, would therefore induce
- // a deadlock. This call would block on the shutdown sequence completing, but the shutdown
- // sequence would in turn be blocked on this thread finishing. Instead, exit fast via
- // halt().
- Runtime.getRuntime().halt(exitCode);
+ } else {
+ logCrash(throwable, args);
}
- } else {
- logCrash(throwable, args);
+ } catch (Throwable t) {
+ System.err.println(
+ "An crash occurred while "
+ + Constants.PRODUCT_NAME
+ + " was trying to handle a crash! Please file a bug against "
+ + Constants.PRODUCT_NAME
+ + " and include the information below.");
+
+ System.err.println("Original uncaught exception:");
+ throwable.printStackTrace(System.err);
+
+ System.err.println("Exception encountered during BugReport#handleCrash:");
+ t.printStackTrace(System.err);
+
+ Runtime.getRuntime().halt(exitCode);
}
}