<!DOCTYPE html>
<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  </head>
  <body>
    <p>>why is the call to abort() not triggering a coredump?</p>
    <p>I guess you mean that the JVM generates coredumps by calling
      abort() as I read in:<br>
<a class="moz-txt-link-freetext" href="https://github.com/openjdk/jdk/blob/jdk-25%2B36/src/hotspot/os/posix/os_posix.cpp#L2091">https://github.com/openjdk/jdk/blob/jdk-25%2B36/src/hotspot/os/posix/os_posix.cpp#L2091</a></p>
    <p>But glibc calls abort() and apparently doesn't generate the
      coredump.</p>
    <p>This is beyond my knowledge of the topic. The only thing I can
      try to help with is that I did a quick test you can see at:<br>
<a class="moz-txt-link-freetext" href="https://github.com/atorrescogollo/poc-jdk-sigabrt-coredump-bug/commit/891969416579c7d6a8df6f3b10007a7c78f8ae61">https://github.com/atorrescogollo/poc-jdk-sigabrt-coredump-bug/commit/891969416579c7d6a8df6f3b10007a7c78f8ae61</a></p>
    <p>The relevant code:</p>
    <blockquote>
      <pre>// src/main/kotlin/com/example/demo/controller/CrashController.kt
...
@RequestMapping("/crash")
class CrashController {
    @GetMapping("/abort")
    fun crashWithAbort(): String {
        return NativeCrasher.crashWithAbort()
    }
...


// src/main/kotlin/com/example/demo/native/NativeCrasher.kt
...
object NativeCrasher {
    init {
        LibraryLoader.load()
    }
    external fun crashWithAbort(): String
...


// src/main/c/native_crasher.c
...
JNIEXPORT void JNICALL Java_com_example_demo_native_NativeCrasher_crashWithAbort
  (JNIEnv *env, jobject obj)
{
    abort();
}
...</pre>
    </blockquote>
    <pre>
</pre>
    <p>If I hit the endpoint with JDK25:</p>
    <blockquote>
      <pre>curl localhost:8080/crash/abort

</pre>
    </blockquote>
    <p>I don't get any coredump from that but only this exit code:</p>
    <blockquote>
      <pre>exited with code 133

</pre>
    </blockquote>
    <p>The PoC repository uses docker and everything is pretty standard
      apart from the optional patched compilation of the JVM to register
      the SIGABRT handler:<br>
<a class="moz-txt-link-freetext" href="https://github.com/atorrescogollo/poc-jdk-sigabrt-coredump-bug/blob/891969416579c7d6a8df6f3b10007a7c78f8ae61/Dockerfile">https://github.com/atorrescogollo/poc-jdk-sigabrt-coredump-bug/blob/891969416579c7d6a8df6f3b10007a7c78f8ae61/Dockerfile</a></p>
    <blockquote>
      <pre>FROM amazoncorretto:25 AS amazoncorretto-25
#FROM amazoncorretto-25-patched AS amazoncorretto-25 # Use this instead to use the patched JVM</pre>
      <pre>FROM amazoncorretto-25

WORKDIR /app

# Copy built JAR from builder
COPY --from=builder /build/build/libs/*.jar app.jar

# Expose port
EXPOSE 8080

# Run application
ENTRYPOINT ["java", "-jar", "app.jar"]</pre>
    </blockquote>
    <p><br>
    </p>
    <p>Álvaro</p>
    <p><br>
    </p>
    <div class="moz-cite-prefix">On 16/2/26 22:33, David Holmes wrote:<br>
    </div>
    <blockquote type="cite"
      cite="mid:bde8964e-fca9-4b38-8d70-0ab6c20ed987@oracle.com">On
      16/02/2026 9:27 pm, Álvaro Torres Cogollo wrote:
      <br>
      <blockquote type="cite">I believe what happens is that something
        has a bug and does an invalid call to free() that makes glibc to
        call abort(). And since there is no handler for that, nothing
        generates a core dump and it just ends.
        <br>
        <br>
        Based on this stackoverflow post:
        <br>
        <a class="moz-txt-link-freetext" href="https://stackoverflow.com/a/151568">https://stackoverflow.com/a/151568</a>
        <br>
        <br>
             As for how to debug it, installing a handler for SIGABRT is
        probably the best way to proceed. You can set a breakpoint in
        your handler or deliberately trigger a core dump.
        <br>
      </blockquote>
      <br>
      I think you are missing my point. I get that glibc calls abort()
      but that in itself should trigger a coredump. You don't have to
      install a handler for SIGABRT for abort() to create a coredump.
      <br>
      <br>
      So my question remains: why is the call to abort() not triggering
      a coredump?
      <br>
      <br>
      I wonder if glibc doesn't actually call abort() but just raises
      SIGABRT directly? And if so why? It sounds like you can control
      what glibc does for these kinds of errors so perhaps you need to
      be telling glibc to do something different?
      <br>
      <br>
      David
      <br>
      ------
      <br>
      <blockquote type="cite">Álvaro
        <br>
        <br>
        <br>
        On 16/2/26 11:41, David Holmes wrote:
        <br>
        <blockquote type="cite">On 13/02/2026 7:25 pm, Álvaro Torres
          Cogollo wrote:
          <br>
          <blockquote type="cite">Hi,
            <br>
            <br>
            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.
            <br>
          </blockquote>
          <br>
          My query is: how is it calling abort but not getting a
          coredump?
          <br>
          <br>
          David
          <br>
          <blockquote type="cite">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.
            <br>
            <br>
            Regards,
            <br>
            <br>
            Álvaro
            <br>
            <br>
            <br>
            On 13/2/26 08:07, David Holmes wrote:
            <br>
            <blockquote type="cite">Hi,
              <br>
              <br>
              On 13/02/2026 3:16 am, Álvaro Torres Cogollo wrote:
              <br>
              <blockquote type="cite">Hi again,
                <br>
                <br>
                I just realized that I made a typo in the reproduction
                repository link. This is the right one:
                <br>
                <br>
<a class="moz-txt-link-freetext" href="https://github.com/atorrescogollo/poc-jdk-sigabrt-coredump-bug">https://github.com/atorrescogollo/poc-jdk-sigabrt-coredump-bug</a>
                <br>
                <br>
                Sorry about that.
                <br>
                <br>
                Álvaro
                <br>
                <br>
                <br>
                On 12/2/26 18:04, Álvaro Torres Cogollo wrote:
                <br>
                <blockquote type="cite">Hi,
                  <br>
                  <br>
                  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.
                  <br>
                </blockquote>
              </blockquote>
              <br>
              This is the right place (hotspot-runtime-dev would also
              have done but a narrower audience).
              <br>
              <br>
              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.
              <br>
              <br>
              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.
              <br>
              <br>
              Need to hear what other think about this.
              <br>
              <br>
              Cheers,
              <br>
              David
              <br>
              -----
              <br>
              <br>
              <blockquote type="cite">
                <blockquote type="cite">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.
                  <br>
                  <br>
                  Here's what we're seeing when it crashes:
                  <br>
                       munmap_chunk(): invalid pointer
                  <br>
                  <br>
                  Or when using tcmalloc:
                  <br>
                       src/tcmalloc.cc:333] Attempt to free invalid
                  pointer 0xffff38000b60
                  <br>
                  <br>
                  We're running with:
                  <br>
                       JAVA_TOOL_OPTIONS=-XX:+CreateCoredumpOnCrash
                  -XX:ErrorFile=/ core-dumps/hs_err_pid%p.log
                  <br>
                  <br>
                  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.
                  <br>
                  <br>
                  After digging through the hotspot source, I noticed
                  that signal handlers are installed for SIGSEGV,
                  SIGBUS, SIGFPE, etc., but not for SIGABRT:
                  <br>
                  <br>
                  <a class="moz-txt-link-freetext" href="https://github.com/openjdk/jdk/">https://github.com/openjdk/jdk/</a>
                  blob/37dc1be67d4c15a040dc99dbc105c3269c65063d/src/hotspot/os/
                  posix/ signals_posix.cpp#L1352-L1358
                  <br>
                  <br>
                  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.
                  <br>
                  <br>
                  To demonstrate the issue, I put together a small
                  reproduction case:
                  <br>
                  <br>
<a class="moz-txt-link-freetext" href="https://github.com/atorrescogollo/poc-jdk-sigabrt-coredump-handling">https://github.com/atorrescogollo/poc-jdk-sigabrt-coredump-handling</a>
                  <br>
                  <br>
                  The repo has a Spring Boot app with three endpoints
                  that show the problem:
                  <br>
                  <br>
                  1. /crash/unsafe - Uses Java Unsafe to write to
                  address 0
                  <br>
                     Result: SIGSEGV -> Works correctly, generates
                  hs_err file
                  <br>
                  <br>
                  2. /crash/null - JNI code that dereferences a null
                  pointer
                  <br>
                     Result: SIGSEGV -> Works correctly, generates
                  hs_err file
                  <br>
                  <br>
                  3. /crash/free - JNI code that calls free() on a stack
                  variable
                  <br>
                     Result: SIGABRT -> BROKEN, just prints
                  "munmap_chunk(): invalid pointer" and dies
                  <br>
                  <br>
                  You can reproduce it with:
                  <br>
                       docker-compose up -d
                  <br>
                       curl localhost:8080/crash/free
                  <br>
                       docker-compose logs
                  <br>
                  <br>
                  And you'll see it just prints the error and exits, no
                  hs_err file gets created.
                  <br>
                  <br>
                  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:
                  <br>
                  <br>
<a class="moz-txt-link-freetext" href="https://github.com/atorrescogollo/poc-jdk-sigabrt-coredump-bug/">https://github.com/atorrescogollo/poc-jdk-sigabrt-coredump-bug/</a> blob/
                  main/jdk17.patch
                  <br>
                  <br>
                  - Adds set_signal_handler(SIGABRT) in
                  signals_posix.cpp
                  <br>
                  - Resets SIGABRT to SIG_DFL before calling abort() in
                  os_posix.cpp to avoid recursive handling
                  <br>
                  <br>
                  After applying it, the /crash/free endpoint generates
                  proper diagnostics:
                  <br>
                       # SIGABRT (0x6) at pc=0x0000ffffbd177608 (sent by
                  kill), pid=1, tid=41
                  <br>
                       # Problematic frame:
                  <br>
                       # C  [libc.so.6+0x87608]
                  <br>
                       # Core dump will be written. Default location:
                  //core
                  <br>
                       # An error report file with more information is
                  saved as:
                  <br>
                       # /core-dumps/java_error1.log
                  <br>
                  <br>
                  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.
                  <br>
                  <br>
                  Thanks,
                  <br>
                  <br>
                  Álvaro
                  <br>
                  <br>
                </blockquote>
              </blockquote>
              <br>
            </blockquote>
          </blockquote>
          <br>
        </blockquote>
      </blockquote>
      ---
      <br>
      <br>
    </blockquote>
  </body>
</html>