third_party/java/proguard/proguard6.2.2/docs/manual/retrace/examples.md
Assume for instance ProGuard itself has been obfuscated using the following extra options:
-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:
retrace 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
In the previous example, we could also use the verbose flag:
retrace -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
Assume for instance ProGuard itself has been obfuscated using the following extra options, this time without preserving the line number tables:
-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.