如何使用检测在 Java 代码中设置断点?

How to set a breakpoint in Java code with instrumentation?

因此,根据 Java 规范,操作码 202 (1100 1010)reserved for a breakpoint event。我尝试在 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)来使用代码检测设置断点事件?

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

当你手动注入断点指令时,JVM不知道如何处理它,也不知道原来的字节码被替换了什么。

使用 JVM TI SetBreakpoint event, and notifications are received via Breakpoint event callback. If you don't want to use JVM TI directly, the alternative is JDWP 设置断点。大多数 Java IDE 使用 JDWP 进行调试。