libc.so SIGSEGV 上 busybox 上的 Openjdk 11 崩溃

Openjdk 11 on busybox crash on SIGSEGV in libc.so

我正在尝试基于带有 openjdk 11 的 busybox 创建 docker 图像,以获得最小 java 图像

我使用 progrium/busybox 作为包含 glibc 的基础映像并安装了缺少的 zlib.so:opkg-install zlib-dev
然后我从https://jdk.java.net/11/下载编译好的linuxjdk.

然后当尝试 运行 java -version 它输出版本但随后崩溃。 这是来自创建的日志:

#
# A fatal error has been detected by the Java Runtime Environment:
#
#  SIGSEGV (0xb) at pc=0x00007f6d7013d5c0, pid=47, tid=62
#
# JRE version: OpenJDK Runtime Environment (11.0.2+9) (build 11.0.2+9)
# Java VM: OpenJDK 64-Bit Server VM (11.0.2+9, mixed mode, tiered, compressed oops, g1 gc, linux-amd64)
# Problematic frame:
# C  [libc.so.6+0x385c0]  __call_tls_dtors+0x10
#

完整日志here

如果有任何关于如何解决此问题的建议或指导,我将不胜感激,谢谢

问题是您在基本映像中同时安装了 两个 版本的 libc - GNU libcmusl libc:

$ docker run -it progrium/busybox
/ #
/ # /lib64/libc.so.6
GNU C Library (Buildroot) stable release version 2.18, by Roland McGrath et al.
<...>
/ # 
/ # /lib64/libc.so
musl libc (x86_64)
<...>

opkg 提供的 libc 包是 musl libc,opkg 包中的所有二进制文件都是针对它构建的。这包括 zlib,因此,事实证明 musl libc 是 Java 二进制文件的传递依赖。

但是,Java 二进制文件本身是针对 GNU libc 构建的,因此您最终会同时加载两个 libc 版本:

/ # LD_DEBUG=libs /opt/jdk/jdk-11.0.2/bin/java
<...>
572: calling init: /lib64/libc.so
<...>
572: calling init: /lib/libc.so.6

结果是 ,在你的情况下这是一个分段错误。

如果你想从官方 OpenJDK 网站下载 JDK 版本,你必须使用 Alpine Linux OpenJDK 版本,因为 Alpine 也使用 musl libc

不幸的是,OpenJDK 11 不存在此构建,但您可以检查 Early Access OpenJDK 13 构建 Alpine Linux 是否运行良好(但请注意它是 不是一个稳定的发布版本!)。