我希望能够可视化给定JVM进程的调用序列(在哪些对象和传递的参数上调用了哪些方法)。例如,将此信息转储到文件的工具。 有现成的工具吗?如果没有,你能否就如何做到这一点给出一些指示?您可以建议哪些解决方案(除了修改方法的字节码)?
答案 0 :(得分:1)
好的,您需要的是一种将自定义检测自动插入应用程序的方法。
我们的DMS Software Reengineering Toolkit及其Java Front End可用于执行此操作。 DMS提供通用机制来解析源代码,构建AST和符号表,分析特殊情况的代码(树),并对代码(树)进行转换,最后重新生成修改后的代码(来自修改后的树)。 Java Front端使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> }
}
您可以根据需要定义“调用”对象,以记录结果。如果你想在那里放置额外的过滤器来消除错误线程中的数据,或者在某个时间窗口之间没有,或者在某个有趣的事件附近没有,你可以。这可能会大大减慢您的应用程序速度,至少如果您让仪器人对您的应用程序中的每个函数调用执行此操作。 (更复杂的转换可以控制它们的应用位置。)
答案 1 :(得分:0)
我查看Java调用堆栈的最佳方法是通过Eclipse调试器。如果您只是在代码中放置断点,您将能够单步执行代码并查看调用堆栈。
答案 2 :(得分:0)
我认为最简单的方法是使用JPDA(Java平台调试器架构)。您将不得不暂停所有线程,分析,转储信息和恢复线程。它不会是微不足道的,但从第一眼看就应该是可能的。