Debug Native Image Generation
When using GraalVM native-image
to build native images, you may encounter exceptions thrown in the generation process. Native image generation is done using Java, so we can debug the generation process using Java remote debugging.
For example, when building a native image using GraalVM 20.0.0.2, in the creating image stage, the following NullPointerException
was thrown. As shown in the message, t.instantiatedTypes
is null
in the com.oracle.graal.pointsto.meta.AnalysisType
class.
Fatal error: com.oracle.svm.core.util.VMError$HostedError: java.lang.NullPointerException: Cannot invoke "com.oracle.graal.pointsto.flow.AllInstantiatedTypeFlow.addState(com.oracle.graal.pointsto.PointsToAnalysis, com.oracle.graal.pointsto.typestate.TypeState)" because "t.instantiatedTypes" is null
at com.oracle.svm.core.util.VMError.shouldNotReachHere(VMError.java:72)
at com.oracle.svm.hosted.NativeImageGenerator.doRun(NativeImageGenerator.java:656)
at com.oracle.svm.hosted.NativeImageGenerator.run(NativeImageGenerator.java:494)
at com.oracle.svm.hosted.NativeImageGeneratorRunner.buildImage(NativeImageGeneratorRunner.java:426)
at com.oracle.svm.hosted.NativeImageGeneratorRunner.build(NativeImageGeneratorRunner.java:587)
at com.oracle.svm.hosted.NativeImageGeneratorRunner.main(NativeImageGeneratorRunner.java:126)
at com.oracle.svm.hosted.NativeImageGeneratorRunner$JDK9Plus.main(NativeImageGeneratorRunner.java:617)
Caused by: java.lang.NullPointerException: Cannot invoke "com.oracle.graal.pointsto.flow.AllInstantiatedTypeFlow.addState(com.oracle.graal.pointsto.PointsToAnalysis, com.oracle.graal.pointsto.typestate.TypeState)" because "t.instantiatedTypes" is null
at com.oracle.graal.pointsto.meta.AnalysisType.lambda$registerAsInstantiated$4(AnalysisType.java:443)
at com.oracle.graal.pointsto.meta.AnalysisType.forAllSuperTypes(AnalysisType.java:526)
at com.oracle.graal.pointsto.meta.AnalysisType.forAllSuperTypes(AnalysisType.java:512)
at com.oracle.graal.pointsto.meta.AnalysisType.forAllSuperTypes(AnalysisType.java:508)
at com.oracle.graal.pointsto.meta.AnalysisType.registerAsInstantiated(AnalysisType.java:442)
at com.oracle.graal.pointsto.meta.AnalysisType.registerAsAllocated(AnalysisType.java:425)
at com.oracle.graal.pointsto.meta.AnalysisType.markReachable(AnalysisType.java:482)
at com.oracle.graal.pointsto.meta.AnalysisType.forAllSuperTypes(AnalysisType.java:526)
at com.oracle.graal.pointsto.meta.AnalysisType.forAllSuperTypes(AnalysisType.java:512)
at com.oracle.graal.pointsto.meta.AnalysisType.forAllSuperTypes(AnalysisType.java:508)
at com.oracle.graal.pointsto.meta.AnalysisType.registerAsReachable(AnalysisType.java:466)
at com.oracle.svm.hosted.ameta.AnalysisConstantReflectionProvider.registerAsReachable(AnalysisConstantReflectionProvider.java:290)
at com.oracle.svm.hosted.ameta.HostedDynamicHubFeature.replace(HostedDynamicHubFeature.java:53)
at com.oracle.graal.pointsto.meta.AnalysisUniverse.replaceObject(AnalysisUniverse.java:575)
at com.oracle.svm.hosted.image.NativeImageHeap.addArrayElements(NativeImageHeap.java:576)
at com.oracle.svm.hosted.image.NativeImageHeap.addObjectToImageHeap(NativeImageHeap.java:473)
at com.oracle.svm.hosted.image.NativeImageHeap.addObject(NativeImageHeap.java:295)
at com.oracle.svm.hosted.image.NativeImageHeap.processAddObjectWorklist(NativeImageHeap.java:598)
at com.oracle.svm.hosted.image.NativeImageHeap.addTrailingObjects(NativeImageHeap.java:198)
at com.oracle.svm.hosted.NativeImageGenerator.doRun(NativeImageGenerator.java:638)
... 5 more
To debug this issue, we need to update the native-image
options and add -J-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=5005
to the command. -J
means passing arguments to the JVM which runs the native image generation.
After running the native-image
command again, the process is suspended and waiting for a debugger to connect. We can use IDE to start remote debugging.
Open the AnalysisType.java
file in the IDE and add a breakpoint with condition t.instantiatedTypes == null
at line 443. When the breakpoint is hit, we can know the class which caused the issue.
This issue should have been fixed in the head of GraalVM source code.