SIGABRT signals don't create core dumps
Álvaro Torres Cogollo
atorrescogollo at gmail.com
Fri Feb 13 09:25:39 UTC 2026
Hi,
In my opinion, I think it's fair to assume that other libraries
shouldn't call abort() if they actively don't want it to generate a core
dump. At least in the context of a Spring Boot server, I can't think of
a valid reason to call abort from a library and don't expect a core dump.
However, I understand the concern about handling SIGABRT signals in
hosting environments. I'm also missing a huge context on the
implications of this. Maybe it's enough to create a flag
like -XX:+CreateCoreDumpOnAbort, -XX:+HandleAbort or -XX:+CrashOnAbort.
That could be a best-practice configuration so far in certain contexts
(Spring Boot) and eventually consider making this the default behaviour.
Regards,
Álvaro
On 13/2/26 08:07, David Holmes wrote:
> Hi,
>
> On 13/02/2026 3:16 am, Álvaro Torres Cogollo wrote:
>> Hi again,
>>
>> I just realized that I made a typo in the reproduction repository
>> link. This is the right one:
>>
>> https://github.com/atorrescogollo/poc-jdk-sigabrt-coredump-bug
>>
>> Sorry about that.
>>
>> Álvaro
>>
>>
>> On 12/2/26 18:04, Álvaro Torres Cogollo wrote:
>>> Hi,
>>>
>>> We've been hitting a problem in production that I think might be a
>>> bug in hotspot's signal handling. Let me know if this should go
>>> somewhere else.
>
> This is the right place (hotspot-runtime-dev would also have done but
> a narrower audience).
>
> Not sure it is a bug as such. I'm missing a piece of the puzzle here.
> These other libraries are presumably calling abort() to raise the
> SIGABRT but there is no coredump. Yet if the VM calls abort() there is
> a coredump. I'm not seeing why there would be different behaviour.
>
> Catching SIGABRT in the VM then re-calling abort() may fix your issue,
> but I'm not sure if it could introduce problems for hosting
> environments which may already catch SIGABRT themselves.
>
> Need to hear what other think about this.
>
> Cheers,
> David
> -----
>
>>> The issue is that when a native library crashes due to memory
>>> corruption (like an invalid free() call), the JVM exits immediately
>>> without generating any core dump or error report, even though we
>>> have -XX:+CreateCoredumpOnCrash enabled.
>>>
>>> Here's what we're seeing when it crashes:
>>> munmap_chunk(): invalid pointer
>>>
>>> Or when using tcmalloc:
>>> src/tcmalloc.cc:333] Attempt to free invalid pointer
>>> 0xffff38000b60
>>>
>>> We're running with:
>>> JAVA_TOOL_OPTIONS=-XX:+CreateCoredumpOnCrash
>>> -XX:ErrorFile=/core-dumps/hs_err_pid%p.log
>>>
>>> But when these crashes happen, we get nothing - just the error
>>> message above and the process dies. This makes debugging really
>>> difficult, especially since the crashes happen randomly in production.
>>>
>>> After digging through the hotspot source, I noticed that signal
>>> handlers are installed for SIGSEGV, SIGBUS, SIGFPE, etc., but not
>>> for SIGABRT:
>>>
>>> https://github.com/openjdk/jdk/
>>> blob/37dc1be67d4c15a040dc99dbc105c3269c65063d/src/hotspot/os/posix/
>>> signals_posix.cpp#L1352-L1358
>>>
>>> When glibc detects the memory corruption, it calls abort() which
>>> raises SIGABRT. Since there's no handler for it, the JVM can't catch
>>> it and generate the diagnostics.
>>>
>>> To demonstrate the issue, I put together a small reproduction case:
>>>
>>> https://github.com/atorrescogollo/poc-jdk-sigabrt-coredump-handling
>>>
>>> The repo has a Spring Boot app with three endpoints that show the
>>> problem:
>>>
>>> 1. /crash/unsafe - Uses Java Unsafe to write to address 0
>>> Result: SIGSEGV -> Works correctly, generates hs_err file
>>>
>>> 2. /crash/null - JNI code that dereferences a null pointer
>>> Result: SIGSEGV -> Works correctly, generates hs_err file
>>>
>>> 3. /crash/free - JNI code that calls free() on a stack variable
>>> Result: SIGABRT -> BROKEN, just prints "munmap_chunk(): invalid
>>> pointer" and dies
>>>
>>> You can reproduce it with:
>>> docker-compose up -d
>>> curl localhost:8080/crash/free
>>> docker-compose logs
>>>
>>> And you'll see it just prints the error and exits, no hs_err file
>>> gets created.
>>>
>>> I also tested a potential fix by adding SIGABRT handling to hotspot.
>>> With that change, scenario 3 correctly generates an hs_err file and
>>> core dump. The patch basically:
>>>
>>> https://github.com/atorrescogollo/poc-jdk-sigabrt-coredump-bug/blob/
>>> main/jdk17.patch
>>>
>>> - Adds set_signal_handler(SIGABRT) in signals_posix.cpp
>>> - Resets SIGABRT to SIG_DFL before calling abort() in os_posix.cpp
>>> to avoid recursive handling
>>>
>>> After applying it, the /crash/free endpoint generates proper
>>> diagnostics:
>>> # SIGABRT (0x6) at pc=0x0000ffffbd177608 (sent by kill), pid=1,
>>> tid=41
>>> # Problematic frame:
>>> # C [libc.so.6+0x87608]
>>> # Core dump will be written. Default location: //core
>>> # An error report file with more information is saved as:
>>> # /core-dumps/java_error1.log
>>>
>>> I'm not sure if there's a specific reason why SIGABRT isn't handled
>>> currently. If there is, are there any alternative approaches to
>>> capture diagnostics when native libraries trigger abort()? For us
>>> and probably others dealing with native library bugs in production,
>>> having some way to get these diagnostics would be really valuable.
>>>
>>> Thanks,
>>>
>>> Álvaro
>>>
>
More information about the hotspot-dev
mailing list