Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8307331

Correctly update line maps when class redefine rewrites bytecodes

XMLWordPrintable

    • b22
    • generic
    • generic

        Class VM_RedefineClasses sometimes modifies the *new* bytecode it is presented. This can occur when the the old and new class's constant pools differ. VM_RedefineClasses constructs a merged constant pool, supplementing all the entries found in the old class bytecode with all extra, distinct entries found in the new bytecode. This may relocate some of the new entries, necessitating rewrites to pool indices appearing as operands in the newly supplied method bytecode.

        Normally, the rewritten operations occupy the same number of bytes as the original. However, in the case of an some operations the updated index for the merged pool may no longer fit into 8 bits and require use of an alternative operation that allows a 16 bit index, for example an ldc may need to be replaced with a ldc_w. In such cases this requires adjustment of all offsets that reference later operations.

        Class VM_RedefineClasses correctly adjust all offsets in the method bytecode and also includes logic to update offsets in the line number table. However, it fails to adjust line numbers correctly when more than one such change is required. Each adjustment is applied independently to a new copy the method's original line number table. What is needed is for them to be applied cumulatively to a single new copy.

        This problem can manifest as a JVM forced exit when debugging via JDWP. If a debugger hot swaps a class that requires several replacements and then places a line break which targets a bytecode operation that follows the first modified bytecode then the JDWP agent will use an invalid line map to identify the first bytecode instruction for the line, the location at which it expects to temporarily swap the actual, correct bytecode with a breakpoint pseudo-bytecode. Since this location can be off by one (or more) the agent may end up overwriting a bytecode instruction operand rather than a proper instruction. In many cases this mistake be caught as a verify error, leading to a forced exit, but it is also possible that the program will continue to execute valid yet incorrect bytecode.

              adinn Andrew Dinn
              adinn Andrew Dinn
              Votes:
              0 Vote for this issue
              Watchers:
              5 Start watching this issue

                Created:
                Updated:
                Resolved: