我们正在尝试将未捕获的GWT异常(我们使用GWT 2.5 rc1)发送到我们的服务器以进行日志记录和调试。我们希望对异常堆栈跟踪进行反混淆处理,否则它将毫无用处。
经过一些调查后,我发现7 Tips for Exception Handling in GWT和WebModeExceptions包含了有价值的信息。
因此,我们创建了一个GWT UncaughtExceptionHandler,它使用自定义RPC服务来传输带有堆栈跟踪的异常。这很好。
如WebModeExceptions deobfuscation section所述,我们在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。
我们的自定义日志服务使用symbolMaps目录来调用com.google.gwt.logging.server.StackTraceDeobfuscator。我们使用X-GWT-Permutation http头来调用反混淆器。我介入了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并得到了相同的结果。
答案 0 :(得分:9)
经过进一步调查后,我们使用的新GWT编译器选项-XenableClosureCompiler
似乎生成的代码不会输出使用编译器生成的符号映射的堆栈跟踪。删除该选项后,可以成功地对堆栈跟踪进行反混淆处理。
作为旁注,启用堆栈跟踪反混淆所需的编译器和GWT模块选项(在我的问题中描述并删除闭包编译器选项)使我们的最终js文件比以前大两倍。
答案 1 :(得分:0)
问题中的StackTraceDeobfuscator
版本现已弃用。这是新方法(没什么大不了):
仍然在.gwt.xml文件中设置属性:
<set-property name="compiler.stackMode" value="emulated" />
<set-configuration-property name="compiler.emulatedStack.recordLineNumbers" value="true" />
然后,一旦将异常传递回您的服务器RemoteServiceServlet
:
import com.google.gwt.core.server.StackTraceDeobfuscator;
import com.google.gwt.user.client.rpc.RpcRequestBuilder;
String path = getServletConfig().getServletContext().getRealPath("/WEB-INF/deploy/<your module name>/symbolMaps/");
StackTraceDeobfuscator deobfuscator = StackTraceDeobfuscator.fromFileSystem(path);
String strongName = getThreadLocalRequest().getHeader(RpcRequestBuilder.STRONG_NAME_HEADER);
// Do the magic
deobfuscator.deobfuscateStackTrace(exception, strongName);
// Log it
logger.severe("Uncaught GWT exception", exception);