Byte Buddy Advice 破坏了 Eclipse 调试器

我已经使用 net.bytebuddy.asm.Advice 在适当注释的方法之前和之后添加代码,以启动和停止计时器。修改后的类在它们的原始类可以被引用之前被手动加载到目标类加载器中,从而取代它们。我正在使用 OSGi (Equinox)。


非常棒,但是当我在目标方法的断点上停止 Eclipse (Photon 4.8.0) 调试器时,变量视图仅显示:


com.sun.jdi.InternalException:在回复中得到错误代码:35 发生从堆栈帧检索“this”。


这是不可避免和不可避免的吗?如果这使得检测的代码不可调试,那有点破坏了我的用例:(


(我已禁用选项“在步骤操作后显示方法结果(如果 VM 支持;可能很慢”。)


例子

我相信我可能已经发现生成的字节码存在一些问题。


要检测的类:


 1 package com.tom.test;

 2

 3 import com.tom.instrument.Instrumented;

 4 import com.tom.instrument.Timed;

 5

 6 @Instrumented(serviceType = "blah")

 7 public class Test {

 8

 9 @Timed

10 public void writeName() {

11   final String myLocal = "Tom";

12      System.out.println(myLocal);  

13   }

14

15 }

“建议”:


package com.tom.instrument;


import net.bytebuddy.asm.Advice.OnMethodEnter;


public class Instrumentation {


    @OnMethodEnter

    public static void onMethodEnter() {

        System.out.println("Enter");

    }


}

呼叫字节好友:


new ByteBuddy()

    .redefine(type, ClassFileLocator.ForClassLoader.of(this.classLoader))

    .visit(Advice.to(Instrumentation.class)

    .on(isAnnotatedWith(Timed.class)))

    .make().saveIn(new File("instrumented"));

也许这是 Eclipse 调试器希望this始终位于插槽 0 中的错误?或者也许这就是它应该的方式。不过,错误代码 35 来自 JVM。

添加退出建议更改插槽的原因似乎是因为它导致ForInstrumentedMethod.Default.Copying使用而不是Simple. 他们有不同的variable().


qq_遁去的一_1
浏览 203回答 2
2回答

临摹微笑

请参阅Eclipse 错误 531706:当并非所有类都已检测时会出现此问题,请参阅Tobias Hirning 的评论 #4:...现在我也有了更清晰的认识:错误仅出现在方法位于 jar 文件中的方法调用中。我认为他们没有使用仪器。...错误发生在 VM 中,而不是 Eclipse 中。当 Eclipse 通过调试接口请求变量时,会返回错误代码35而不是值。由于提到的错误报告所做的更改是忽略它,请参阅Till Brychcy(做出更改的人)的评论 #7:...我已经能够重现该问题,只需忽略此代码路径中的 InternalException 即可改善这种情况。您有时会在变量视图中看到有关错误代码 35 的消息,但通常它似乎有效。为避免此问题,您必须检测所有类。

慕的地6264312

解决方法啊哈!我四处寻找补丁的所有钓鱼活动使我找到了我希望早点找到的东西。我可以@OnMethodEnter(prependLineNumber = false)用来避免行号的问题。并且使用@OnMethodExit(backupArguments = false)避免了插槽的问题。这对我来说是个好消息!然而,据推测,这些并不是有充分理由的默认值。我还不明白使用这些选项是否会产生重要的负面影响。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java