diff options
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.java | 55 |
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); } } |