我们正在尝试将未捕获的GWT异常(我们使用的是GWT 2.5 rc1版本)发送到服务器以进行日志记录和调试。我们希望对异常堆栈跟踪进行反混淆,否则它几乎没有用。
经过一些调查,我发现了 7个关于GWT异常处理的技巧 和 WebModeExceptions 这两篇文章提供了有价值的信息。
因此,我们创建了一个GWT UncaughtExceptionHandler,使用自定义RPC服务传输异常及其堆栈跟踪。这工作得很好。
正如WebModeExceptions反混淆部分所述,我们在GWT模块中启用了堆栈跟踪仿真:
<set-property name="compiler.stackMode" value="emulated" />
<set-configuration-property name="compiler.emulatedStack.recordLineNumbers"
value="true" />
现在我们的堆栈跟踪看起来像这样: com.google.gwt.core.client.JavaScriptException: (TypeError) : Cannot call method 'pp' of null
Unknown.aT(Unknown Source:174)
Unknown.AVa(Unknown Source:501)
Unknown.YF(Unknown Source:29)
Unknown.Lqb(Unknown Source:138)
...
在我看来这个看起来没问题,因为它包含了混淆方法名和行号,这似乎是需要的,如WebModeExceptions deobfuscation section中所述。
然后我们使用-extra参数编译我们的GWT模块,以获取符号映射。
我们的自定义日志服务使用symbolMaps目录调用com.google.gwt.logging.server.StackTraceDeobfuscator。我们使用X-GWT-Permutation http头来调用deobfuscator。我进入deobfuscate方法,确保它可以加载符号映射。它可以。我验证了使用的symbolMap文件名与GWT模块的*.cache.js文件名匹配。它是匹配的。
所以基本上,该服务执行以下操作:
// Create the deobfuscator
String dir = getSymbolMapsDirPath();
StackTraceDeobfuscator deobfuscator = new StackTraceDeobfuscator(dir);
// request is the HttpServletRequest
String strongName = request.getHeader(RpcRequestBuilder.STRONG_NAME_HEADER);
// Deobfuscate the stack trace
exception.setStackTrace(
deobfuscator.deobfuscateStackTrace(exception.getStackTrace(), strongName));
// Log the exception
logger.severe("Uncaught GWT exception", exception);
最终结果是堆栈跟踪未被反混淆。有时,一些行会用错误的类和方法名进行反混淆,但仅此而已。当查看symbolMap文件时,堆栈跟踪中的实际符号与symbolMap文件中的任何符号都不匹配。
不知道我们做错了什么?
编辑:我尝试了RemoteLoggingServiceImpl,得到了相同的结果。
RemoteLoggingServiceImpl
有什么原因吗? - Thomas Broyer