IntelliJ IDEA 2024.3 Help

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.

  1. Press Ctrl+Alt+S to open settings and then select Plugins.

  2. 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

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

  1. Click the run configuration menu in the run widget and select Edit Configurations.

  2. Click Add New Configuration on the toolbar or press Alt+Insert, then select GraalVM Native Attach.

  3. 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

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).

    the Stop button on the debugger toolbar

Docker image

You can use the following Docker image as a reference when debugging GraalVM native executables in a Docker container:

ARG JAVA_VERSION=21 FROM ghcr.io/graalvm/native-image-community:${JAVA_VERSION} RUN microdnf update -y oraclelinux-release-el9 \ && microdnf --enablerepo ol9_codeready_builder install -y gdb-gdbserver gcc maven \ && microdnf clean all

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:

-H:ReflectionConfigurationFiles=reflection-config.json

The reflection-config.json file has to contain the following configuration:

[ { "name" : "jdk.internal.misc.Unsafe", "methods": [ { "name": "getUnsafe" }, { "name": "allocateInstance" } ] } ]
Last modified: 06 August 2024