Non urgent question on https://bugs.openjdk.java.net/browse/JDK-4834738 (Adding which Object is null to an NPE)
Volker Simonis
volker.simonis at gmail.com
Tue Feb 28 10:40:29 UTC 2017
Hi,
as Martijn mentioned, we've implemented something like this in our SAP JVM [1].
For a the following example:
public final NPE a() {
return new NPE();
}
public final NPE b() {
return null;
}
public final NPE c() {
return new NPE();
}
public static void m(NPE n) {
n.a().b().c();
}
calling m(new NPE()) would result in the following exception:
java.lang.NullPointerException: while trying to invoke the method
NPE.c() of a null object returned from NPE.b()
at NPE.m(NPE.java:66)
at NPE.main(NPE.java:74)
We're considering to contribute this (and other enhancements) to the
OpenJDK - it's just a matter of resources :) Moreover, this particular
enhancement is not trivial. It requires bytecode parsing in order to
find the source of a null pointer.
The implementation also interacts with the
-XX:+/-OmitStackTraceInFastThrow option. We, in the SAP JVM, have
switched it off, so we always get the full exception message as posted
above. But that comes at the cost of more deoptimizations, because
exceptions will not be thrown right from compiled code. Oracle/OpenJDK
have switched OmitStackTraceInFastThrow on by default. This leads to
exceptions being thrown right from the JITed code (i.e. "fast throw").
But the drawback is that these are just empty, preallocated exceptions
without message and stack trace.
Regards,
Volker
[1] https://tools.hana.ondemand.com/#cloud
On Tue, Feb 28, 2017 at 2:58 AM, David Holmes <david.holmes at oracle.com> wrote:
> On 28/02/2017 11:52 AM, Ioi Lam wrote:
>>
>> On 2/27/17 5:34 PM, David Holmes wrote:
>>>
>>> On 28/02/2017 11:14 AM, Ioi Lam wrote:
>>>>
>>>> Now sure if this has been suggested before -- how about including the
>>>> BCI in the exception message. That will tell you exactly where the
>>>> exception happened. In fact we can do this for any exception, not just
>>>> NPEs. Like:
>>>
>>>
>>> One of the bug reports references BCIs. Not sure how useful that is to
>>> the end developer though as they typically want to map an exception to
>>> a place in the source code.
>>>
>> It's better than nothing. I'd assume if this problem has bothered you so
>> much to cause you to file a bug, then you would feel enough motivation
>> to use the BCI :-)
>
>
> Most Java developers don't even know what BCI stands for! :)
>
>> Anyhow, the Java class simply doesn't carry enough debugging information
>> to tell you which position of a source line triggered the exception, like
>>
>> foo.bar(x.y(), a.b);
>>
>> Is it the dereference of foo, x or a?
>
>
> Hence the suggestions to report the member access that triggered the NPE -
> eg:
>
> - call to bar() on null reference
> - call to y() on null reference
> - access of b on null reference
>
>> One possibility is to update the Java class file format:
>>
>> LineNumberTable_attribute {
>> u2 attribute_name_index;
>> u4 attribute_length;
>> u2 line_number_table_length;
>> { u2 start_pc;
>> u2 line_number;
>> } line_number_table[line_number_table_length];
>> }
>>
>> To add a "column_number" next to the line_number. Then, the exception
>> message could be enhanced to
>>
>> java.lang.NullPointerException
>> at Test.testNPE(Test.java:14:5)
>> at Test.main(Test.java:8:xx)
>>
>> Where "5" is the column on line 14 that triggered the exception.
>
>
> :) Not sure how you'd carry that through to JITed code, but I like it.
>
> Cheers,
> David
>
>
>> - Ioi
>>
>>
>>> Cheers,
>>> David
>>>
>>>>
>>>> try {
>>>> someThingSecure().someThingElseSecure().evenMoreSecure();
>>>> } catch (Security Exception e) {
>>>> e.printStackTrace();
>>>> }
>>>>
>>>> - Ioi
>>>>
>>>> On 2/27/17 4:45 AM, David Holmes wrote:
>>>>>
>>>>> Hi Martijn,
>>>>>
>>>>> On 27/02/2017 10:03 PM, Martijn Verburg wrote:
>>>>>>
>>>>>> Hi all,
>>>>>>
>>>>>> The topic of adding more useful information to an NPE came up on the
>>>>>> Java
>>>>>> Champions list and after some digging we discovered some
>>>>>> implementations
>>>>>> elsewhere (SAP VM for example) and some historical conversations /
>>>>>> issues.
>>>>>>
>>>>>> https://bugs.openjdk.java.net/browse/JDK-4834738
>>>>>>
>>>>>> http://mail.openjdk.java.net/pipermail/hotspot-dev/2014-April/013535.html
>>>>>>
>>>>>>
>>>>>
>>>>> As I state in that linked topic that request was almost the inverse of
>>>>> other requests in this area - it wanted to report the method invoked
>>>>> on the null reference, whereas other requests were seeking more
>>>>> information on where the null arose eg in:
>>>>>
>>>>> a().b().c();
>>>>>
>>>>> which invocation produced the NPE. But thinking about it again,
>>>>> perhaps reporting the member access that triggered the NPE is the most
>>>>> generally useful information to provide.
>>>>>
>>>>>> The bug is listed as won't fix but didn't have any explanation added
>>>>>> to it
>>>>>> as to why. Is it just a case that the JIT and/or other mechanisms
>>>>>> strips
>>>>>> away that sort of information at runtime?
>>>>>
>>>>>
>>>>> The bug was closed as "won't fix" as part of a general cleanup up of
>>>>> old issues for which there are no active plans to address the issue.
>>>>>
>>>>> As I've commented in some of the issues where this was raised (and
>>>>> they are all quite old) there is a general lack of context available
>>>>> to give a meaningful error message about the NPE.
>>>>>
>>>>> Cheers,
>>>>> David
>>>>>
>>>>>> Cheers,
>>>>>> Martijn
>>>>>>
>>>>
>>
>
More information about the hotspot-dev
mailing list