adoptium / adoptium/adoptium-support
Launching with AOT cache fatally crashes with SIGILL (0x4) depending on available CPU instructions
- Dominant language
- No language data
- Stars
- 59
- Forks
- 13
- PR merge metrics
- No merged PRs in 30d
Description
### Please provide a brief summary of the bug
NOTE: I'm first reporting this issue here because the crash report told me so, however this is likely a general JVM bug and should likely be reported upstream at `bugs.openjdk.org` once clarified.
### Situation
We're using the [AOT cache](https://openjdk.org/jeps/483) to speed up the boot of a (Spring Boot) application.
However - depending on the used CPU - this causes a fatal crash at runtime.
This seems to happen when the AOT cache contains certain CPU instructions that are not supported by the executing CPU at runtime.
Related issue with more information: https://github.com/xdev-software/tci/issues/688
We detected the issue because GitHub provided Actions (CI) runners seem to sometimes support AVX512 and sometimes not which causes problems when we re-use AOT cache between CI runs.
The problem was also already described here: https://www.coffeesprout.nl/en/quarkus-jdk25-aot-cache-cpu-mismatch.html however I do not concur with the conclusions of the author/AI.
### Did you test with the latest update version?
- [x] Yes
### Please provide steps to reproduce where possible
1. Train/Create the AOT cache on a machine that supports AVX512 instructions (e.g. [Zen4+](https://en.wikipedia.org/wiki/AVX-512#CPUs_with_AVX-512))
2. Copy it over to non AVX512 machine - The machine requires the same OS (I used Docker on Windows for this)
3. Run it → crash with `SIGILL`
Real world example: https://github.com/xdev-software/tci/issues/688#issuecomment-4955275659
### Expected Results
No crash occurs; AOT is used.
---
[JEP483](https://openjdk.org/jeps/483) mentions that the hardware architecture needs to be the same to use the AOT cache:
> To enjoy the benefits of the AOT cache generated during a training run, the training run and all subsequent runs must be essentially similar.
> * All runs must use the same JDK release and be on the same hardware architecture (e.g., x64 or aarch64) and operating system.
The [Java docs](https://download.java.net/java/early_access/loom/docs/specs/man/java.html) also mention:
> * auto or on: These modes should be used in the Production phase. If -XX:AOTCache=cachefile is specified, the JVM tries to load cachefile as the AOT cache. ...
> ...
> When the AOT cache fails to load:
> * If AOTMode is auto, the JVM will continue execution without using the AOT cache. This is the recommended mode for production environments, especially when you may not have complete control of the command-line (e.g., your application's launch script may allow users to inject options to the command-line). This allows your application to function correctly, although sometimes it may not benefit from the AOT cache.
I therefore would expect that
* AOTCaching works with the same architectures when everything else is the same (OS, commandline). e.g. any Alpine-Linux x64 machine should be able to use AOT cache created by any other Alpine-Linux x64 machine
* Even if it fails to use the AOT cache due to diverging CPU instructions it should simply print an error/warning like "Can't use AOT cache" and not fatally crash with a hard SIGILL
It might also be an idea to make it possible to provide the maximum targeted CPU instruction set during AOT cache training (e.g. something like https://gcc.gnu.org/onlinedocs/gcc/x86-Options.html e.g. `-mavx2`)
### Actual Results
Fatal error: [`SIGILL (0x4)` with `Problematic frame: v ~AdapterBlob ...`](https://github.com/xdev-software/tci/issues/688#issuecomment-4955796480)
[hs_err_pid1.log](https://github.com/user-attachments/files/29961231/hs_err_pid1.log)
Decompiled instructions:
https://github.com/xdev-software/tci/issues/688#issuecomment-4955990681
> Registers `xmm16` to `xmm32` only exist with [AVX512](https://en.wikipedia.org/wiki/AVX-512#Opmask_registers)
### What Java Version are you using?
openjdk 25.0.3 2026-04-21 LTS OpenJDK Runtime Environment Temurin-25.0.3+9 (build 25.0.3+9-LTS) OpenJDK 64-Bit Server VM Temurin-25.0.3+9 (build 25.0.3+9-LTS, mixed mode, sharing)
### What is your operating system and platform?
Creating/Training system:
* AMD Ryzen 9700X (Zen 5, AVX512)
* Docker Desktop on Windows (WSL) using `eclipse-temurin:25-jdk-alpine`
Executing/Runtime system:
* AMD Ryzen 3700X (Zen 2; AVX2)
* Docker Desktop on Windows (WSL) using `eclipse-temurin:25-jdk-alpine`
### How did you install Java?
See above; Docker
### Did it work before?
```Shell
N/A
```
### Did you test with other Java versions?
```Shell
The only LTS supporting AOT is currently 25
```
### Relevant log output
```Shell
See hs_err_pid file above
```
Contributor guide
Research direction
Start with the linked hs_err_pid1.log, the SIGILL in AdapterBlob, and the reproduction steps using the AOT cache across the Zen 5 and Zen 2 systems. Compare behavior in auto mode and inspect the referenced JEP 483 and Java AOTCache documentation. Done means a minimal confirmed reproduction and a clear determination of whether the cache should be rejected or reported upstream.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- docker, java, spring-boot
- Domain
- backend, operating-systems
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 42/100