-printmapping mapping.txt -renamesourcefileattribute MyApplication -keepattributes SourceFile,LineNumberTable
Now assume the processed application throws an exception:
java.io.IOException: Can't read [dummy.jar] (No such file or directory) at proguard.y.a(MyApplication:188) at proguard.y.a(MyApplication:158) at proguard.y.a(MyApplication:136) at proguard.y.a(MyApplication:66) at proguard.ProGuard.c(MyApplication:218) at proguard.ProGuard.a(MyApplication:82) at proguard.ProGuard.main(MyApplication:538) Caused by: java.io.IOException: No such file or directory at proguard.d.q.a(MyApplication:50) at proguard.y.a(MyApplication:184) ... 6 more
If we have saved the stack trace in a file stacktrace.txt
, we can
use the following command to recover the stack trace:
java -jar retrace.jar mapping.txt stacktrace.txt
The output will correspond to the original stack trace:
java.io.IOException: Can't read [dummy.jar] (No such file or directory) at proguard.InputReader.readInput(InputReader.java:188) at proguard.InputReader.readInput(InputReader.java:158) at proguard.InputReader.readInput(InputReader.java:136) at proguard.InputReader.execute(InputReader.java:66) at proguard.ProGuard.readInput(ProGuard.java:218) at proguard.ProGuard.execute(ProGuard.java:82) at proguard.ProGuard.main(ProGuard.java:538) Caused by: java.io.IOException: No such file or directory at proguard.io.DirectoryPump.pumpDataEntries(DirectoryPump.java:50) at proguard.InputReader.readInput(InputReader.java:184) ... 6 more
java -jar retrace.jar -verbose mapping.txt stacktrace.txt
The output will then look as follows:
java.io.IOException: Can't read [dummy.jar] (No such file or directory) at proguard.InputReader.void readInput(java.lang.String,proguard.ClassPathEntry,proguard.io.DataEntryReader)(InputReader.java:188) at proguard.InputReader.void readInput(java.lang.String,proguard.ClassPath,int,int,proguard.io.DataEntryReader)(InputReader.java:158) at proguard.InputReader.void readInput(java.lang.String,proguard.ClassPath,proguard.io.DataEntryReader)(InputReader.java:136) at proguard.InputReader.void execute(proguard.classfile.ClassPool,proguard.classfile.ClassPool)(InputReader.java:66) at proguard.ProGuard.void readInput()(ProGuard.java:218) at proguard.ProGuard.void execute()(ProGuard.java:82) at proguard.ProGuard.void main(java.lang.String[])(ProGuard.java:538) Caused by: java.io.IOException: No such file or directory at proguard.io.DirectoryPump.void pumpDataEntries(proguard.io.DataEntryReader)(DirectoryPump.java:50) at proguard.InputReader.void readInput(java.lang.String,proguard.ClassPathEntry,proguard.io.DataEntryReader)(InputReader.java:184) ... 6 more
-printmapping mapping.txt
A stack trace stacktrace.txt
will then lack line number
information, showing "Unknown source" instead:
java.io.IOException: Can't read [dummy.jar] (No such file or directory) at proguard.y.a(Unknown Source) at proguard.y.a(Unknown Source) at proguard.y.a(Unknown Source) at proguard.y.a(Unknown Source) at proguard.ProGuard.c(Unknown Source) at proguard.ProGuard.a(Unknown Source) at proguard.ProGuard.main(Unknown Source) Caused by: java.io.IOException: No such file or directory at proguard.d.q.a(Unknown Source) ... 7 more
We can still use the same command to recover the stack trace:
java -jar retrace.jar mapping.txt stacktrace.txt
The output will now list all alternative original method names for each ambiguous obfuscated method name:
java.io.IOException: Can't read [dummy.jar] (No such file or directory) at proguard.InputReader.execute(InputReader.java) readInput(InputReader.java) at proguard.InputReader.execute(InputReader.java) readInput(InputReader.java) at proguard.InputReader.execute(InputReader.java) readInput(InputReader.java) at proguard.InputReader.execute(InputReader.java) readInput(InputReader.java) at proguard.ProGuard.readInput(ProGuard.java) at proguard.ProGuard.execute(ProGuard.java) optimize(ProGuard.java) createPrintStream(ProGuard.java) closePrintStream(ProGuard.java) fileName(ProGuard.java) at proguard.ProGuard.main(ProGuard.java) Caused by: java.io.IOException: No such file or directory at proguard.io.DirectoryPump.pumpDataEntries(DirectoryPump.java) readFiles(DirectoryPump.java)
For instance, ReTrace can't tell if the method a
corresponds
to execute
or to readInput
, so it lists both. You
need to figure it out based on your knowledge of the application. Having line
numbers and unambiguous names clearly is a lot easier, so you should consider
preserving the line numbers when you
obfuscate your application.