[Retrace] Add support for partitioning without metadata
Bug: b/201666766
Bug: b/211603371
Change-Id: Ib20df2c8120ba4a4dbfe64d3c51437b113fd2609
diff --git a/src/main/java/com/android/tools/r8/naming/MapVersion.java b/src/main/java/com/android/tools/r8/naming/MapVersion.java
index a23196c..ae93504 100644
--- a/src/main/java/com/android/tools/r8/naming/MapVersion.java
+++ b/src/main/java/com/android/tools/r8/naming/MapVersion.java
@@ -3,8 +3,10 @@
// BSD-style license that can be found in the LICENSE file.
package com.android.tools.r8.naming;
+import com.android.tools.r8.Keep;
import com.android.tools.r8.utils.structural.Ordered;
+@Keep
public enum MapVersion implements Ordered<MapVersion> {
MAP_VERSION_NONE("none"),
MAP_VERSION_1_0("1.0"),
diff --git a/src/main/java/com/android/tools/r8/retrace/MappingPartitionFromKeySupplier.java b/src/main/java/com/android/tools/r8/retrace/MappingPartitionFromKeySupplier.java
new file mode 100644
index 0000000..9b8c0a1
--- /dev/null
+++ b/src/main/java/com/android/tools/r8/retrace/MappingPartitionFromKeySupplier.java
@@ -0,0 +1,20 @@
+// Copyright (c) 2022, 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;
+
+/***
+ * Supplier to provide the bytes for a partition specified by a key. Retrace guarantee that the
+ * supplier is always called after a call with the key to {@link RegisterMappingPartitionCallback}
+ * and a call to {@link PrepareMappingPartitionsCallback}
+ *
+ */
+@FunctionalInterface
+@Keep
+public interface MappingPartitionFromKeySupplier {
+
+ byte[] get(String key);
+}
diff --git a/src/main/java/com/android/tools/r8/retrace/PartitionMappingSupplier.java b/src/main/java/com/android/tools/r8/retrace/PartitionMappingSupplier.java
index cec8467..d56aee5 100644
--- a/src/main/java/com/android/tools/r8/retrace/PartitionMappingSupplier.java
+++ b/src/main/java/com/android/tools/r8/retrace/PartitionMappingSupplier.java
@@ -5,20 +5,56 @@
package com.android.tools.r8.retrace;
import com.android.tools.r8.Keep;
+import com.android.tools.r8.naming.MapVersion;
import com.android.tools.r8.retrace.internal.PartitionMappingSupplierBuilderImpl;
-import java.util.function.Consumer;
-import java.util.function.Function;
@Keep
public abstract class PartitionMappingSupplier extends MappingSupplier<PartitionMappingSupplier> {
public static Builder builder() {
- return new PartitionMappingSupplierBuilderImpl();
+ return new PartitionMappingSupplierBuilderImpl(MapVersion.MAP_VERSION_NONE);
+ }
+
+ public static NoMetadataBuilder<?> noMetadataBuilder(MapVersion mapVersion) {
+ return new PartitionMappingSupplierBuilderImpl(mapVersion);
}
@Keep
- public abstract static class Builder
- extends MappingSupplierBuilder<PartitionMappingSupplier, Builder> {
+ public abstract static class NoMetadataBuilder<B extends NoMetadataBuilder<B>>
+ extends MappingSupplierBuilder<PartitionMappingSupplier, B> {
+
+ /***
+ * Callback to be notified of a partition that is later going to be needed. When all needed
+ * partitions are found the callback specified to {@code setPrepareMappingPartitionsCallback} is
+ * called.
+ *
+ * @param registerPartitionCallback the consumer to get keys for partitions.
+ */
+ public abstract Builder setRegisterMappingPartitionCallback(
+ RegisterMappingPartitionCallback registerPartitionCallback);
+
+ /***
+ * A callback notifying that all partitions should be prepared. The prepare callback is
+ * guaranteed to be called prior to any calls to the partition supplier.
+ *
+ * @param prepare the callback to listen for when partitions should be prepared.
+ */
+ public abstract Builder setPrepareMappingPartitionsCallback(
+ PrepareMappingPartitionsCallback prepare);
+
+ /***
+ * Set the partition supplier that is needed for retracing. All partitions needed has been
+ * declared earlier and this should block until the bytes associated with the partition is
+ * ready.
+ *
+ * @param partitionSupplier the function to return a partition to retrace
+ */
+ public abstract Builder setMappingPartitionFromKeySupplier(
+ MappingPartitionFromKeySupplier partitionSupplier);
+ }
+
+ @Keep
+ public abstract static class Builder extends NoMetadataBuilder<Builder> {
/***
* Sets the serialized metadata that was obtained when partitioning.
@@ -26,30 +62,5 @@
* @param metadata the serialized metadata
*/
public abstract Builder setMetadata(byte[] metadata);
-
- /***
- * Callback to be notified of a partition that is later going to be needed. When all needed
- * partitions has been found, the callback specified to {@code setPrepareNewPartitions} will
- * be called.
- *
- * @param partitionToFetchConsumer the consumer to get keys for partitions.
- */
- public abstract Builder setPartitionToFetchConsumer(Consumer<String> partitionToFetchConsumer);
-
- /***
- * A callback notifying that all partitions should be prepared.
- *
- * @param run the callback to listen for when partitions should be prepared.
- */
- public abstract Builder setPrepareNewPartitions(Runnable run);
-
- /***
- * Set the partition supplier that is needed for retracing. All partitions needed has been
- * declared earlier and this should block until the bytes associated with the partition is
- * ready.
- *
- * @param supplier the function to return a partition to retrace
- */
- public abstract Builder setPartitionSupplier(Function<String, byte[]> supplier);
}
}
diff --git a/src/main/java/com/android/tools/r8/retrace/PrepareMappingPartitionsCallback.java b/src/main/java/com/android/tools/r8/retrace/PrepareMappingPartitionsCallback.java
new file mode 100644
index 0000000..b19babd
--- /dev/null
+++ b/src/main/java/com/android/tools/r8/retrace/PrepareMappingPartitionsCallback.java
@@ -0,0 +1,19 @@
+// Copyright (c) 2022, 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;
+
+/***
+ * Callback to be called to prepare all partitions registered by
+ * {@link RegisterMappingPartitionCallback}. This is guaranteed to be called before calling
+ * {@link MappingPartitionFromKeySupplier}.
+ */
+@FunctionalInterface
+@Keep
+public interface PrepareMappingPartitionsCallback {
+
+ void prepare();
+}
diff --git a/src/main/java/com/android/tools/r8/retrace/RegisterMappingPartitionCallback.java b/src/main/java/com/android/tools/r8/retrace/RegisterMappingPartitionCallback.java
new file mode 100644
index 0000000..df5c943
--- /dev/null
+++ b/src/main/java/com/android/tools/r8/retrace/RegisterMappingPartitionCallback.java
@@ -0,0 +1,17 @@
+// Copyright (c) 2022, 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;
+
+/***
+ * Interface for registering a mapping partition to be used later.
+ */
+@FunctionalInterface
+@Keep
+public interface RegisterMappingPartitionCallback {
+
+ void register(String key);
+}
diff --git a/src/main/java/com/android/tools/r8/retrace/internal/PartitionMappingSupplierBuilderImpl.java b/src/main/java/com/android/tools/r8/retrace/internal/PartitionMappingSupplierBuilderImpl.java
index f100f97..2f69645 100644
--- a/src/main/java/com/android/tools/r8/retrace/internal/PartitionMappingSupplierBuilderImpl.java
+++ b/src/main/java/com/android/tools/r8/retrace/internal/PartitionMappingSupplierBuilderImpl.java
@@ -4,19 +4,25 @@
package com.android.tools.r8.retrace.internal;
+import com.android.tools.r8.naming.MapVersion;
+import com.android.tools.r8.retrace.MappingPartitionFromKeySupplier;
import com.android.tools.r8.retrace.PartitionMappingSupplier;
-import com.android.tools.r8.utils.ConsumerUtils;
-import java.util.function.Consumer;
-import java.util.function.Function;
+import com.android.tools.r8.retrace.PrepareMappingPartitionsCallback;
+import com.android.tools.r8.retrace.RegisterMappingPartitionCallback;
public class PartitionMappingSupplierBuilderImpl extends PartitionMappingSupplier.Builder {
- private Function<String, byte[]> partitionSupplier;
- private Consumer<String> partitionToFetchConsumer = ConsumerUtils.emptyConsumer();
- private Runnable prepare = () -> {};
+ private MappingPartitionFromKeySupplier partitionSupplier;
+ private RegisterMappingPartitionCallback registerPartitionCallback = key -> {};
+ private PrepareMappingPartitionsCallback prepare = () -> {};
private byte[] metadata;
+ private final MapVersion fallbackMapVersion;
private boolean allowExperimental = false;
+ public PartitionMappingSupplierBuilderImpl(MapVersion fallbackMapVersion) {
+ this.fallbackMapVersion = fallbackMapVersion;
+ }
+
@Override
public PartitionMappingSupplier.Builder self() {
return this;
@@ -35,28 +41,38 @@
}
@Override
- public PartitionMappingSupplier.Builder setPartitionSupplier(
- Function<String, byte[]> partitionSupplier) {
- this.partitionSupplier = partitionSupplier;
+ public PartitionMappingSupplier.Builder setRegisterMappingPartitionCallback(
+ RegisterMappingPartitionCallback registerPartitionCallback) {
+ this.registerPartitionCallback = registerPartitionCallback;
return self();
}
@Override
- public PartitionMappingSupplier.Builder setPartitionToFetchConsumer(
- Consumer<String> partitionToFetchConsumer) {
- this.partitionToFetchConsumer = partitionToFetchConsumer;
- return self();
- }
-
- @Override
- public PartitionMappingSupplier.Builder setPrepareNewPartitions(Runnable prepare) {
+ public PartitionMappingSupplier.Builder setPrepareMappingPartitionsCallback(
+ PrepareMappingPartitionsCallback prepare) {
this.prepare = prepare;
return self();
}
@Override
+ public PartitionMappingSupplier.Builder setMappingPartitionFromKeySupplier(
+ MappingPartitionFromKeySupplier partitionSupplier) {
+ this.partitionSupplier = partitionSupplier;
+ return self();
+ }
+
+ @Override
public PartitionMappingSupplier build() {
+ if (partitionSupplier == null) {
+ throw new RuntimeException(
+ "Cannot build without providing a mapping partition from key supplier.");
+ }
return new PartitionMappingSupplierImpl(
- metadata, partitionToFetchConsumer, prepare, partitionSupplier, allowExperimental);
+ metadata,
+ registerPartitionCallback,
+ prepare,
+ partitionSupplier,
+ allowExperimental,
+ fallbackMapVersion);
}
}
diff --git a/src/main/java/com/android/tools/r8/retrace/internal/PartitionMappingSupplierImpl.java b/src/main/java/com/android/tools/r8/retrace/internal/PartitionMappingSupplierImpl.java
index 7d7708d..dfddd37 100644
--- a/src/main/java/com/android/tools/r8/retrace/internal/PartitionMappingSupplierImpl.java
+++ b/src/main/java/com/android/tools/r8/retrace/internal/PartitionMappingSupplierImpl.java
@@ -15,7 +15,10 @@
import com.android.tools.r8.references.ClassReference;
import com.android.tools.r8.references.Reference;
import com.android.tools.r8.retrace.InvalidMappingFileException;
+import com.android.tools.r8.retrace.MappingPartitionFromKeySupplier;
import com.android.tools.r8.retrace.PartitionMappingSupplier;
+import com.android.tools.r8.retrace.PrepareMappingPartitionsCallback;
+import com.android.tools.r8.retrace.RegisterMappingPartitionCallback;
import com.android.tools.r8.retrace.internal.ProguardMapReaderWithFiltering.ProguardMapReaderWithFilteringInputBuffer;
import com.android.tools.r8.utils.StringDiagnostic;
import java.io.ByteArrayInputStream;
@@ -24,8 +27,6 @@
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.Set;
-import java.util.function.Consumer;
-import java.util.function.Function;
/**
* IntelliJ highlights the class as being invalid because it cannot see getClassNameMapper is
@@ -34,10 +35,11 @@
public class PartitionMappingSupplierImpl extends PartitionMappingSupplier {
private final byte[] metadata;
- private final Consumer<String> partitionToFetchConsumer;
- private final Runnable prepare;
- private final Function<String, byte[]> partitionSupplier;
+ private final RegisterMappingPartitionCallback registerPartitionCallback;
+ private final PrepareMappingPartitionsCallback prepare;
+ private final MappingPartitionFromKeySupplier partitionSupplier;
private final boolean allowExperimental;
+ private final MapVersion fallbackMapVersion;
private ClassNameMapper classNameMapper;
private final Set<String> pendingKeys = new LinkedHashSet<>();
@@ -47,21 +49,26 @@
PartitionMappingSupplierImpl(
byte[] metadata,
- Consumer<String> partitionToFetchConsumer,
- Runnable prepare,
- Function<String, byte[]> partitionSupplier,
- boolean allowExperimental) {
+ RegisterMappingPartitionCallback registerPartitionCallback,
+ PrepareMappingPartitionsCallback prepare,
+ MappingPartitionFromKeySupplier partitionSupplier,
+ boolean allowExperimental,
+ MapVersion fallbackMapVersion) {
this.metadata = metadata;
- this.partitionToFetchConsumer = partitionToFetchConsumer;
+ this.registerPartitionCallback = registerPartitionCallback;
this.prepare = prepare;
this.partitionSupplier = partitionSupplier;
this.allowExperimental = allowExperimental;
+ this.fallbackMapVersion = fallbackMapVersion;
}
private MappingPartitionMetadataInternal getMetadata(DiagnosticsHandler diagnosticsHandler) {
+ if (mappingPartitionMetadataCache != null) {
+ return mappingPartitionMetadataCache;
+ }
return mappingPartitionMetadataCache =
MappingPartitionMetadataInternal.createFromBytes(
- metadata, MapVersion.MAP_VERSION_NONE, diagnosticsHandler);
+ metadata, fallbackMapVersion, diagnosticsHandler);
}
@Override
@@ -86,13 +93,13 @@
private ClassNameMapper getClassNameMapper(DiagnosticsHandler diagnosticsHandler) {
MappingPartitionMetadataInternal metadata = getMetadata(diagnosticsHandler);
if (!pendingKeys.isEmpty()) {
- prepare.run();
+ prepare.prepare();
}
for (String pendingKey : pendingKeys) {
try {
LineReader reader =
new ProguardMapReaderWithFilteringInputBuffer(
- new ByteArrayInputStream(partitionSupplier.apply(pendingKey)), alwaysTrue(), true);
+ new ByteArrayInputStream(partitionSupplier.get(pendingKey)), alwaysTrue(), true);
classNameMapper =
ClassNameMapper.mapperFromLineReaderWithFiltering(
reader, metadata.getMapVersion(), diagnosticsHandler, true, allowExperimental)
@@ -118,7 +125,7 @@
private void registerKeyUse(String key) {
if (!builtKeys.contains(key) && pendingKeys.add(key)) {
- partitionToFetchConsumer.accept(key);
+ registerPartitionCallback.register(key);
}
}
diff --git a/src/test/java/com/android/tools/r8/retrace/api/RetraceApiTestCollection.java b/src/test/java/com/android/tools/r8/retrace/api/RetraceApiTestCollection.java
index 731fc0b..ffb522b 100644
--- a/src/test/java/com/android/tools/r8/retrace/api/RetraceApiTestCollection.java
+++ b/src/test/java/com/android/tools/r8/retrace/api/RetraceApiTestCollection.java
@@ -40,7 +40,9 @@
RetraceApiInlineInOutlineTest.ApiTest.class,
RetraceApiSingleFrameTest.ApiTest.class,
RetracePartitionStringTest.ApiTest.class,
- RetracePartitionRoundTripTest.ApiTest.class);
+ RetracePartitionRoundTripTest.ApiTest.class,
+ RetracePartitionJoinNoMetadataTest.ApiTest.class,
+ RetracePartitionSerializedObfuscatedKeyTest.ApiTest.class);
public static List<Class<? extends RetraceApiBinaryTest>> CLASSES_PENDING_BINARY_COMPATIBILITY =
ImmutableList.of();
diff --git a/src/test/java/com/android/tools/r8/retrace/api/RetracePartitionJoinNoMetadataTest.java b/src/test/java/com/android/tools/r8/retrace/api/RetracePartitionJoinNoMetadataTest.java
new file mode 100644
index 0000000..095eb99
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/retrace/api/RetracePartitionJoinNoMetadataTest.java
@@ -0,0 +1,99 @@
+// Copyright (c) 2022, 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.api;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+import com.android.tools.r8.TestParameters;
+import com.android.tools.r8.naming.MapVersion;
+import com.android.tools.r8.retrace.PartitionMappingSupplier;
+import com.android.tools.r8.retrace.Retrace;
+import com.android.tools.r8.retrace.RetraceCommand;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+@RunWith(Parameterized.class)
+public class RetracePartitionJoinNoMetadataTest extends RetraceApiTestBase {
+
+ public RetracePartitionJoinNoMetadataTest(TestParameters parameters) {
+ super(parameters);
+ }
+
+ @Override
+ protected Class<? extends RetraceApiBinaryTest> binaryTestClass() {
+ return ApiTest.class;
+ }
+
+ public static class ApiTest implements RetraceApiBinaryTest {
+
+ private final String aMapping =
+ "com.foo.bar.baz -> a:\n"
+ + " # {'id':'sourceFile','fileName':'BarBaz.kt'}\n"
+ + " int field -> c\n"
+ + " 1:1:void method():42:42 -> d";
+
+ private final String bMapping =
+ "foo -> foo:\n"
+ + " # {'id':'sourceFile','fileName':'Foo-inlinee.kt'}\n"
+ + "com.android.google.R8 -> b:\n"
+ + " # {'id':'sourceFile','fileName':'R8Car.kt'}\n"
+ + " 2:2:int foo.inlinee():43:43 -> f\n"
+ + " 2:2:int otherMethod():44 -> f\n"
+ + "# otherCommentHere";
+
+ private final String exceptionMapping = "com.android.google.exception -> exception:\n";
+
+ private final List<String> stackTrace =
+ Arrays.asList("exception: Hello World!", " at a.d(Unknown:1)", " at b.f(Unknown:2)");
+
+ private final List<String> expectedRetracedStackTrace =
+ Arrays.asList(
+ "com.android.google.exception: Hello World!",
+ " at com.foo.bar.baz.method(BarBaz.kt:42)",
+ " at foo.inlinee(Foo-inlinee.kt:43)",
+ " at com.android.google.R8.otherMethod(R8Car.kt:44)");
+
+ @Test
+ public void test() throws IOException {
+ List<String> preFetch = new ArrayList<>();
+ PartitionMappingSupplier mappingSupplier =
+ PartitionMappingSupplier.noMetadataBuilder(MapVersion.MAP_VERSION_1_0)
+ .setMappingPartitionFromKeySupplier(
+ key -> {
+ switch (key) {
+ case "a":
+ return aMapping.getBytes();
+ case "b":
+ return bMapping.getBytes();
+ case "exception":
+ return exceptionMapping.getBytes();
+ default:
+ fail();
+ return null;
+ }
+ })
+ .setRegisterMappingPartitionCallback(preFetch::add)
+ .build();
+ Retrace.run(
+ RetraceCommand.builder()
+ .setStackTrace(stackTrace)
+ .setMappingSupplier(mappingSupplier)
+ .setRetracedStackTraceConsumer(
+ retraced -> assertEquals(expectedRetracedStackTrace, retraced))
+ .build());
+ assertEquals(3, preFetch.size());
+ Set<String> expected = new HashSet<>(Arrays.asList("a", "b", "exception"));
+ assertEquals(expected, new HashSet<>(preFetch));
+ }
+ }
+}
diff --git a/src/test/java/com/android/tools/r8/retrace/api/RetracePartitionRoundTripTest.java b/src/test/java/com/android/tools/r8/retrace/api/RetracePartitionRoundTripTest.java
index 6a91dab..0eac918 100644
--- a/src/test/java/com/android/tools/r8/retrace/api/RetracePartitionRoundTripTest.java
+++ b/src/test/java/com/android/tools/r8/retrace/api/RetracePartitionRoundTripTest.java
@@ -89,9 +89,9 @@
PartitionMappingSupplier mappingSupplier =
PartitionMappingSupplier.builder()
.setMetadata(metadataData.getBytes())
- .setPartitionToFetchConsumer(preFetchedKeys::add)
- .setPrepareNewPartitions(() -> prepareCounter++)
- .setPartitionSupplier(
+ .setRegisterMappingPartitionCallback(preFetchedKeys::add)
+ .setPrepareMappingPartitionsCallback(() -> prepareCounter++)
+ .setMappingPartitionFromKeySupplier(
key -> {
assertTrue(preFetchedKeys.contains(key));
return partitions.get(key);
diff --git a/src/test/java/com/android/tools/r8/retrace/api/RetracePartitionSerializedObfuscatedKeyTest.java b/src/test/java/com/android/tools/r8/retrace/api/RetracePartitionSerializedObfuscatedKeyTest.java
new file mode 100644
index 0000000..58b092b
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/retrace/api/RetracePartitionSerializedObfuscatedKeyTest.java
@@ -0,0 +1,71 @@
+// Copyright (c) 2022, 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.api;
+
+import static org.junit.Assert.assertEquals;
+
+import com.android.tools.r8.TestParameters;
+import com.android.tools.r8.retrace.PartitionMappingSupplier;
+import com.android.tools.r8.retrace.Retrace;
+import com.android.tools.r8.retrace.RetraceCommand;
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
+import java.util.List;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+@RunWith(Parameterized.class)
+public class RetracePartitionSerializedObfuscatedKeyTest extends RetraceApiTestBase {
+
+ public RetracePartitionSerializedObfuscatedKeyTest(TestParameters parameters) {
+ super(parameters);
+ }
+
+ @Override
+ protected Class<? extends RetraceApiBinaryTest> binaryTestClass() {
+ return ApiTest.class;
+ }
+
+ public static class ApiTest implements RetraceApiBinaryTest {
+
+ private final String mapping = "com.R8 -> a:\n" + " void m() -> b\n";
+
+ // Serialized data from ObfuscatedTypeNameAsKeyMetadata with Map Version 1.0.
+ private final byte[] metadata = new byte[] {0, 0, 49, 46, 48};
+
+ private static final String minifiedStackTraceLine = " at a.b()";
+
+ private static final String retracedStackTraceLine = " at com.R8.m(R8.java)";
+
+ @Test
+ public void test() throws IOException {
+ PartitionMappingSupplier mappingSupplier =
+ PartitionMappingSupplier.builder()
+ .setMetadata(metadata)
+ .setMappingPartitionFromKeySupplier(
+ key -> {
+ assertEquals("a", key);
+ return mapping.getBytes(StandardCharsets.UTF_8);
+ })
+ .build();
+
+ List<String> stackTrace = new ArrayList<>();
+ stackTrace.add(minifiedStackTraceLine);
+
+ Retrace.run(
+ RetraceCommand.builder()
+ .setMappingSupplier(mappingSupplier)
+ .setStackTrace(stackTrace)
+ .setRetracedStackTraceConsumer(
+ retraced -> {
+ assertEquals(1, retraced.size());
+ assertEquals(retracedStackTraceLine, retraced.get(0));
+ })
+ .build());
+ }
+ }
+}
diff --git a/third_party/retrace/binary_compatibility.tar.gz.sha1 b/third_party/retrace/binary_compatibility.tar.gz.sha1
index f5a5521..0ebc3f5 100644
--- a/third_party/retrace/binary_compatibility.tar.gz.sha1
+++ b/third_party/retrace/binary_compatibility.tar.gz.sha1
@@ -1 +1 @@
-3aa48c8d23b8ae1e1c51c91ef8c73f7bc7cb4657
\ No newline at end of file
+f49f174fe4f8ecf0ddc4b47d98bcb293d689eeb9
\ No newline at end of file