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

Always record hidden frames in backtrace to improve helpfull NPEs

    XMLWordPrintable

Details

    • Enhancement
    • Resolution: Won't Fix
    • P4
    • tbd
    • 19
    • hotspot

    Description

      Currently, when a NullPointerException is happening in a hidden frame, the Helpful NullPointerException from JEP 358 won't show any helpful information at all.

      This is because we are running with -XX:-ShowHiddenFrames by default and this setting disables the recording of the offending NPE method and BCI. Without this information the Helpful NullPointerException feature has no chance to display additional information about the NPE.

      Consider the following trivial example from https://twitter.com/tagir_valeev/status/1530544950256992256

      import java.util.*;

      public class Demo {
        public static void main(String[] args) {
          List<String> input = Arrays.asList(null, " a ", " b ");
          List<String> list = input. stream().map(String::trim).toList();
        }
      }

      By default we get:

      $ java Demo
      Exception in thread "main" java.lang.NullPointerException
      at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:197)
      at java.base/java.util.Spliterators$ArraySpliterator.forEachRemaining(Spliterators.java:992)
      at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:509)
      at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:499)
      at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:575)
      at java.base/java.util.stream.AbstractPipeline.evaluateToArrayNode(AbstractPipeline.java:260)
      at java.base/java.util.stream.ReferencePipeline.toArray(ReferencePipeline.java:616)
      at java.base/java.util.stream.ReferencePipeline.toArray(ReferencePipeline.java:622)
      at java.base/java.util.stream.ReferencePipeline.toList(ReferencePipeline.java:627)
      at Demo.main(Demo.java:7)

      And only with -XX:+ShowHiddenFrames we get the much more helpfull:

      $ java -XX:+UnlockDiagnosticVMOptions -XX:+ShowHiddenFrames Demo
      Exception in thread "main" java.lang.NullPointerException: Cannot invoke "String.trim()" because "<parameter1>" is null
      at Demo$$Lambda$1/0x0000000801000a00.apply(Unknown Source)
      at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:197)
      at java.base/java.util.Spliterators$ArraySpliterator.forEachRemaining(Spliterators.java:992)
      at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:509)
      at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:499)
      at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:575)
      at java.base/java.util.stream.AbstractPipeline.evaluateToArrayNode(AbstractPipeline.java:260)
      at java.base/java.util.stream.ReferencePipeline.toArray(ReferencePipeline.java:616)
      at java.base/java.util.stream.ReferencePipeline.toArray(ReferencePipeline.java:622)
      at java.base/java.util.stream.ReferencePipeline.toList(ReferencePipeline.java:627)
      at Demo.main(Demo.java:7)

      We should consider to always record hidden frames in the backtrace constructed by java_lang_Throwable::fill_in_stack_trace() (or at least for the top frame if it is hidden) and only filter out the hidden frames later on when the actual stack trace is built in java_lang_Throwable::get_stack_trace_elements(). This will help the Helpful NullPointerException feature to be more helpful :)

      Attachments

        Issue Links

          Activity

            People

              Unassigned Unassigned
              simonis Volker Simonis
              Votes:
              0 Vote for this issue
              Watchers:
              4 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved: