Java调用序列分析

问题描述

| 我希望能够可视化给定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平台调试器体系结构)。您将不得不暂停所有线程,分析,转储信息并恢复线程。这将不是小事,但是从一开始就应该是可能的。