diff --git a/Android.bp b/Android.bp
index 3ace361..8078b69 100644
--- a/Android.bp
+++ b/Android.bp
@@ -1,3 +1,18 @@
+//
+// Copyright (C) 2021 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
 package {
     default_applicable_licenses: ["prebuilts_r8_license"],
 }
@@ -54,6 +69,19 @@
     static_libs: ["r8"],
 }
 
+java_binary_host {
+    name: "retrace",
+    main_class: "com.android.tools.r8.retrace.RetraceWrapper",
+    srcs: ["src/com/android/tools/r8/retrace/RetraceWrapper.java"],
+    static_libs: ["r8"],
+}
+
+java_binary_host {
+    name: "extractmarker",
+    main_class: "com.android.tools.r8.ExtractMarker",
+    static_libs: ["r8"],
+}
+
 java_import_host {
     name: "r8",
     jars: ["r8.jar"],
diff --git a/src/com/android/tools/r8/retrace/RetraceWrapper.java b/src/com/android/tools/r8/retrace/RetraceWrapper.java
new file mode 100644
index 0000000..034dcdb
--- /dev/null
+++ b/src/com/android/tools/r8/retrace/RetraceWrapper.java
@@ -0,0 +1,739 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.tools.r8.retrace;
+
+import com.android.tools.r8.Diagnostic;
+import com.android.tools.r8.DiagnosticsHandler;
+import com.android.tools.r8.references.ClassReference;
+import com.android.tools.r8.references.Reference;
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.net.URISyntaxException;
+import java.nio.file.FileVisitResult;
+import java.nio.file.FileVisitor;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.nio.file.StandardOpenOption;
+import java.nio.file.attribute.BasicFileAttributes;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.OptionalInt;
+import java.util.function.BiConsumer;
+import java.util.stream.Stream;
+
+public class RetraceWrapper {
+
+  /** Default paths to search for mapping files. */
+  private static final List<String> AOSP_MAP_SEARCH_PATHS =
+      Collections.singletonList("out/target/common/obj/APPS");
+
+  private static final String USAGE =
+      String.join(
+          System.lineSeparator(),
+          "Usage: retrace [<option>]* [<file>]",
+          "where <file> is the file to retrace (default stdin)",
+          "  and <option> is one of:",
+          "  --default-map <file>     # Default map to retrace lines that don't auto-identify.",
+          "  --map-search-path <path> # Path to search for mappings that support auto-identify.",
+          "                           # Separate <path> entries by colon ':'.",
+          "                           # Default '" + String.join(":", AOSP_MAP_SEARCH_PATHS) + "'.",
+          "  --print-map-table        # Print the table of identified mapping files and exit.",
+          "  -h, --help               # Print this message.");
+
+  private static class ForwardingDiagnosticsHander implements DiagnosticsHandler {
+    @Override
+    public void error(Diagnostic error) {
+      throw RetraceWrapper.error(error.getDiagnosticMessage());
+    }
+
+    @Override
+    public void warning(Diagnostic warning) {
+      RetraceWrapper.warning(warning.getDiagnosticMessage());
+    }
+
+    @Override
+    public void info(Diagnostic info) {
+      RetraceWrapper.info(info.getDiagnosticMessage());
+    }
+  }
+
+  private static class LazyRetracer {
+    final MapInfo mapInfo;
+    final Path mapPath;
+
+    private Retracer lazyRetracer = null;
+
+    public LazyRetracer(MapInfo mapInfo, Path mapPath) {
+      this.mapInfo = mapInfo;
+      this.mapPath = mapPath;
+    }
+
+    public Retracer getRetracer() {
+      if (lazyRetracer == null) {
+        try {
+          lazyRetracer =
+              Retracer.createDefault(
+                  ProguardMapProducer.fromPath(mapPath), new ForwardingDiagnosticsHander());
+        } catch (InvalidMappingFileException e) {
+          throw new RuntimeException("Failure in mapping file: " + mapPath, e);
+        }
+      }
+      return lazyRetracer;
+    }
+  }
+
+  private static class MapInfo {
+    final String id;
+    final String hash;
+
+    public MapInfo(String id, String hash) {
+      assert id != null;
+      assert hash != null;
+      this.id = id;
+      this.hash = hash;
+    }
+
+    @Override
+    public boolean equals(Object other) {
+      if (this == other) {
+        return true;
+      }
+      if (other == null || getClass() != other.getClass()) {
+        return false;
+      }
+      MapInfo otherMapInfo = (MapInfo) other;
+      return Objects.equals(id, otherMapInfo.id) && Objects.equals(hash, otherMapInfo.hash);
+    }
+
+    @Override
+    public int hashCode() {
+      return Objects.hash(id, hash);
+    }
+
+    @Override
+    public String toString() {
+      return "MapInfo{" + "id='" + id + '\'' + ", hash='" + hash + '\'' + '}';
+    }
+  }
+
+  /** Representation of a line with a hole, ala "<prefix><hole><suffix>". */
+  private static class LineWithHole {
+    final String line;
+    final int start;
+    final int end;
+
+    public LineWithHole(String line, int start, int end) {
+      this.line = line;
+      this.start = start;
+      this.end = end;
+    }
+
+    public String plug(String string) {
+      return line.substring(0, start) + string + line.substring(end);
+    }
+  }
+
+  /** Parsed exception header line, such as "Caused by: <exception>". */
+  private static class ExceptionLine extends LineWithHole {
+    final ClassReference exception;
+
+    public ExceptionLine(String line, int start, int end, ClassReference exception) {
+      super(line, start, end);
+      this.exception = exception;
+    }
+  }
+
+  /** Parsed frame line, such as "at <class>.<method>(<source-file>:<line>)". */
+  private static class FrameLine extends LineWithHole {
+    final ClassReference clazz;
+    final String methodName;
+    final String sourceFile;
+    final OptionalInt lineNumber;
+
+    public FrameLine(
+        String line,
+        int start,
+        int end,
+        ClassReference clazz,
+        String methodName,
+        String sourceFile,
+        OptionalInt lineNumber) {
+      super(line, start, end);
+      this.clazz = clazz;
+      this.methodName = methodName;
+      this.sourceFile = sourceFile;
+      this.lineNumber = lineNumber;
+    }
+  }
+
+  /** An immutable linked list of the result lines so that a result tree can be created. */
+  private static class ResultNode {
+    final ResultNode parent;
+    final String line;
+
+    public ResultNode(ResultNode parent, String line) {
+      this.parent = parent;
+      this.line = line;
+    }
+
+    public void print() {
+      if (parent != null) {
+        parent.print();
+      }
+      System.out.println(line);
+    }
+  }
+
+  /**
+   * Indication that a line is the start of an escaping stack trace.
+   *
+   * <p>Note that this does not identify an exception that is directly printed with, e.g.,
+   * Throwable.printStackTrace(), but only one that exits the runtime. That should generally catch
+   * what we need, but could be refined to match ':' which is the only other indicator.
+   */
+  private static final String ESCAPING_EXCEPTION_MARKER = "Exception in thread \"";
+
+  /** Indication that a line is the start of a "caused by" stack trace. */
+  private static final String CAUSED_BY_EXCEPTION_MARKER = "Caused by: ";
+
+  /** Indication that a line is the start of a "suppressed" stack trace. */
+  private static final String SUPPRESSED_EXCEPTION_MARKER = "Suppressed: ";
+
+  /** Start of the source file for any R8 build withing AOSP. */
+  // TODO(zerny): Should this be a configurable prefix?
+  private static final String AOSP_SF_MARKER = "go/retraceme ";
+
+  /** Start of the source file for any R8 compiler build. */
+  private static final String R8_SF_MARKER = "R8_";
+
+  /** Mapping file header indicating the id of mapping file. */
+  private static final String MAP_ID_HEADER_MARKER = "# pg_map_id: ";
+
+  /** Mapping file header indicating the hash of mapping file. */
+  private static final String MAP_HASH_HEADER_MARKER = "# pg_map_hash: SHA-256 ";
+
+  /** Map of cached/lazy retracer instances for maps found in the local AOSP build. */
+  private static final Map<String, LazyRetracer> RETRACERS = new HashMap<>();
+
+  private static final List<String> PENDING_MESSAGES = new ArrayList<>();
+
+  private static void flushPendingMessages() {
+    PENDING_MESSAGES.forEach(System.err::println);
+  }
+
+  private static void info(String message) {
+    PENDING_MESSAGES.add("Info: " + message);
+  }
+
+  private static void warning(String message) {
+    PENDING_MESSAGES.add("Warning: " + message);
+  }
+
+  private static RuntimeException error(String message) {
+    flushPendingMessages();
+    throw new RuntimeException(message);
+  }
+
+  private static MapInfo readMapHeaderInfo(Path path) throws IOException {
+    String mapId = null;
+    String mapHash = null;
+    try (BufferedReader reader = Files.newBufferedReader(path)) {
+      while (true) {
+        String line = reader.readLine();
+        if (line == null || !line.startsWith("#")) {
+          break;
+        }
+        if (mapId == null) {
+          mapId = tryParseMapIdHeader(line);
+        }
+        if (mapHash == null) {
+          mapHash = tryParseMapHashHeader(line);
+        }
+      }
+    }
+    if (mapId != null && mapHash != null) {
+      return new MapInfo(mapId, mapHash);
+    }
+    return null;
+  }
+
+  private static Path getProjectRoot() throws URISyntaxException {
+    // The retrace.jar should be located in out/[soong/]host/<platform>/framework/retrace.jar
+    Path hostPath = Paths.get("out", "host");
+    Path hostSoongPath = Paths.get("out", "soong");
+    Path retraceJarPath =
+        Paths.get(RetraceWrapper.class.getProtectionDomain().getCodeSource().getLocation().toURI());
+    for (Path current = retraceJarPath; current != null; current = current.getParent()) {
+      if (current.endsWith(hostPath) || current.endsWith(hostSoongPath)) {
+        return current.getParent().getParent();
+      }
+    }
+    info(
+        "Unable to determine the project root based on the retrace.jar location: "
+            + retraceJarPath);
+    return null;
+  }
+
+  private static LazyRetracer getRetracerForAosp(String sourceFile) {
+    MapInfo stackLineInfo = tryParseSourceFileMarkerForAosp(sourceFile);
+    return stackLineInfo == null ? null : RETRACERS.get(stackLineInfo.id);
+  }
+
+  private static LazyRetracer getRetracerForR8(String sourceFile) {
+    MapInfo stackLineInfo = tryParseSourceFileMarkerForR8(sourceFile);
+    if (stackLineInfo == null) {
+      return null;
+    }
+    LazyRetracer retracer = RETRACERS.get(stackLineInfo.id);
+    if (retracer == null) {
+      // TODO(zerny): Lookup the mapping file in the R8 cloud storage bucket.
+      info("Could not identify a mapping file for lines with R8 tag: " + stackLineInfo);
+    }
+    return retracer;
+  }
+
+  private static String tryParseMapIdHeader(String line) {
+    return tryParseMapHeaderLine(line, MAP_ID_HEADER_MARKER);
+  }
+
+  private static String tryParseMapHashHeader(String line) {
+    return tryParseMapHeaderLine(line, MAP_HASH_HEADER_MARKER);
+  }
+
+  private static String tryParseMapHeaderLine(String line, String headerMarker) {
+    if (line.startsWith(headerMarker)) {
+      return line.substring(headerMarker.length());
+    }
+    return null;
+  }
+
+  private static FrameLine tryParseFrameLine(String line) {
+    String atMarker = "at ";
+    int atIndex = line.indexOf(atMarker);
+    if (atIndex < 0) {
+      return null;
+    }
+    int parenStartIndex = line.indexOf('(', atIndex);
+    if (parenStartIndex < 0) {
+      return null;
+    }
+    int parenEndIndex = line.indexOf(')', parenStartIndex);
+    if (parenEndIndex < 0) {
+      return null;
+    }
+    int classAndMethodSeperatorIndex = line.lastIndexOf('.', parenStartIndex);
+    if (classAndMethodSeperatorIndex < 0) {
+      return null;
+    }
+    int classStartIndex = atIndex + atMarker.length();
+    String clazz = line.substring(classStartIndex, classAndMethodSeperatorIndex);
+    String method = line.substring(classAndMethodSeperatorIndex + 1, parenStartIndex);
+    // Source file and line may or may not be present.
+    int sourceAndLineSeperatorIndex = line.lastIndexOf(':', parenEndIndex);
+    String sourceFile;
+    OptionalInt lineNumber;
+    if (parenStartIndex < sourceAndLineSeperatorIndex) {
+      sourceFile = line.substring(parenStartIndex + 1, sourceAndLineSeperatorIndex);
+      try {
+        lineNumber =
+            OptionalInt.of(
+                Integer.parseInt(line.substring(sourceAndLineSeperatorIndex + 1, parenEndIndex)));
+      } catch (NumberFormatException e) {
+        lineNumber = OptionalInt.empty();
+      }
+    } else {
+      sourceFile = line.substring(parenStartIndex + 1, parenEndIndex);
+      lineNumber = OptionalInt.empty();
+    }
+    return new FrameLine(
+        line,
+        classStartIndex,
+        parenEndIndex + 1,
+        Reference.classFromTypeName(clazz),
+        method,
+        sourceFile,
+        lineNumber);
+  }
+
+  private static int indexOfExceptionStart(String line) {
+    int i = line.indexOf(ESCAPING_EXCEPTION_MARKER);
+    if (i >= 0) {
+      int start = line.indexOf("\" ", i + ESCAPING_EXCEPTION_MARKER.length());
+      if (start > 0) {
+        return start;
+      }
+    }
+    i = line.indexOf(CAUSED_BY_EXCEPTION_MARKER);
+    if (i >= 0) {
+      return i + CAUSED_BY_EXCEPTION_MARKER.length();
+    }
+    i = line.indexOf(SUPPRESSED_EXCEPTION_MARKER);
+    if (i >= 0) {
+      return i + SUPPRESSED_EXCEPTION_MARKER.length();
+    }
+    return -1;
+  }
+
+  private static ExceptionLine tryParseExceptionLine(String line) {
+    int start = indexOfExceptionStart(line);
+    if (start < 0) {
+      return null;
+    }
+    int end = line.indexOf(':', start);
+    if (end < 0) {
+      return null;
+    }
+    String exception = line.substring(start, end);
+    return new ExceptionLine(line, start, end, Reference.classFromTypeName(exception));
+  }
+
+  private static MapInfo tryParseSourceFileMarkerForAosp(String sourceFile) {
+    if (!sourceFile.startsWith(AOSP_SF_MARKER)) {
+      return null;
+    }
+    int hashStart = AOSP_SF_MARKER.length();
+    String mapHash = sourceFile.substring(hashStart);
+    // Currently, app builds use the map-hash as the build id.
+    return new MapInfo(mapHash, mapHash);
+  }
+
+  private static MapInfo tryParseSourceFileMarkerForR8(String sourceFile) {
+    if (!sourceFile.startsWith(R8_SF_MARKER)) {
+      return null;
+    }
+    int versionStart = R8_SF_MARKER.length();
+    int mapHashStart = sourceFile.indexOf('_', versionStart) + 1;
+    if (mapHashStart <= 0) {
+      return null;
+    }
+    String version = sourceFile.substring(versionStart, mapHashStart - 1);
+    String mapHash = sourceFile.substring(mapHashStart);
+    return new MapInfo(version, mapHash);
+  }
+
+  private static void printIdentityStackTrace(ExceptionLine exceptionLine, List<FrameLine> frames) {
+    if (exceptionLine != null) {
+      System.out.println(exceptionLine.line);
+    }
+    frames.forEach(frame -> System.out.println(frame.line));
+  }
+
+  private static void retrace(InputStream stream, LazyRetracer defaultRetracer) throws Exception {
+    BufferedReader reader = new BufferedReader(new InputStreamReader(stream));
+    String currentLine = reader.readLine();
+    List<FrameLine> frames = new ArrayList<>();
+    while (currentLine != null) {
+      ExceptionLine exceptionLine = tryParseExceptionLine(currentLine);
+      if (exceptionLine != null) {
+        currentLine = reader.readLine();
+        if (currentLine == null) {
+          // Reached end-of-file and we can't retrace the exception. Flush and exit.
+          printIdentityStackTrace(exceptionLine, Collections.emptyList());
+          return;
+        }
+      }
+      FrameLine topFrameLine = tryParseFrameLine(currentLine);
+      if (topFrameLine == null) {
+        // The line is not a frame so we can't retrace it. Flush and continue on the next line.
+        printIdentityStackTrace(exceptionLine, Collections.emptyList());
+        System.out.println(currentLine);
+        currentLine = reader.readLine();
+        continue;
+      }
+      // Collect all subsequent lines with the same source file info.
+      FrameLine frame = topFrameLine;
+      while (frame != null) {
+        if (!frame.sourceFile.equals(topFrameLine.sourceFile)) {
+          break;
+        }
+        frames.add(frame);
+        currentLine = reader.readLine();
+        frame = currentLine == null ? null : tryParseFrameLine(currentLine);
+      }
+      retraceStackTrace(defaultRetracer, exceptionLine, frames);
+      frames.clear();
+    }
+  }
+
+  private static LazyRetracer determineRetracer(String sourceFile, LazyRetracer defaultRetracer)
+      throws Exception {
+    LazyRetracer lazyRetracer = getRetracerForR8(sourceFile);
+    if (lazyRetracer != null) {
+      return lazyRetracer;
+    }
+    lazyRetracer = getRetracerForAosp(sourceFile);
+    if (lazyRetracer != null) {
+      return lazyRetracer;
+    }
+    return defaultRetracer;
+  }
+
+  private static void retraceStackTrace(
+      LazyRetracer defaultRetracer, ExceptionLine exceptionLine, List<FrameLine> frames)
+      throws Exception {
+    String sourceFile = frames.get(0).sourceFile;
+    LazyRetracer lazyRetracer = determineRetracer(sourceFile, defaultRetracer);
+    if (lazyRetracer == null) {
+      printIdentityStackTrace(exceptionLine, frames);
+      return;
+    }
+    Retracer retracer = lazyRetracer.getRetracer();
+    List<ResultNode> finalResultNodes = new ArrayList<>();
+    retraceOptionalExceptionLine(
+        retracer,
+        exceptionLine,
+        (context, parentResult) ->
+            retraceFrameRecursive(retracer, context, parentResult, 0, frames)
+                .forEach(finalResultNodes::add));
+
+    if (finalResultNodes.size() > 1) {
+      System.out.println(
+          "Printing "
+              + finalResultNodes.size()
+              + " ambiguous stacks separated by <OR>.\n"
+              + "If this is unexpected, please file a bug on R8 and attach the "
+              + "content of the raw stack trace and the mapping file: "
+              + lazyRetracer.mapPath
+              + "\nPublic tracker at https://issuetracker.google.com/issues/new?component=326788");
+    }
+    for (int i = 0; i < finalResultNodes.size(); i++) {
+      if (i > 0) {
+        System.out.println("<OR>");
+      }
+      ResultNode node = finalResultNodes.get(i);
+      node.print();
+    }
+  }
+
+  private static void retraceOptionalExceptionLine(
+      Retracer retracer,
+      ExceptionLine exceptionLine,
+      BiConsumer<RetraceStackTraceContext, ResultNode> resultCallback) {
+    // This initial result node parent is 'null', i.e., no parent.
+    ResultNode initialResultNode = null;
+    if (exceptionLine == null) {
+      // If no exception line is given, retracing starts in the empty context.
+      resultCallback.accept(RetraceStackTraceContext.empty(), initialResultNode);
+      return;
+    }
+    // If an exception line is given the result is possibly a forrest, so each individual result
+    // has a null parent.
+    retracer
+        .retraceThrownException(exceptionLine.exception)
+        .forEach(
+            element ->
+                resultCallback.accept(
+                    element.getContext(),
+                    new ResultNode(
+                        initialResultNode,
+                        exceptionLine.plug(element.getRetracedClass().getTypeName()))));
+  }
+
+  private static Stream<ResultNode> retraceFrameRecursive(
+      Retracer retracer,
+      RetraceStackTraceContext context,
+      ResultNode parentResult,
+      int frameIndex,
+      List<FrameLine> frames) {
+    if (frameIndex >= frames.size()) {
+      return Stream.of(parentResult);
+    }
+
+    // Helper to link up frame results when iterating via a closure callback.
+    class ResultLinker {
+      ResultNode current;
+
+      public ResultLinker(ResultNode current) {
+        this.current = current;
+      }
+
+      public void link(String nextResult) {
+        current = new ResultNode(current, nextResult);
+      }
+    }
+
+    FrameLine frameLine = frames.get(frameIndex);
+    return retracer
+        .retraceFrame(context, frameLine.lineNumber, frameLine.clazz, frameLine.methodName)
+        .flatMap(
+            frameElement -> {
+              // Create a linking helper to amend the result when iterating the frames.
+              ResultLinker linker = new ResultLinker(parentResult);
+              frameElement.forEachRewritten(
+                  frame -> {
+                    RetracedMethodReference method = frame.getMethodReference();
+                    RetracedClassReference holder = method.getHolderClass();
+                    int origPos = method.getOriginalPositionOrDefault(-1);
+                    linker.link(
+                        frameLine.plug(
+                            holder.getTypeName()
+                                + "."
+                                + method.getMethodName()
+                                + "("
+                                + frame.getSourceFile().getOrInferSourceFile()
+                                + (origPos >= 0 ? (":" + origPos) : "")
+                                + ")"));
+                  });
+              return retraceFrameRecursive(
+                  retracer,
+                  frameElement.getRetraceStackTraceContext(),
+                  linker.current,
+                  frameIndex + 1,
+                  frames);
+            });
+  }
+
+  private static void populateMappingFileMap(List<String> searchPaths) throws Exception {
+    Path projectRoot = getProjectRoot();
+    if (projectRoot == null) {
+      return;
+    }
+    Path prebuiltR8MapPath = projectRoot.resolve("prebuilts").resolve("r8").resolve("r8.jar.map");
+    MapInfo prebuiltR8MapInfo = readMapHeaderInfo(prebuiltR8MapPath);
+    if (prebuiltR8MapInfo == null) {
+      info("Unable to read expected prebuilt R8 map in " + prebuiltR8MapPath);
+    } else {
+      RETRACERS.put(prebuiltR8MapInfo.id, new LazyRetracer(prebuiltR8MapInfo, prebuiltR8MapPath));
+    }
+    for (String path : searchPaths) {
+      Path resolvedPath = projectRoot.resolve(Paths.get(path));
+      if (Files.notExists(resolvedPath)) {
+        error("Invalid search path entry: " + resolvedPath);
+      }
+      Files.walkFileTree(
+          resolvedPath,
+          new FileVisitor<Path>() {
+
+            final Path mapFileName = Paths.get("proguard_dictionary");
+
+            @Override
+            public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) {
+              return FileVisitResult.CONTINUE;
+            }
+
+            @Override
+            public FileVisitResult visitFile(Path file, BasicFileAttributes attrs)
+                throws IOException {
+              if (file.endsWith(mapFileName)) {
+                MapInfo mapInfo = readMapHeaderInfo(file);
+                if (mapInfo != null) {
+                  RETRACERS.put(mapInfo.id, new LazyRetracer(mapInfo, file));
+                }
+              }
+              return FileVisitResult.CONTINUE;
+            }
+
+            @Override
+            public FileVisitResult visitFileFailed(Path file, IOException exc) {
+              return FileVisitResult.CONTINUE;
+            }
+
+            @Override
+            public FileVisitResult postVisitDirectory(Path dir, IOException exc) {
+              return FileVisitResult.CONTINUE;
+            }
+          });
+    }
+  }
+
+  public static void main(String[] args) throws Exception {
+    String stackTraceFile = null;
+    String defaultMapArg = null;
+    boolean printMappingFileTable = false;
+    List<String> searchPaths = AOSP_MAP_SEARCH_PATHS;
+    for (int i = 0; i < args.length; i++) {
+      String arg = args[i];
+      if (arg.equals("-h") || arg.equals("--help")) {
+        System.out.println(USAGE);
+        return;
+      }
+      if (arg.equals("--default-map")) {
+        i++;
+        if (i == args.length) {
+          throw error("No argument given for --default-map");
+        }
+        defaultMapArg = args[i];
+      } else if (arg.equals("--map-search-path")) {
+        i++;
+        if (i == args.length) {
+          throw error("No argument given for --map-search-path");
+        }
+        searchPaths = parseSearchPath(args[i]);
+      } else if (arg.equals("--print-map-table")) {
+        printMappingFileTable = true;
+      } else if (arg.startsWith("-")) {
+        throw error("Unknown option: " + arg);
+      } else if (stackTraceFile != null) {
+        throw error("At most one input file is supported.");
+      } else {
+        stackTraceFile = arg;
+      }
+    }
+
+    LazyRetracer defaultRetracer = null;
+    if (defaultMapArg != null) {
+      defaultRetracer = new LazyRetracer(null, Paths.get(defaultMapArg));
+    }
+
+    populateMappingFileMap(searchPaths);
+    if (printMappingFileTable) {
+      List<String> keys = new ArrayList<>(RETRACERS.keySet());
+      keys.sort(String::compareTo);
+      for (String key : keys) {
+        LazyRetracer retracer = RETRACERS.get(key);
+        System.out.println(key + " -> " + retracer.mapPath);
+      }
+      return;
+    }
+
+    if (stackTraceFile == null) {
+      retrace(System.in, defaultRetracer);
+    } else {
+      Path path = Paths.get(stackTraceFile);
+      if (!Files.exists(path)) {
+        throw error("Input file does not exist: " + stackTraceFile);
+      }
+      try (InputStream stream = Files.newInputStream(path, StandardOpenOption.READ)) {
+        retrace(stream, defaultRetracer);
+      }
+    }
+    flushPendingMessages();
+  }
+
+  private static List<String> parseSearchPath(String paths) {
+    int length = paths.length();
+    List<String> result = new ArrayList<>();
+    int start = 0;
+    do {
+      int split = paths.indexOf(':', start);
+      int end = split != -1 ? split : length;
+      String path = paths.substring(start, end).strip();
+      if (!path.isEmpty()) {
+        result.add(path);
+      }
+      start = end + 1;
+    } while (start < length);
+    return result;
+  }
+}
diff --git a/tests/Android.bp b/tests/Android.bp
new file mode 100644
index 0000000..b1270eb
--- /dev/null
+++ b/tests/Android.bp
@@ -0,0 +1,76 @@
+//
+// Copyright (C) 2021 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Integration test for the R8 retracing tool.
+
+// The retracing tool is a developer tool and part of the build tools.
+// The following tests are structured so that the app and retrace tool
+// are invoked exactly as a normal build would. The check that they
+// produce the correct result is then postponed to a test so that a
+// retrace tool failure will not result in a build failure.
+
+// Rule to dexdump the content of a sample app.
+// The dexdump is used to simulate a raw stack trace from the app.
+genrule {
+    name: "r8retrace-dexdump-sample-app",
+    out: ["dexdump.txt"],
+    srcs: [":HelloActivityWithR8"],
+    tools: ["dexdump", "extractmarker"],
+    cmd: "$(location extractmarker) $(in) > $(out)"
+        + " && $(location dexdump) -d $(in) >> $(out)",
+}
+
+// Tool and rule to create the raw stack trace from a dexdump.
+java_binary_host {
+    name: "r8retrace-create-stacktrace-tool",
+    main_class: "com.android.tools.r8.CreateStacktraceFromDexDumpTool",
+    srcs: ["src/com/android/tools/r8/CreateStacktraceFromDexDumpTool.java"],
+}
+
+genrule {
+    name: "r8retrace-create-stacktrace",
+    out: ["stacktrace.txt"],
+    srcs: [":r8retrace-dexdump-sample-app"],
+    tools: ["r8retrace-create-stacktrace-tool"],
+    cmd: "$(location r8retrace-create-stacktrace-tool) $(in) $(out)",
+}
+
+// Run retrace on the stack trace to produce a retraced stack trace.
+genrule {
+    name: "r8retrace-run-retrace",
+    out: ["retraced-stacktrace.txt"],
+    srcs: [":r8retrace-create-stacktrace", ":HelloActivityWithR8{.proguard_map}"],
+    tools: ["retrace"],
+    cmd: "$(location retrace)"
+        + " --map-search-path $(location :HelloActivityWithR8{.proguard_map})"
+        + " $(location :r8retrace-create-stacktrace)"
+        + " > $(out)",
+}
+
+// Test checks that the raw and retraced stack traces are as expected.
+// All the output files are added as resources here so that, in case of failure, their content
+// can be included in the error message.
+java_test_host {
+    name: "r8retrace-check-retraced-stacktrace",
+    test_suites: ["general-tests"],
+    srcs: ["src/com/android/tools/r8/CheckRetracedStacktraceTest.java"],
+    static_libs: ["junit"],
+    java_resources: [
+        ":r8retrace-dexdump-sample-app",
+        ":HelloActivityWithR8{.proguard_map}",
+        ":r8retrace-create-stacktrace",
+        ":r8retrace-run-retrace",
+    ],
+}
diff --git a/tests/samples/HelloActivityWithR8/Android.bp b/tests/samples/HelloActivityWithR8/Android.bp
new file mode 100644
index 0000000..74887d0
--- /dev/null
+++ b/tests/samples/HelloActivityWithR8/Android.bp
@@ -0,0 +1,35 @@
+//
+// Copyright (C) 2021 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+android_app {
+    name: "HelloActivityWithR8",
+    srcs: ["src/**/*.java"],
+    sdk_version: "current",
+    dex_preopt: {
+        enabled: false,
+    },
+    optimize: {
+        enabled: true,
+        shrink: true,
+        optimize: true,
+        obfuscate: true,
+        proguard_compatibility: false,
+        proguard_flags_files: ["proguard.config"]
+    }
+}
diff --git a/tests/samples/HelloActivityWithR8/AndroidManifest.xml b/tests/samples/HelloActivityWithR8/AndroidManifest.xml
new file mode 100644
index 0000000..ef2e5ae
--- /dev/null
+++ b/tests/samples/HelloActivityWithR8/AndroidManifest.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2021 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<!-- Declare the contents of this Android application.  The namespace
+     attribute brings in the Android platform namespace, and the package
+     supplies a unique name for the application.  When writing your
+     own application, the package name must be changed from "com.example.*"
+     to come from a domain that you own or have control over. -->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.example.android.helloactivitywithr8">
+    <application android:label="Hello, Activity With R8!">
+        <activity android:name="HelloActivityWithR8"
+                android:exported="true">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN"/>
+                <category android:name="android.intent.category.LAUNCHER"/>
+            </intent-filter>
+        </activity>
+    </application>
+</manifest>
diff --git a/tests/samples/HelloActivityWithR8/proguard.config b/tests/samples/HelloActivityWithR8/proguard.config
new file mode 100644
index 0000000..e61169d
--- /dev/null
+++ b/tests/samples/HelloActivityWithR8/proguard.config
@@ -0,0 +1 @@
+-keepattributes LineNumberTable
diff --git a/tests/samples/HelloActivityWithR8/res/layout/hello_activity.xml b/tests/samples/HelloActivityWithR8/res/layout/hello_activity.xml
new file mode 100644
index 0000000..fa6a434
--- /dev/null
+++ b/tests/samples/HelloActivityWithR8/res/layout/hello_activity.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2021 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<EditText xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/text"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:textSize="18sp"
+    android:autoText="true"
+    android:capitalize="sentences"
+    android:text="@string/hello_activity_text_text" />
+
diff --git a/tests/samples/HelloActivityWithR8/res/values/strings.xml b/tests/samples/HelloActivityWithR8/res/values/strings.xml
new file mode 100644
index 0000000..6be1a65
--- /dev/null
+++ b/tests/samples/HelloActivityWithR8/res/values/strings.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2021 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<resources>
+
+    <string name="hello_activity_text_text">Hello, World!</string>
+
+</resources>
diff --git a/tests/samples/HelloActivityWithR8/src/com/example/android/helloactivitywithr8/HelloActivityWithR8.java b/tests/samples/HelloActivityWithR8/src/com/example/android/helloactivitywithr8/HelloActivityWithR8.java
new file mode 100644
index 0000000..f2f097c
--- /dev/null
+++ b/tests/samples/HelloActivityWithR8/src/com/example/android/helloactivitywithr8/HelloActivityWithR8.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.helloactivitywithr8;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.view.View;
+
+/**
+ * A simple application compiled with R8.
+ *
+ * <p>Adapted from development/samples/HelloActivity.
+ */
+public class HelloActivityWithR8 extends Activity {
+
+  /** Getter method that will be inlined by R8. */
+  private View getView() {
+    return getLayoutInflater().inflate(R.layout.hello_activity, null);
+  }
+
+  @Override
+  public void onCreate(Bundle savedInstanceState) {
+    super.onCreate(savedInstanceState);
+    View view = getView();
+    setContentView(view);
+  }
+}
diff --git a/tests/src/com/android/tools/r8/CheckRetracedStacktraceTest.java b/tests/src/com/android/tools/r8/CheckRetracedStacktraceTest.java
new file mode 100644
index 0000000..8c692da
--- /dev/null
+++ b/tests/src/com/android/tools/r8/CheckRetracedStacktraceTest.java
@@ -0,0 +1,110 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.tools.r8;
+
+import java.io.BufferedReader;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.nio.charset.StandardCharsets;
+import java.util.List;
+import java.util.stream.Collectors;
+import org.junit.Assert;
+import org.junit.Test;
+
+public class CheckRetracedStacktraceTest {
+
+  private static final String FRAME_PREFIX =
+      "    at com.example.android.helloactivitywithr8.HelloActivityWithR8.";
+
+  private List<String> getResourceLines(String resource) throws Exception {
+    try (InputStream is = getClass().getResourceAsStream(resource)) {
+      return new BufferedReader(new InputStreamReader(is, StandardCharsets.UTF_8))
+          .lines()
+          .collect(Collectors.toList());
+    }
+  }
+
+  private String onErrorDebugInfo() throws Exception {
+    StringBuilder builder = new StringBuilder("\nAdditional debug info:\n");
+    appendResourceContent(builder, "dexdump.txt");
+    appendResourceContent(builder, "proguard_dictionary");
+    appendResourceContent(builder, "stacktrace.txt");
+    appendResourceContent(builder, "retraced-stacktrace.txt");
+    return builder.toString();
+  }
+
+  private void appendResourceContent(StringBuilder builder, String resource) throws Exception {
+    builder.append("==== ").append(resource).append('\n');
+    getResourceLines("/" + resource).forEach(l -> builder.append(l).append('\n'));
+  }
+
+  @Test
+  public void checkRawStacktrace() throws Exception {
+    String errorInfo = onErrorDebugInfo();
+
+    List<String> lines = getResourceLines("/stacktrace.txt");
+    // In release builds a single frame is present, in debug builds two.
+    Assert.assertTrue(errorInfo, 1 < lines.size() && lines.size() <= 3);
+    Assert.assertEquals(errorInfo, "java.lang.RuntimeException: error", lines.get(0));
+    // The frame lines "at line" is the qualified method and we don't check build hash
+    // and PC to allow minor changes to the test app and compiler without breaking this test.
+    for (int i = 1; i < lines.size(); i++) {
+      String frameLine = lines.get(i);
+      int sourceFileStart = frameLine.indexOf('(');
+      int lineNumberSeparator = frameLine.indexOf(':');
+      int lineNumberEnd = frameLine.lastIndexOf(')');
+      int hashInfoSeparator = frameLine.lastIndexOf(' ', lineNumberSeparator);
+      Assert.assertTrue(errorInfo, frameLine.startsWith(FRAME_PREFIX));
+      Assert.assertEquals(
+          errorInfo, "(go/retraceme", frameLine.substring(sourceFileStart, hashInfoSeparator));
+      String lineNumberString = frameLine.substring(lineNumberSeparator + 1, lineNumberEnd);
+      try {
+        int lineNumber = Integer.parseInt(lineNumberString);
+      } catch (NumberFormatException e) {
+        Assert.fail("Invalid line number: " + lineNumberString + errorInfo);
+      }
+    }
+  }
+
+  @Test
+  public void checkRetracedStacktrace() throws Exception {
+    String errorInfo = onErrorDebugInfo();
+
+    // Prefix is the qualified class on each line, suffix does not check line numbers to
+    // allow minor changes to the test app without breaking this test.
+    String suffix = "(HelloActivityWithR8.java";
+
+    List<String> lines = getResourceLines("/retraced-stacktrace.txt");
+    int expectedLines = 3;
+    Assert.assertEquals(
+        "Expected "
+            + expectedLines
+            + " lines, got: \n=====\n"
+            + String.join("\n", lines)
+            + "\n====="
+            + errorInfo,
+        expectedLines,
+        lines.size());
+    Assert.assertEquals(errorInfo, "java.lang.RuntimeException: error", lines.get(0));
+    String line1 = lines.get(1);
+    Assert.assertEquals(
+        errorInfo, FRAME_PREFIX + "getView" + suffix, line1.substring(0, line1.indexOf(':')));
+    String line2 = lines.get(2);
+    Assert.assertEquals(
+        errorInfo, FRAME_PREFIX + "onCreate" + suffix, line2.substring(0, line2.indexOf(':')));
+  }
+}
diff --git a/tests/src/com/android/tools/r8/CreateStacktraceFromDexDumpTool.java b/tests/src/com/android/tools/r8/CreateStacktraceFromDexDumpTool.java
new file mode 100644
index 0000000..abfbb35
--- /dev/null
+++ b/tests/src/com/android/tools/r8/CreateStacktraceFromDexDumpTool.java
@@ -0,0 +1,191 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.tools.r8;
+
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.nio.file.StandardOpenOption;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.function.Predicate;
+
+public class CreateStacktraceFromDexDumpTool {
+
+  private static final String CLASS = "com.example.android.helloactivitywithr8.HelloActivityWithR8";
+  private static final String SOURCE_FILE_IDX = "source_file_idx";
+  private static final String INVOKE_VIRTUAL = ": invoke-virtual";
+  private static final String INVOKE_DIRECT = ": invoke-direct";
+  private static final String METHOD_ON_CREATE = "onCreate";
+  private static final String METHOD_GET_VIEW = "getView";
+  private static final String METHOD_GET_LAYOUT_INFLATER = "getLayoutInflater";
+  private static final String R8_MARKER_PREFIX = "~~R8{";
+
+  private final List<String> inputLines;
+  private final List<String> outputLines = new ArrayList<>();
+  private final String sourceFile;
+
+  private CreateStacktraceFromDexDumpTool(List<String> lines) {
+    this.inputLines = lines;
+    sourceFile = getSourceFile(lines);
+    outputLines.add("java.lang.RuntimeException: error");
+  }
+
+  // Find the source file line.
+  private static String getSourceFile(List<String> lines) {
+    for (String line : lines) {
+      if (line.contains(SOURCE_FILE_IDX)) {
+        // Read <source-file> from line:
+        //   source_file_idx   : <idx> (<source-file>)
+        int start = line.indexOf('(');
+        if (start > 0) {
+          int end = line.indexOf(')', start);
+          if (end > 0) {
+            return line.substring(start + 1, end);
+          }
+        }
+      }
+    }
+    return "NoSourceFile";
+  }
+
+  private static String skipUntil(Iterator<String> iterator, Predicate<String> fn) {
+    while (iterator.hasNext()) {
+      String next = iterator.next();
+      if (fn.test(next)) {
+        return next;
+      }
+    }
+    return null;
+  }
+
+  private static String skipUntilInMethod(Iterator<String> iterator, Predicate<String> fn) {
+    String line = skipUntil(iterator, fn.or(l -> isMethodHeader(l)));
+    return line == null || isMethodHeader(line) ? null : line;
+  }
+
+  private static boolean isMethodHeader(String line) {
+    return line.endsWith("'") && line.contains("name");
+  }
+
+  private boolean isDebug() {
+    String marker = skipUntil(inputLines.iterator(), l -> l.startsWith(R8_MARKER_PREFIX));
+    return marker != null && marker.contains("debug");
+  }
+
+  private static String mapPcInLineNumberTable(
+      Iterator<String> iterator, int invokePcValue, String invokePcString) {
+    Map<Integer, String> lineTable = new HashMap<>();
+    String lineTableEntry;
+    do {
+      lineTableEntry = skipUntilInMethod(iterator, line -> line.contains(" line="));
+      if (lineTableEntry != null) {
+        // Read a line table mapping entry:
+        // 0x<addr> line=<linenumber>
+        String stripped = lineTableEntry.strip();
+        int split = stripped.indexOf(" line=");
+        if (split > 0 && stripped.startsWith("0x")) {
+          try {
+            int pc = Integer.parseInt(stripped.substring(2, split), 16);
+            lineTable.put(pc, stripped.substring(split + " line=".length()));
+          } catch (NumberFormatException e) {
+            return "InvalidLineTablePc";
+          }
+        }
+      }
+    } while (lineTableEntry != null);
+    // If there is no line number table return the PC as the line.
+    if (lineTable.isEmpty()) {
+      return invokePcString;
+    }
+    String lineNumber = lineTable.get(invokePcValue);
+    if (lineNumber != null) {
+      return lineNumber;
+    }
+    return "PcNotInLineNumberTable";
+  }
+
+  private void addLineFor(String methodName, String invokeType, String invokedMethod) {
+    Iterator<String> iterator = inputLines.iterator();
+    // Find the method entry.
+    if (skipUntil(iterator, line -> line.endsWith("'" + methodName + "'") && isMethodHeader(line))
+        == null) {
+      outputLines.add("MethodNotFound: " + methodName);
+      return;
+    }
+    // Find the code section.
+    if (skipUntilInMethod(iterator, line -> line.contains("insns size")) == null) {
+      outputLines.add("InstructionsNotFound: " + methodName);
+      return;
+    }
+    // Find the invoke instruction.
+    String invokeLine =
+        skipUntilInMethod(
+            iterator, line -> line.contains(invokeType) && line.contains(invokedMethod));
+    if (invokeLine == null) {
+      outputLines.add(
+          "InvokeNotFound: " + methodName + " calling " + invokeType + " " + invokedMethod);
+      return;
+    }
+    String invokePcString = "NoPcInfo";
+    int invokePcValue = -1;
+    // Read <pc> from line:
+    // <addr>: <bytes> |<pc>: <invoke-type> {vX}, <type-desc>.<method-name>:<method-desc>;
+    int end = invokeLine.indexOf(invokeType);
+    if (end > 0) {
+      int start = invokeLine.lastIndexOf('|', end);
+      if (start > 0) {
+        String pcString = invokeLine.substring(start + 1, end);
+        try {
+          int pc = Integer.parseInt(pcString, 16);
+          invokePcValue = pc;
+          invokePcString = "" + pc;
+        } catch (NumberFormatException e) {
+          invokePcString = "PcParseError";
+        }
+      }
+    }
+    String lineNumber = mapPcInLineNumberTable(iterator, invokePcValue, invokePcString);
+    outputLines.add(
+        String.format("    at %s.%s(%s:%s)", CLASS, methodName, sourceFile, lineNumber));
+  }
+
+  public static void main(String[] args) throws Exception {
+    Path dexdumpPath = Paths.get(args[0]);
+    Path outputPath = Paths.get(args[1]);
+    List<String> inputLines = Files.readAllLines(dexdumpPath);
+    CreateStacktraceFromDexDumpTool tool = new CreateStacktraceFromDexDumpTool(inputLines);
+    if (tool.isDebug()) {
+      // In debug builds onCreate calls getView which calls getLayoutInflater.
+      tool.addLineFor(METHOD_GET_VIEW, INVOKE_VIRTUAL, METHOD_GET_LAYOUT_INFLATER);
+      tool.addLineFor(METHOD_ON_CREATE, INVOKE_DIRECT, METHOD_GET_VIEW);
+    } else {
+      // In release builds getView is inlined away.
+      tool.addLineFor(METHOD_ON_CREATE, INVOKE_VIRTUAL, METHOD_GET_LAYOUT_INFLATER);
+    }
+    Files.write(
+        outputPath,
+        tool.outputLines,
+        StandardCharsets.UTF_8,
+        StandardOpenOption.CREATE,
+        StandardOpenOption.TRUNCATE_EXISTING);
+  }
+}
