You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Describe the bug
Runtime behavior is fine during execution, but a native crash occurs on program exit.
# A fatal error has been detected by the Java Runtime Environment:
#
# SIGSEGV (0xb) at pc=0x00007f310ed1610d, pid=252732, tid=0x00007f3140569700
#
# JRE version: OpenJDK Runtime Environment (8.0_432-b06) (build 1.8.0_432-432-b06)
# Java VM: OpenJDK 64-Bit Server VM (25.432-b06 mixed mode linux-amd64 compressed oops)
# Problematic frame:
# C [libwebrtc-java-linux-x86_642121276466645068163.so+0x4d010d] jni::JavaFactory<webrtc::RtpTransceiverInterface>::~JavaFactory()+0x2d
#
# Failed to write core dump. Core dumps have been disabled. To enable core dumping, try "ulimit -c unlimited" before starting Java again
#
# An error report file with more information is saved as:
# /home/dev/hs_err_pid252732.log
#
# A fatal error has been detected by the Java Runtime Environment:
#
# SIGSEGV (0xb) at pc=0x00007fd4b21817e7, pid=178907, tid=179957
#
# JRE version: OpenJDK Runtime Environment Corretto-25.0.0.36.2 (25.0+36) (build 25+36-LTS)
# Java VM: OpenJDK 64-Bit Server VM Corretto-25.0.0.36.2 (25+36-LTS, mixed mode, emulated-client, sharing, tiered, compressed oops, compressed class ptrs, g1 gc, linux-amd64)
# Problematic frame:
# C [libwebrtc-java-linux-x86_649756144665632658865.so+0x84a7e7]
#
# Core dump will be written. Default location: Core dumps may be processed with "/usr/lib/systemd/systemd-coredump %P %u %g %s %t %c %h %d %F" (or dumping to /home/kalgecin/***/core.178907)
#
# If you would like to submit a bug report, please visit:
# https://github.com/corretto/corretto-25/issues/
# The crash happened outside the Java Virtual Machine in native code.
# See problematic frame for where to report the bug.
#
--------------- S U M M A R Y ------------
Command Line: -Dvisualvm.id=12399302740675 -Xmx20G -XX:TieredStopAtLevel=1 -Dspring.output.ansi.enabled=always -Dcom.sun.management.jmxremote -Dspring.jmx.enabled=true -Dspring.liveBeansView.mbeanDomain -Dspring.application.admin.enabled=true -Dmanagement.endpoints.jmx.exposure.include=* -javaagent:/home/kalgecin/.local/share/JetBrains/Toolbox/apps/intellij-idea-ultimate/lib/idea_rt.jar=44989 -Dfile.encoding=UTF-8 -Dsun.stdout.encoding=UTF-8 -Dsun.stderr.encoding=UTF-8 com.****
Host: AMD Ryzen 5 3600 6-Core Processor, 12 cores, 62G, Manjaro Linux
Time: Thu Sep 25 09:43:23 2025 UTC elapsed time: 140.269789 seconds (0d 0h 2m 20s)
--------------- T H R E A D ---------------
Current thread (0x00007fd3b0025e10): JavaThread "Thread-10" [_thread_in_native, id=179957, stack(0x00007fd440eeb000,0x00007fd4416eb000) (8192K)]
Stack: [0x00007fd440eeb000,0x00007fd4416eb000], sp=0x00007fd4416e9d90, free space=8187k
Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)
C [libwebrtc-java-linux-x86_649756144665632658865.so+0x84a7e7]
C [libwebrtc-java-linux-x86_649756144665632658865.so+0x849ba6]
C [libwebrtc-java-linux-x86_649756144665632658865.so+0x84b1f9]
C [libc.so.6+0x969cb]
siginfo: si_signo: 11 (SIGSEGV), si_code: 2 (SEGV_ACCERR), si_addr: 0x00007fd41d2d88c8
Figured out my problem. I was trying to dispose peer connection factory from within PeerConnectionObserver (that was passed into factory.createPeerConnection). Changing the logic around fixed the problem.
Thanks for the detailed report and reproduction, and thanks @KF-Miyata for confirming this doesn't occur on JDK 17.
I looked into the crash trace more closely. It's happening in jni::JavaFactory<webrtc::RtpTransceiverInterface>::~JavaFactory() — but that class is never exercised by the repro (new AudioProcessing(); dispose();). That destructor only runs when the process-wide static factory map (JavaFactories::getFactoryMap()) is torn down at process exit, destroying every registered JavaFactory<T> in some order — it just happened to be RtpTransceiverInterface's turn when the crash was captured, it's not specific to that type.
~JavaFactory() itself is written defensively — it only calls javaClass.release(), which just nulls the held global ref without touching JNI, specifically so the subsequent JavaGlobalRef destructor becomes a no-op and never calls DeleteGlobalRef during static teardown. So the crash is likely one level deeper: something about the C++ static/global destruction order at process exit vs. the JVM's own shutdown/native-library-unload sequence on JDK 8 specifically (heap/allocator or std::any internals already torn down by the time this runs).
I checked the two most relevant native fixes merged recently (#283 — JNI reference-counting/lifetime bugs, #269 — JNI thread attach/detach on JVM shutdown) and neither touches JavaFactory/JavaFactories or this static-teardown path, so this isn't fixed by anything that's landed so far. (@kalgecin's crash further down this thread turned out to be a separate, self-inflicted issue — disposing the factory reentrantly from inside its own PeerConnectionObserver callback — so that one isn't additional evidence here.)
Since this seems specific to how JDK 8 tears down native libraries at process exit, and reproduction is difficult on newer JDKs, I likely need a JDK 8 environment myself to chase the actual static-destruction ordering. In the meantime — is System.exit() being called explicitly, or is this a plain fall-off-the-end-of-main shutdown? And does forcing a System.exit(0) right after dispose() change anything? That would help narrow down whether this is JVM-triggered shutdown-hook ordering vs. plain C++ atexit ordering.
Activity
devopvoid commentedon Sep 19, 2025
Thanks for the report! I see that you are using the OpenJDK Runtime Environment (8.0_432-b06), which is quite outdated.
Unfortunately, I can't reproduce the issue on AlmaLinux 8 using newer JDKs. I will try it with JDK 8 later.
Could you also try to reproduce this behaviour with JDK 17, for example?
KF-Miyata commentedon Sep 24, 2025
Thank you for your reply, and I apologize for the delay.
I have tested with JDK 17, and I can confirm that the issue does not occur with that version.
kalgecin commentedon Sep 25, 2025
I'm also seeing SIGSEGV on JVM 25
kalgecin commentedon Sep 26, 2025
but mine comes from peerConnectionFactory.dispose(). I will try to reproduce with minimal code and probably open a new ticket
kalgecin commentedon Sep 26, 2025
Figured out my problem. I was trying to dispose peer connection factory from within PeerConnectionObserver (that was passed into factory.createPeerConnection). Changing the logic around fixed the problem.
selfancy commentedon Nov 1, 2025
Can it be compatible with Java 8?
devopvoid commentedon Sep 13, 2026
Thanks for the detailed report and reproduction, and thanks @KF-Miyata for confirming this doesn't occur on JDK 17.
I looked into the crash trace more closely. It's happening in
jni::JavaFactory<webrtc::RtpTransceiverInterface>::~JavaFactory()— but that class is never exercised by the repro (new AudioProcessing(); dispose();). That destructor only runs when the process-wide static factory map (JavaFactories::getFactoryMap()) is torn down at process exit, destroying every registeredJavaFactory<T>in some order — it just happened to beRtpTransceiverInterface's turn when the crash was captured, it's not specific to that type.~JavaFactory()itself is written defensively — it only callsjavaClass.release(), which just nulls the held global ref without touching JNI, specifically so the subsequentJavaGlobalRefdestructor becomes a no-op and never callsDeleteGlobalRefduring static teardown. So the crash is likely one level deeper: something about the C++ static/global destruction order at process exit vs. the JVM's own shutdown/native-library-unload sequence on JDK 8 specifically (heap/allocator orstd::anyinternals already torn down by the time this runs).I checked the two most relevant native fixes merged recently (#283 — JNI reference-counting/lifetime bugs, #269 — JNI thread attach/detach on JVM shutdown) and neither touches
JavaFactory/JavaFactoriesor this static-teardown path, so this isn't fixed by anything that's landed so far. (@kalgecin's crash further down this thread turned out to be a separate, self-inflicted issue — disposing the factory reentrantly from inside its ownPeerConnectionObservercallback — so that one isn't additional evidence here.)Since this seems specific to how JDK 8 tears down native libraries at process exit, and reproduction is difficult on newer JDKs, I likely need a JDK 8 environment myself to chase the actual static-destruction ordering. In the meantime — is
System.exit()being called explicitly, or is this a plain fall-off-the-end-of-main shutdown? And does forcing aSystem.exit(0)right afterdispose()change anything? That would help narrow down whether this is JVM-triggered shutdown-hook ordering vs. plain C++atexitordering.