0

So, opcode 202 (1100 1010) is reserved for a breakpoint event according to the Java specification. I tried inserting a breakpoint opcode in a Java method with the help of the ASM library:

targetWriter.visitInsn(202);

but the JVM crashed with error message: no original bytecode found in ... at bci 0. After searching in the Hotspot implementation I found where this error is thrown:

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;
}

So according to this, the method needs to know about the breakpoint (it stores all its breakpoints in a list) but it doesn't know about it if it is directly set via code instrumentation.

Is there a workaround (without JVMTI) to set a breakpoint event with code instrumentation?

Nfff3
  • 321
  • 8
  • 24
  • No, breakpoint opcode is not supposed to be set directly. Why do you want to avoid JVM TI? What do you expect to happen when JVM reaches the breakpoint? – apangin Jun 10 '20 at 16:52
  • @apangin, I though that if I set a breakpoint directly, the JVM will stop there and Intellij IDEA's debugger will fire automatically. But I am not sure about the latter one. – Nfff3 Jun 10 '20 at 16:55

1 Answers1

3

Being a reserved opcode according to JVMS §6.2, breakpoint opcode is exclusively for the JVM internal use. It should not occur in the user generated class files.

When you inject the breakpoint instruction manually, JVM does not know what to do with it, and it does not know what original bytecode has been replaced.

Breakpoints are set with 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. Most Java IDEs use JDWP for debugging.

apangin
  • 92,924
  • 10
  • 193
  • 247
  • 2
    The spec does list it, e.g. see [this page](https://docs.oracle.com/javase/specs/jvms/se14/html/jvms-7.html), together with `impdep1` and `impdep2`. Which is kinda weird, considering that any unused opcode can be used by an implementation internally (and in fact, HotSpot does also use other opcodes internally). – Holger Jun 11 '20 at 07:16
  • 2
    Also worth linking, [JVMS §6.2](https://docs.oracle.com/javase/specs/jvms/se14/html/jvms-6.html#jvms-6.2). – Holger Jun 11 '20 at 07:32