Debug GraalVM native images
IntelliJ IDEA allows you to debug GraalVM native images.
Install the GraalVM Native Debugger plugin
This functionality relies on the GraalVM Native Debugger plugin, which you need to install and enable.
Press Ctrl+Alt+S to open settings and then select
.Open the Marketplace tab, find the GraalVM Native Debugger plugin, and click Install (restart the IDE if prompted).
Operating systems
GraalVM builds are not yet capable of producing debug information for operating systems other than Linux.
For debugging a native image on another operating system, you have to compile the executable for Linux and run it in a Docker container. If you're on Windows, you can also use WSL for this purpose.
For requirements to the Docker container, refer to Docker image.
Prerequisites
Before debugging a GraalVM Native image, make sure to check the following prerequisites:
The artifact must be compiled with the debug information.
Debug information is metadata used by the debugger to understand the mapping between the running program and source code. It is controlled at the build stage by the compiler flags and is often absent in the production builds.
The artifact must be compiled with minimal (preferably zero) optimizations.
You might be able to debug a native executable with optimizations in place; however, this may limit the debugger functionality. For example, if the executable was compiled with the
-O2
optimization level (also referred to as release), you will only be able to examine the threads' stacks and some of the global variables.Since the debugger relies on the application's sources, make sure that you have access to the exact version of the sources that were used to build it.
In case of debugging in a Docker container or on a remote environment, the target must have gdbserver installed and running.
Local debugging on Linux
If you are running the executable using the GraalVM Native Image run configuration on Linux, you can debug it without additional setup.
Debug a 'GraalVM Native Image' run configuration
Select the run configuration in the run widget, then click Debug.
Attach to a running native executable
If you are not on Linux or not executing the program from IntelliJ IDEA, use the GraalVM Native Attach run configuration.
Create a run configuration
Click the run configuration menu in the run widget and select Edit Configurations.
Click Add New Configuration on the toolbar or press Alt+Insert, then select GraalVM Native Attach.
Specify the following values:
Attach string (host:port)
Host and port for attaching to the process in the following format:
host:port
.Use classpath of module
Select the module whose classpath will be used to compile the application.
Symbol file
The file with debug symbols. The debugger uses this information to map the compiled program's binary instructions back to the original source code.
System root
The directory for the debug symbols of the system libraries (such as libc) that are used on the remote host. If left blank, the debugger will search for these libraries' debug symbols on the remote host.
Source mappings
Optional source mapping for special cases. For example, if the remote app was built from sources in /tmp/buildserver/my_app/MyApp.java and you have the sources locally in /home/me_user/my_app/MyApp.java, the correct mapping will be:
/tmp/buildserver/my_app/ , /home/me_user/my_app/MyApp.java
After you have set up the GraalVM Native Attach run configuration, run the native executable as you normally would. When the target process has started, launch the run configuration that you created for debugging.
Launch a run configuration
Select the run configuration in the run widget, then click Debug.
When the debugger is successfully attached, the application output will appear in the console.
Terminate a debugger session
Click the Stop button in the Debug tool window.
Alternatively, press Ctrl+F2 and select the process to terminate (if there are two or more of them).
Docker image
You can use the following Docker image as a reference when debugging GraalVM native executables in a Docker container:
For steps to run and debug a Docker image, refer to Run targets.
Create objects from expressions
If you are going to evaluate expressions that involve creating new objects, you'll need to build the application with the following option:
The reflection-config.json file has to contain the following configuration: