diff options
| -rw-r--r-- | tools/ahat/Android.mk | 17 | ||||
| -rw-r--r-- | tools/ahat/README.txt | 6 | ||||
| -rw-r--r-- | tools/ahat/src/AhatSnapshot.java | 5 | ||||
| -rw-r--r-- | tools/ahat/src/Main.java | 17 | ||||
| -rw-r--r-- | tools/ahat/test-dump/config.pro | 15 | ||||
| -rw-r--r-- | tools/ahat/test/TestDump.java | 16 |
6 files changed, 67 insertions, 9 deletions
diff --git a/tools/ahat/Android.mk b/tools/ahat/Android.mk index ebf087d859..27c20545f6 100644 --- a/tools/ahat/Android.mk +++ b/tools/ahat/Android.mk @@ -55,11 +55,23 @@ LOCAL_MODULE := ahat-tests include $(BUILD_HOST_JAVA_LIBRARY) AHAT_TEST_JAR := $(LOCAL_BUILT_MODULE) +# Rule to generate the proguard configuration for the test-dump program. +# We copy the configuration to the intermediates directory because jack will +# output the proguard map in that same directory. +AHAT_TEST_DUMP_PROGUARD_CONFIG := $(intermediates.COMMON)/config.pro +AHAT_TEST_DUMP_PROGUARD_MAP := $(intermediates.COMMON)/proguard.map +$(AHAT_TEST_DUMP_PROGUARD_CONFIG): PRIVATE_AHAT_PROGUARD_CONFIG_IN := $(LOCAL_PATH)/test-dump/config.pro +$(AHAT_TEST_DUMP_PROGUARD_CONFIG): PRIVATE_AHAT_PROGUARD_CONFIG := $(AHAT_TEST_DUMP_PROGUARD_CONFIG) +$(AHAT_TEST_DUMP_PROGUARD_CONFIG): $(LOCAL_PATH)/test-dump/config.pro + cp $(PRIVATE_AHAT_PROGUARD_CONFIG_IN) $(PRIVATE_AHAT_PROGUARD_CONFIG) + # --- ahat-test-dump.jar -------------- include $(CLEAR_VARS) LOCAL_MODULE := ahat-test-dump LOCAL_MODULE_TAGS := tests LOCAL_SRC_FILES := $(call all-java-files-under, test-dump) +LOCAL_ADDITIONAL_DEPENDENCIES := $(AHAT_TEST_DUMP_PROGUARD_CONFIG) +LOCAL_JACK_FLAGS := --config-proguard $(AHAT_TEST_DUMP_PROGUARD_CONFIG) include $(BUILD_HOST_DALVIK_JAVA_LIBRARY) # Determine the location of the test-dump.jar and test-dump.hprof files. @@ -84,12 +96,15 @@ $(AHAT_TEST_DUMP_HPROF): $(AHAT_TEST_DUMP_JAR) $(AHAT_TEST_DUMP_DEPENDENCIES) .PHONY: ahat-test ahat-test: PRIVATE_AHAT_TEST_DUMP_HPROF := $(AHAT_TEST_DUMP_HPROF) ahat-test: PRIVATE_AHAT_TEST_JAR := $(AHAT_TEST_JAR) +ahat-test: PRIVATE_AHAT_PROGUARD_MAP := $(AHAT_TEST_DUMP_PROGUARD_MAP) ahat-test: $(AHAT_TEST_JAR) $(AHAT_TEST_DUMP_HPROF) - java -Dahat.test.dump.hprof=$(PRIVATE_AHAT_TEST_DUMP_HPROF) -jar $(PRIVATE_AHAT_TEST_JAR) + java -Dahat.test.dump.hprof=$(PRIVATE_AHAT_TEST_DUMP_HPROF) -Dahat.test.dump.map=$(PRIVATE_AHAT_PROGUARD_MAP) -jar $(PRIVATE_AHAT_TEST_JAR) # Clean up local variables. AHAT_TEST_DUMP_DEPENDENCIES := AHAT_TEST_DUMP_HPROF := AHAT_TEST_DUMP_JAR := +AHAT_TEST_DUMP_PROGUARD_CONFIG := +AHAT_TEST_DUMP_PROGUARD_MAP := AHAT_TEST_JAR := diff --git a/tools/ahat/README.txt b/tools/ahat/README.txt index dbc1102095..8dfb4abe5b 100644 --- a/tools/ahat/README.txt +++ b/tools/ahat/README.txt @@ -1,12 +1,14 @@ AHAT - Android Heap Analysis Tool Usage: - java -jar ahat.jar [-p port] FILE + java -jar ahat.jar [-p port] [--proguard-map FILE] FILE Launch an http server for viewing the given Android heap-dump FILE. Options: -p <port> Serve pages on the given port. Defaults to 7100. + --proguard-map FILE + Use the proguard map FILE to deobfuscate the heap dump. TODO: * Have a way to diff two heap dumps. @@ -84,7 +86,7 @@ Release History: Target Java 1.7. 0.6 Jun 21, 2016 - Add support for proguard deobfuscation (pending AOSP push of perflib) + Add support for proguard deobfuscation. 0.5 Apr 19, 2016 Update perflib to perflib-25.0.0 to improve processing performance. diff --git a/tools/ahat/src/AhatSnapshot.java b/tools/ahat/src/AhatSnapshot.java index a8205c7f1a..ba8243f744 100644 --- a/tools/ahat/src/AhatSnapshot.java +++ b/tools/ahat/src/AhatSnapshot.java @@ -20,6 +20,7 @@ import com.android.tools.perflib.captures.MemoryMappedFileBuffer; import com.android.tools.perflib.heap.ClassObj; import com.android.tools.perflib.heap.Heap; import com.android.tools.perflib.heap.Instance; +import com.android.tools.perflib.heap.ProguardMap; import com.android.tools.perflib.heap.RootObj; import com.android.tools.perflib.heap.RootType; import com.android.tools.perflib.heap.Snapshot; @@ -71,8 +72,8 @@ class AhatSnapshot { /** * Create an AhatSnapshot from an hprof file. */ - public static AhatSnapshot fromHprof(File hprof) throws IOException { - Snapshot snapshot = Snapshot.createSnapshot(new MemoryMappedFileBuffer(hprof)); + public static AhatSnapshot fromHprof(File hprof, ProguardMap map) throws IOException { + Snapshot snapshot = Snapshot.createSnapshot(new MemoryMappedFileBuffer(hprof), map); snapshot.computeDominators(); return new AhatSnapshot(snapshot); } diff --git a/tools/ahat/src/Main.java b/tools/ahat/src/Main.java index fdc5a860eb..c79b57863e 100644 --- a/tools/ahat/src/Main.java +++ b/tools/ahat/src/Main.java @@ -16,24 +16,28 @@ package com.android.ahat; +import com.android.tools.perflib.heap.ProguardMap; import com.sun.net.httpserver.HttpServer; import java.io.File; import java.io.IOException; import java.io.PrintStream; import java.net.InetAddress; import java.net.InetSocketAddress; +import java.text.ParseException; import java.util.concurrent.Executors; public class Main { public static void help(PrintStream out) { - out.println("java -jar ahat.jar [-p port] FILE"); + out.println("java -jar ahat.jar [-p port] [--proguard-map FILE] FILE"); out.println(" Launch an http server for viewing " + "the given Android heap-dump FILE."); out.println(""); out.println("Options:"); out.println(" -p <port>"); out.println(" Serve pages on the given port. Defaults to 7100."); + out.println(" --proguard-map FILE"); + out.println(" Use the proguard map FILE to deobfuscate the heap dump."); out.println(""); } @@ -47,10 +51,19 @@ public class Main { } File hprof = null; + ProguardMap map = new ProguardMap(); for (int i = 0; i < args.length; i++) { if ("-p".equals(args[i]) && i + 1 < args.length) { i++; port = Integer.parseInt(args[i]); + } else if ("--proguard-map".equals(args[i]) && i + 1 < args.length) { + i++; + try { + map.readFromFile(new File(args[i])); + } catch (IOException|ParseException ex) { + System.out.println("Unable to read proguard map: " + ex); + System.out.println("The proguard map will not be used."); + } } else { if (hprof != null) { System.err.println("multiple input files."); @@ -74,7 +87,7 @@ public class Main { HttpServer server = HttpServer.create(addr, 0); System.out.println("Processing hprof file..."); - AhatSnapshot ahat = AhatSnapshot.fromHprof(hprof); + AhatSnapshot ahat = AhatSnapshot.fromHprof(hprof, map); server.createContext("/", new AhatHttpHandler(new OverviewHandler(ahat, hprof))); server.createContext("/rooted", new AhatHttpHandler(new RootedHandler(ahat))); server.createContext("/object", new AhatHttpHandler(new ObjectHandler(ahat))); diff --git a/tools/ahat/test-dump/config.pro b/tools/ahat/test-dump/config.pro new file mode 100644 index 0000000000..0cf7a87303 --- /dev/null +++ b/tools/ahat/test-dump/config.pro @@ -0,0 +1,15 @@ +# The goal of this proguard configuration is to obfuscate the test-dump +# program so that the heap dump it generates is an obfuscated heap dump. +# This allows us to test that deobfuscation of the generated heap dump is +# working properly. + +# All we care about is obfuscation. Don't do any other optimizations. +-dontpreverify +-dontoptimize +-dontshrink + +-keep public class Main { + public static void main(java.lang.String[]); +} + +-printmapping proguard.map diff --git a/tools/ahat/test/TestDump.java b/tools/ahat/test/TestDump.java index c3a76e4f18..ebce61c2e8 100644 --- a/tools/ahat/test/TestDump.java +++ b/tools/ahat/test/TestDump.java @@ -19,8 +19,10 @@ package com.android.ahat; import com.android.tools.perflib.heap.ClassObj; import com.android.tools.perflib.heap.Field; import com.android.tools.perflib.heap.Instance; +import com.android.tools.perflib.heap.ProguardMap; import java.io.File; import java.io.IOException; +import java.text.ParseException; import java.util.Map; /** @@ -44,11 +46,21 @@ public class TestDump { * For example: * java -Dahat.test.dump.hprof=test-dump.hprof -jar ahat-tests.jar * - * An IOException is thrown if there is a failure reading the hprof file. + * An IOException is thrown if there is a failure reading the hprof file or + * the proguard map. */ private TestDump() throws IOException { String hprof = System.getProperty("ahat.test.dump.hprof"); - mSnapshot = AhatSnapshot.fromHprof(new File(hprof)); + + String mapfile = System.getProperty("ahat.test.dump.map"); + ProguardMap map = new ProguardMap(); + try { + map.readFromFile(new File(mapfile)); + } catch (ParseException e) { + throw new IOException("Unable to load proguard map", e); + } + + mSnapshot = AhatSnapshot.fromHprof(new File(hprof), map); } /** |