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

Invalid stack traces in JFR profile due to wrong DebugInfo generated by C2

    XMLWordPrintable

    Details

      Description

      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.

        Attachments

          Issue Links

            Activity

              People

              Assignee:
              thartmann Tobias Hartmann
              Reporter:
              apangin Andrei Pangin
              Votes:
              1 Vote for this issue
              Watchers:
              6 Start watching this issue

                Dates

                Created:
                Updated:
                Resolved: