问题描述
|
我希望能够可视化给定JVM进程的调用序列(在哪些对象上传递了什么方法,在什么位置传递了什么参数)。例如,将这些信息转储到文件中的工具。
有没有现成的工具可以做到这一点?如果不能,那么您是否可以提出一些建议?您可以建议什么解决方案(除了修改方法的字节码之外)?
解决方法
OP说“ Java日志记录”不好。 \“是的,但是您必须手动插入所有日志调用。对于大型项目而言,这不是一个非常可行的选择,是吗?\”。
好的,您需要的是一种将自定义工具自动插入应用程序的方法。
我们的DMS软件再造工具包及其Java前端可用于执行此操作。 DMS提供了通用的机制来解析源代码,构建AST和符号表,分析特殊情况下的代码(树)以及对代码(树)进行转换,最终(从修改后的树)重新生成修改后的代码。 Java前端使DMS可以针对Java执行此操作。 DMS还有许多其他前端语言模块。
您想要做的是编写一个DMS源到源转换,以使用逻辑来检测该函数条目以转储参数列表值(例如,序列化其\“ toString \”等效项):
tag RecordArguments(a:arguments):statements;
instrument_function_entry rule(r:type,m:identifier,a:arguments,s:stmts):method->method
\"\\r \\m(\\a) { \\s } \"
->
\"\\r \\m(\\a) { Call.FunctionEntry(\\stringify\\(\\m\\));\\RecordArguments\\(\\a\\); { \\s } }\"
empty_arguments rule () arguments -> statements
\"\\RecordArguments\\(\\) \" -> \";\"
more_arguments rule (args:arguments,a:argument) arguments -> statements
\"\\RecordArguments\\(\\args,\\a)\"
-> \"\\RecordArguments\\(\\args\\);Call.Argument(\\a.toString()))\"
\“ instrument_function_entry \”规则的作用是进行调用以记录函数条目,并生成一系列调用以记录参数值。 \“ empty_arguments \”规则处理不再要处理的参数的基本情况(包括\“根本没有参数\”)。 \“ more_arguments \”规则通过选择最后一个参数,生成转储该参数的代码,并生成较短的剩余参数列表,以供同一条规则或最终由\“ empty_arguments \”规则处理来处理参数列表。
这应该为该方法产生什么:
int X3(char J,array[] X)
{ <code> }
将会
int X3(char J,array[] X)
{ Call.FunctionEntry(\"X3\");
Call.Argument(J.toString());
Call.Argument(X.toString());
{ <code> }
}
您可以根据需要定义\“ Call \”对象,以记录结果。如果要在其中放置额外的过滤器以消除错误线程中的数据,或者不在某个时间窗口之间或不在某个有趣的事件附近,则可以。这可能会使您的应用程序减慢很多速度,至少是如果让检测人员对应用程序中的每个函数调用都这样做的话。 (更复杂的转换可以控制它们的应用位置)。
,查看Java调用堆栈的最佳方法是通过Eclipse调试器。如果只是在代码中放置断点,则可以单步执行代码并查看调用堆栈。
,我认为最简单的方法是使用JPDA(Java平台调试器体系结构)。您将不得不暂停所有线程,分析,转储信息并恢复线程。这将不是小事,但是从一开始就应该是可能的。