Mono 本机二进制包无法在较新的 Linux 内核中加载 libc

Posted

技术标签:

【中文标题】Mono 本机二进制包无法在较新的 Linux 内核中加载 libc【英文标题】:Mono native binary bundle fails to load libc in newer Linux kernels 【发布时间】:2014-10-12 00:31:54 【问题描述】:

我正在尝试将 C# Mono 应用程序构建为本机二进制文件,以便它可以在没有任何依赖关系的 Linux 系统上运行(例如 Mono)。

为了确保一些向后兼容性,我使用 Ubuntu 12.04 来构建本机二进制文件。我必须从源代码构建 Mono 3.x,因为 Ubuntu 12.04 只有 Mono 2 的软件包。我记录了 that process here,如果你感兴趣的话。

我正在使用mkbundle 来捆绑 Mono 运行时及其依赖项:

mkbundle -c -o WFTOLauncherNative.c -oo bundles.o --static --deps WFTOLauncher.exe Open.NAT.dll

我正在像这样使用 cc 编译器:

cc -o WFTOLauncherNative.exe WFTOLauncherNative.c bundles.o -l:libmono-2.0.a -l:libgdiplus.a -lc -lpthread -lrt -lm -ldl -I /usr/local/include/mono-2.0/

这适用于我构建它的系统(Ubuntu 12.04)。但是在没有安装 Mono 的 Ubuntu 14.04 上,我收到以下错误:

Unhandled Exception:
System.TypeInitializationException: An exception was thrown by the type initializer for System.Windows.Forms.XplatUI ---> System.DllNotFoundException: libc

应用程序的ldd:

scott@ubuntu:/media/strichnet/WFTOLauncher/bin/Release/LinuxNative$ ldd WFTOLauncherNative.exe
    linux-vdso.so.1 =>  (0x00007fffd0ffe000)
    libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fa6c794a000)
    /lib64/ld-linux-x86-64.so.2 (0x00007fa6c7d27000)
    libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007fa6c772c000)
    librt.so.1 => /lib/x86_64-linux-gnu/librt.so.1 (0x00007fa6c7523000)
    libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007fa6c721d000)
    libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007fa6c7019000)

到目前为止,我的预感是 Mono 在这里有问题 - 我认为它依赖 Mono DllMap 配置从 libc 映射到 libc.so.6,但它失败了。 SO上有一个类似的问题,answer here 看起来很有希望,但由于我的目标是创建一个独立的本机程序集,它不是我可以接受的解决方案。

我已将默认的 Mono 3 配置文件从 /etc/mono/config 复制到二进制目录,并将其重命名为 WFTOLauncher.exe.config 和 WFTOLauncherNative.exe.config(以防万一)。这没有帮助。

完整的 Mono 调试跟踪:https://gist.github.com/strich/e71b23421cdbe941b4f4

【问题讨论】:

【参考方案1】:

问题的根本原因是 Mono 正在寻找 libc.so,而操作系统只有 libc.so.6。 Mono 需要一个 DllMap 配置文件来理解如何翻译它。

问题的解决方案是将默认的 Mono3 DllMap 配置文件添加到与我的二进制文件相同的目录中。遗憾的是,Mono 似乎没有为该进程全局缓存 DllMap,因此我不得不在被调用的各个模块的不同名称下制作配置文件的多个副本。例如:

Mono.Posix.dll.config
System.Drawing.dll.config
System.Windows.Forms.dll.config

【讨论】:

您能否提供其中一个文件的示例。我在 Redhat 8.4 上遇到了类似的问题,使用单声道的 3-rd 方包。谢谢 @SergeyNudnov 恐怕不会。这个问题现在是古老的历史了。 :// 没想到这么老了:)。通过在 RedHat 7 上部署 soft 解决了我的问题

以上是关于Mono 本机二进制包无法在较新的 Linux 内核中加载 libc的主要内容,如果未能解决你的问题,请参考以下文章

autoconf 配置脚本在较新的 Xcode 版本下中断

为啥在较新的 Android 设备上预检失败,但在较旧的设备和台式机上却没有?

FCM - 为啥在较新的 Firebase Admin SDK 中不再支持 FCM 直接通道?

使用3D Touch防止在较新的iPad上拖动图像和链接

使用 rc.status 的 Bash 脚本在较新的 SLES 上执行两次

在较新的 PHP 版本中使用具有相同 CSS 选择器名称的 PHP 变量时出现问题