[Retrace] Add fake stack entry with version to retrace exceptions
Bug: 171478943
Change-Id: I5c1ce93408da575976cc400cc2e4ae28e72faf22
diff --git a/src/main/java/com/android/tools/r8/retrace/Retrace.java b/src/main/java/com/android/tools/r8/retrace/Retrace.java
index bd537a6..90c1cca 100644
--- a/src/main/java/com/android/tools/r8/retrace/Retrace.java
+++ b/src/main/java/com/android/tools/r8/retrace/Retrace.java
@@ -5,6 +5,7 @@
package com.android.tools.r8.retrace;
import static com.android.tools.r8.utils.ExceptionUtils.STATUS_ERROR;
+import static com.android.tools.r8.utils.ExceptionUtils.failWithFakeEntry;
import com.android.tools.r8.Diagnostic;
import com.android.tools.r8.DiagnosticsHandler;
@@ -234,7 +235,7 @@
}
}
- public static void run(String[] args) {
+ public static void run(String[] args) throws RetraceFailedException {
// To be compatible with standard retrace and remapper, we translate -arg into --arg.
String[] mappedArgs = new String[args.length];
boolean printInfo = false;
@@ -255,14 +256,23 @@
}
RetraceDiagnosticsHandler retraceDiagnosticsHandler =
new RetraceDiagnosticsHandler(new DiagnosticsHandler() {}, printInfo);
- Builder builder = parseArguments(mappedArgs, retraceDiagnosticsHandler);
+ try {
+ run(mappedArgs, retraceDiagnosticsHandler);
+ } catch (Throwable t) {
+ throw failWithFakeEntry(
+ retraceDiagnosticsHandler, t, RetraceFailedException::new, RetraceAbortException.class);
+ }
+ }
+
+ private static void run(String[] args, DiagnosticsHandler diagnosticsHandler) {
+ Builder builder = parseArguments(args, diagnosticsHandler);
if (builder == null) {
// --help or --version was an argument to list
- if (Arrays.asList(mappedArgs).contains("--version")) {
+ if (Arrays.asList(args).contains("--version")) {
System.out.println("Retrace " + Version.getVersionString());
return;
}
- assert Arrays.asList(mappedArgs).contains("--help");
+ assert Arrays.asList(args).contains("--help");
System.out.println("Retrace " + Version.getVersionString());
System.out.print(USAGE_MESSAGE);
return;
@@ -274,7 +284,7 @@
printStream.println(line);
}
} catch (UnsupportedEncodingException e) {
- retraceDiagnosticsHandler.error(new StringDiagnostic(e.getMessage()));
+ diagnosticsHandler.error(new StringDiagnostic(e.getMessage()));
}
});
run(builder.build());
@@ -302,21 +312,20 @@
}
private interface MainAction {
- void run() throws RetraceAbortException;
+ void run() throws RetraceFailedException;
}
private static void withMainProgramHandler(MainAction action) {
try {
action.run();
- } catch (RetraceAbortException e) {
+ } catch (RetraceFailedException | RetraceAbortException e) {
// Detail of the errors were already reported
- System.err.println(StringUtils.LINE_SEPARATOR + USAGE_MESSAGE + StringUtils.LINE_SEPARATOR);
+ System.err.println("Retrace failed");
System.exit(STATUS_ERROR);
- } catch (RuntimeException e) {
+ throw null;
+ } catch (Throwable t) {
System.err.println("Retrace failed with an internal error.");
- System.err.println(StringUtils.LINE_SEPARATOR + USAGE_MESSAGE + StringUtils.LINE_SEPARATOR);
- Throwable cause = e.getCause() == null ? e : e.getCause();
- cause.printStackTrace();
+ t.printStackTrace();
System.exit(STATUS_ERROR);
}
}
diff --git a/src/main/java/com/android/tools/r8/retrace/RetraceFailedException.java b/src/main/java/com/android/tools/r8/retrace/RetraceFailedException.java
new file mode 100644
index 0000000..94b61ee
--- /dev/null
+++ b/src/main/java/com/android/tools/r8/retrace/RetraceFailedException.java
@@ -0,0 +1,23 @@
+// Copyright (c) 2020, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+package com.android.tools.r8.retrace;
+
+import com.android.tools.r8.Keep;
+
+/**
+ * Exception thrown when retrace failed to complete because of errors previously reported through
+ * {@link com.android.tools.r8.DiagnosticsHandler}.
+ */
+@Keep
+public class RetraceFailedException extends Exception {
+
+ public RetraceFailedException() {
+ super("Retrace failed to complete");
+ }
+
+ public RetraceFailedException(String message, Throwable cause) {
+ super(message, cause);
+ }
+}
diff --git a/src/main/java/com/android/tools/r8/utils/ExceptionUtils.java b/src/main/java/com/android/tools/r8/utils/ExceptionUtils.java
index 32ca59a..61aa232 100644
--- a/src/main/java/com/android/tools/r8/utils/ExceptionUtils.java
+++ b/src/main/java/com/android/tools/r8/utils/ExceptionUtils.java
@@ -19,6 +19,7 @@
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutionException;
+import java.util.function.BiFunction;
import java.util.function.Consumer;
import java.util.function.Supplier;
@@ -76,6 +77,15 @@
private static CompilationFailedException failCompilation(
Reporter reporter, Throwable topMostException) {
+ return failWithFakeEntry(
+ reporter, topMostException, CompilationFailedException::new, AbortException.class);
+ }
+
+ public static <T extends Exception, A extends Exception> T failWithFakeEntry(
+ DiagnosticsHandler diagnosticsHandler,
+ Throwable topMostException,
+ BiFunction<String, Throwable, T> newException,
+ Class<A> abortException) {
// Find inner-most cause of the failure and compute origin, position and reported for the path.
boolean hasBeenReported = false;
Origin origin = Origin.unknown();
@@ -83,7 +93,7 @@
List<Throwable> suppressed = new ArrayList<>();
Throwable innerMostCause = topMostException;
while (true) {
- hasBeenReported |= innerMostCause instanceof AbortException;
+ hasBeenReported |= abortException.isAssignableFrom(innerMostCause.getClass());
Origin nextOrigin = getOrigin(innerMostCause);
if (nextOrigin != Origin.unknown()) {
origin = nextOrigin;
@@ -105,7 +115,7 @@
// If no abort is seen, the exception is not reported, so report it now.
if (!hasBeenReported) {
- reporter.error(new ExceptionDiagnostic(innerMostCause, origin, position));
+ diagnosticsHandler.error(new ExceptionDiagnostic(innerMostCause, origin, position));
}
// Build the top-level compiler exception and version stack.
@@ -117,8 +127,7 @@
message.append(", origin: ").append(origin);
}
// Create the final exception object.
- CompilationFailedException rethrow =
- new CompilationFailedException(message.toString(), innerMostCause);
+ T rethrow = newException.apply(message.toString(), innerMostCause);
// Replace its stack by the cause stack and insert version info at the top.
String filename = "Version_" + Version.LABEL + ".java";
StackTraceElement versionElement =