使用 Byteman 时,我们必须在规则语法中指定类和方法。如果我想使用 Byteman 跟踪程序执行怎么办?
示例:我不知道在执行程序的某个功能时正在执行哪些方法。我想在功能执行期间识别调用的方法。
这是否意味着我必须为给定包中每个类的每个方法添加规则?或者有没有其他方法可以实现这一目标?
是的,基本上您需要为要跟踪的每种方法制定一个规则(尽管有一种简单的方法可以做到这一点——见下文)。
Byteman 故意避免在它注入的 CLASS 和 METHOD 中使用通配符模式。那是因为使用这些规则会极大地降低 JVM 的速度。
为什么?好吧,每次加载一个类时,Byteman 都会被问到“你想通过注入一些代码来转换这个类吗?”。目前,Byteman 按 CLASSNAME 索引所有加载的规则。因此,回答这个问题涉及到哈希表查找(实际上,有两个——一个带有裸名,另一个带有包限定名)。这意味着没有答案(几乎总是正确的答案)是超级快速的。如果 Byteman 允许 CLASSNAME 的模式,那么它就不能依赖简单的哈希查找。
例如,如果你有一个像 CLASS org 这样的模式。.Foo和 2 个类,如 org.my.app.FooBar 和 org.my.app.Bletch 您如何确定第一个匹配而第二个不匹配?您必须为每个类名的每个模式规则尝试模式匹配。即使是单个模式匹配也比哈希表查找要昂贵得多。如果您使用多个基于模式的规则,则成本将根据规则的数量成倍增加。
好的,那么您如何解决 Byteman 的这个限制呢?如果您想检测很多类+方法,那么我建议您使用一个程序来生成一个规则脚本,其中包含您感兴趣的每个类+方法的规则。编写一个程序来读取包含以下条目的文件
类名称 1 方法模式 1 类名称 2 方法模式 2 。. .
该文件说我想检测 CLASS class_name1 的所有方法,其方法与 method_pattern1 匹配,依此类推。
只要目标 jar 在您的类路径中,您就可以使用当前的类加载器按名称加载每个类(调用 this.getClass().getClassLoader() 来获取类加载器,然后调用 classloader.loadClass(class_name) 来获取所需的班级)。使用反射来获取类的方法列表。对于每个方法,如果该方法的名称与相应的 method_pattern 匹配,则将 AT ENTRY 规则和/或 AT EXIT 规则输出到您的脚本文件。
如果您想查看一些与此类似的代码,请查看作为 Byteman 源的一部分的 contrib/dtest 包。
https://github.com/bytemanproject/byteman/tree/master/contrib/dtest
如果您对 Byteman 有任何疑问,请在项目提供的官方 Byteman 用户论坛上提问:
https://developer.jboss.org/en/byteman?view=discussions
问候,
Andrew Dinn(Byteman 项目负责人)