0

因此,根据 Java 规范,操作码202 (1100 1010)为断点事件保留的。我尝试在 ASM 库的帮助下在 Java 方法中插入断点操作码:

targetWriter.visitInsn(202);

但是 JVM 崩溃并显示错误消息:no original bytecode found in ... at bci 0. 在 Hotspot 实现中搜索后,我发现了引发此错误的位置:

Bytecodes::Code Method::orig_bytecode_at(int bci) const {
  BreakpointInfo* bp = method_holder()->breakpoints();
  for (; bp != NULL; bp = bp->next()) {
    if (bp->match(this, bci)) {
      return bp->orig_bytecode();
    }
  }
  {
    ResourceMark rm;
    fatal(err_msg("no original bytecode found in %s at bci %d", name_and_sig_as_C_string(), bci));
  }
  return Bytecodes::_shouldnotreachhere;
}

因此,根据这一点,该方法需要知道断点(它将所有断点存储在一个列表中),但如果它是通过代码检测直接设置的,则它不知道它。

是否有解决方法(没有 JVMTI)来使用代码检测设置断点事件?

4

1 回答 1

3

作为根据JVMS §6.2的保留操作码,断点操作码仅供 JVM 内部使用。它不应该出现在用户生成的类文件中。

当你手动注入断点指令时,JVM 不知道如何处理它,也不知道替换了哪些原始字节码。

断点通过 JVM TI SetBreakpoint事件设置,通知通过Breakpoint事件回调接收。如果您不想直接使用 JVM TI,另一种选择是JDWP。大多数 Java IDE 使用 JDWP 进行调试。

于 2020-06-10T19:03:33.280 回答