Explicitly constructed NPE is showing (wrong) message

Remi Forax forax at univ-mlv.fr
Sat Jun 27 12:41:26 UTC 2020


----- Mail original -----
> De: "Christoph Dreis" <christoph.dreis at freenet.de>
> À: "hotspot-runtime-dev" <hotspot-runtime-dev at openjdk.java.net>
> Envoyé: Samedi 27 Juin 2020 11:54:19
> Objet: Explicitly constructed NPE is showing (wrong) message

> Hi,

Hi Christoph,

> 
> I hope this is the correct mailing list.
> 
> The latest changes on JDK-8233014 to enable ShowCodeDetailsInExceptionMessages
> by default have uncovered a likely bug (I think).
> 
> To my understanding explicitly created NullPointerExceptions should not print
> any message.
> With the following example:
> 
> public class Main {
>	public static void main(String[] args) {
>		NullPointerException ex = new NullPointerException();
>		Throwable throwable = ex.fillInStackTrace();
>		System.out.println(throwable);
>	}
> }
> 
> I see the following output though:
> 
> java.lang.NullPointerException: Cannot invoke
> "java.lang.NullPointerException.fillInStackTrace()" (on slot 0) because "ex" is
> null
> 
> Which obviously is not really true.
> I was debugging the thing (hence the additional "on slot 0") output, but
> couldn't find the error so far.
> 
> I'm suspecting the error to be somewhere around bytecodeUtils.cpp 1155:
> 
>        if (name != vmSymbols::object_initializer_name()) {
>          int     type_index = cp->signature_ref_index_at(name_and_type_index);
>          Symbol* signature  = cp->symbol_at(type_index);
>          // The 'this' parameter was null. Return the slot of it.
>          return ArgumentSizeComputer(signature).size();
>        } else {
>          return NPE_EXPLICIT_CONSTRUCTED;
>        }
> 
> I initially hoped to find a fix for it directly, but I would probably need a bit
> more time for it, so I decided to report it.
> Is this a bug even or am I chasing ghosts here? In case it is, I would be happy
> about a mentioning somewhere in an eventual commit.

I see the issue.
The idea of the algorithm is to use the backtrace stored in the exception to try to find where the NPE occurs, here by calling fillStackTrace() emplicitly, you are changing the backtrace so getExtendedNPEMessage now use the new backtrace reporting the error in main() :(

One way to fix the issue is to record if fillInStackTrace is called more than once (by having two sentinels by example) and to not call getExtendedNPEMessage if it's the case. Obviously the new added sentinel has to work with the serialization.

> 
> Cheers,
> Christoph

regards,
Rémi


More information about the hotspot-runtime-dev mailing list