Skip to main content

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.

note

This issue should have been fixed in the head of GraalVM source code.