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

Invalid stack traces in JFR when approximating due to a lack of debug information in compiled code

XMLWordPrintable

    • jfr
    • Cause Known
    • x86

      Flight Recording contains stack traces that actually never occured during execution.

      --- Example: ArrayListGrow.java ---

      import java.util.ArrayList;
      import java.util.List;

      public class ArrayListGrow {
         static final int SIZE = 2048;
         static volatile List<Object> tmp;

          static void runTest() {
              List<Object> list = new ArrayList<>(SIZE);
              fill(list);
              tmp = list;
          }

          static void fill(List<Object> list) {
              for (int i = 0; i < SIZE; i++) {
                  list.add(i);
              }
          }

          static void spoil() {
              for (int i = 0; i < 1000000; i++) {
                  new ArrayList<>(0).add("");
              }
          }

          public static void main(String[] args) {
              spoil();

              while (true) {
                  runTest();
              }
          }
      }

      ---

      Start
      java -XX:+UnlockDiagnosticVMOptions -XX:+DebugNonSafepoints -XX:StartFlightRecording=filename=out.jfr ArrayListGrow

      Let it run for ~10 seconds, and then open the produced out.jfr.
      It will contain the considerable number of execution samples with the following stack trace:

      java.util.ArrayList.grow(int):239
      java.util.ArrayList.grow():244
      java.util.ArrayList.add(Object, Object[], int):454
      java.util.ArrayList.add(Object):467
      ArrayListGrow.fill(List):16
      ArrayListGrow.runTest():10
      ArrayListGrow.main(String[]):30

      // see https://cr.openjdk.java.net/~apangin/8281677/img/jfr-screenshot.png

      However, this stack trace could not occur during execution, since the ArrayList is created with the sufficient initial size and never grows.

      The reason is the wrong PcDesc information in the compiled code. Besides JFR, the problem affects other profiling and benchmarking tools, including async-profiler, perf-map-agent, and JMH. Originally, the issue was raised in async-profiler repository: https://github.com/jvm-profiling-tools/async-profiler/discussions/541

      The version I tested:
      OpenJDK 64-Bit Server VM (build 18-ea+35-2085, mixed mode, sharing)

      I see the same problem on recent builds of JDK 11, but not on JDK 8.

      Curiously, if I comment out // spoil() call in the above example, the profile will be correct.
      With `-XX:-TieredCompilation`, there is no problem either.

            mgronlun Markus Grönlund
            apangin Andrei Pangin
            Votes:
            2 Vote for this issue
            Watchers:
            8 Start watching this issue

              Created:
              Updated: