| <!doctype html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> |
| <html> |
| <head> |
| <meta http-equiv="content-type" content="text/html; charset=iso-8859-1"> |
| <meta http-equiv="content-style-type" content="text/css"> |
| <link rel="stylesheet" type="text/css" href="../style.css"> |
| <title>ReTrace Examples</title> |
| </head> |
| <body> |
| |
| <script type="text/javascript" language="JavaScript"> |
| <!-- |
| if (window.self==window.top) |
| document.write('<a class="largebutton" target="_top" href="../../index.html#manual/retrace/examples.html">ProGuard index</a> <a class="largebutton" target="_top" href="http://www.guardsquare.com/dexguard">DexGuard</a> <a class="largebutton" target="_top" href="http://www.guardsquare.com/">GuardSquare</a> <a class="largebutton" target="other" href="http://sourceforge.net/projects/proguard/">Sourceforge</a>') |
| //--> |
| </script> |
| <noscript> |
| <a class="largebutton" target="_top" href="../../index.html#manual/retrace/examples.html">ProGuard index</a> |
| <a class="largebutton" target="_top" href="http://www.guardsquare.com/dexguard">DexGuard</a> |
| <a class="largebutton" target="_top" href="http://www.guardsquare.com/">GuardSquare</a> |
| <a class="largebutton" target="other" href="http://sourceforge.net/projects/proguard/">Sourceforge</a> |
| </noscript> |
| |
| <h2>Examples</h2> |
| |
| Some typical example uses: |
| <ol> |
| <li><a href="#with">Restoring a stack trace with line numbers</a></li> |
| <li><a href="#withverbose">Restoring a stack trace with line numbers |
| (verbose)</a></li> |
| <li><a href="#without">Restoring a stack trace without line numbers</a></li> |
| </ol> |
| |
| <h3><a name="with">Restoring a stack trace with line numbers</a></h3> |
| |
| Assume for instance ProGuard itself has been obfuscated using the following |
| extra options: |
| <pre> |
| -printmapping mapping.txt |
| |
| -renamesourcefileattribute MyApplication |
| -keepattributes SourceFile,LineNumberTable |
| </pre> |
| <p> |
| |
| Now assume the processed application throws an exception: |
| <pre> |
| 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 |
| </pre> |
| <p> |
| |
| If we have saved the stack trace in a file <code>stacktrace.txt</code>, we can |
| use the following command to recover the stack trace: |
| <pre> |
| <b>java -jar retrace.jar mapping.txt stacktrace.txt</b> |
| </pre> |
| <p> |
| |
| The output will correspond to the original stack trace: |
| <pre> |
| 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 |
| </pre> |
| |
| <h3><a name="withverbose">Restoring a stack trace with line numbers (verbose)</a></h3> |
| |
| In the previous example, we could also use the verbose flag: |
| <pre> |
| <b>java -jar retrace.jar -verbose mapping.txt stacktrace.txt</b> |
| </pre> |
| <p> |
| |
| The output will then look as follows: |
| <pre> |
| 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 |
| </pre> |
| |
| |
| <h3><a name="without">Restoring a stack trace without line numbers</a></h3> |
| |
| Assume for instance ProGuard itself has been obfuscated using the following |
| extra options, this time without preserving the line number tables: |
| <pre> |
| -printmapping mapping.txt |
| </pre> |
| <p> |
| |
| A stack trace <code>stacktrace.txt</code> will then lack line number |
| information, showing "Unknown source" instead: |
| <pre> |
| 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 |
| </pre> |
| <p> |
| |
| We can still use the same command to recover the stack trace: |
| <pre> |
| <b>java -jar retrace.jar mapping.txt stacktrace.txt</b> |
| </pre> |
| <p> |
| |
| The output will now list all alternative original method names for each |
| ambiguous obfuscated method name: |
| <pre> |
| 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) |
| </pre> |
| <p> |
| |
| For instance, ReTrace can't tell if the method <code>a</code> corresponds |
| to <code>execute</code> or to <code>readInput</code>, 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 |
| <a href="../examples.html#stacktrace">preserving the line numbers</a> when you |
| obfuscate your application. |
| |
| <hr /> |
| <address> |
| Copyright © 2002-2017 |
| <a target="other" href="http://www.lafortune.eu/">Eric Lafortune</a> @ <a target="top" href="http://www.guardsquare.com/">GuardSquare</a>. |
| </address> |
| </body> |
| </html> |
| |