linux – Mono如何神奇?
作者:互联网
我正在学习C#,所以我制作了一个名为Hello,World!的C#程序,然后用mono-csc编译并用mono运行它:
$mono-csc Hello.cs
$mono Hello.exe
Hello, World!
我注意到当我用bash命中TAB时,Hello.exe被标记为可执行文件.实际上,它仅通过加载文件名的shell运行!
Hello.exe不是带有趣文件扩展名的ELF文件:
$readelf -a Hello.exe
readelf: Error: Not an ELF file - it has the wrong magic bytes at the start
$xxd Hello.exe | head -n1
00000000: 4d5a 9000 0300 0000 0400 0000 ffff 0000 MZ..............
MZ意味着它是Microsoft Windows静态链接的可执行文件.将它放到Windows机器上,它将(应该)运行.
我安装了葡萄酒,但葡萄酒,作为Windows应用程序的兼容层,运行Hello.exe作为单声道并且直接执行它需要大约5倍的时间,所以它不是运行它的葡萄酒.
我假设有一些单声道内核模块安装了mono来拦截exec系统调用/ s,或者捕获以4D 5A开头的二进制文件,但是lsmod | grep mono和friends返回错误.
这里发生了什么,内核如何知道这个可执行文件是特殊的?
只是为了证明它不是我的shell工作魔法,我使用the Crap Shell(也就是sh)运行它并且它仍然本机运行.
这是一个完整的程序,因为评论者很好奇:
using System;
class Hello {
/// <summary>
/// The main entry point for the application
/// </summary>
[STAThread]
public static void Main(string[] args) {
System.Console.Write("Hello, World!\n");
}
}
解决方法:
这是binfmt_misc在行动:它允许内核被告知如何运行它不知道的二进制文件.查看/ proc / sys / fs / binfmt_misc的内容;在那里看到的文件中,应该解释如何运行Mono二进制文件:
enabled
interpreter /usr/lib/binfmt-support/run-detectors
flags:
offset 0
magic 4d5a
(在Debian系统上).这告诉内核应该为运行检测器提供以MZ(4d5a)开头的二进制文件.后者计算出是使用Mono还是Wine来运行二进制文件.
可以随时添加,删除,启用和禁用二进制类型;请参阅上面的文档以获取详细信息(语义令人惊讶,此处使用的虚拟文件系统的行为与标准文件系统完全不同). / proc / sys / fs / binfmt_misc / status给出全局状态,每个二进制“描述符”显示其各自的状态.禁用binfmt_misc的另一种方法是卸载其内核模块(如果它是作为模块构建的);这也意味着可以将其列入黑名单以完全避免它.
此功能允许支持新的二进制类型,例如MZ可执行文件(包括Windows PE和PE二进制文件,还包括DOS和OS / 2二进制文件!),Java JAR文件……它还允许支持已知的二进制类型新架构,通常使用Qemu;因此,使用适当的库,您可以在Intel处理器上透明地运行ARM Linux二进制文件!
您的问题源于交叉编译,尽管在.NET意义上,这引发了对binfmt_misc的警告:当您尝试在可以运行交叉编译二进制文件的系统上进行交叉编译时,某些配置脚本会出现异常.通常,检测交叉编译涉及构建二进制文件并尝试运行它;如果它运行,你不是交叉编译,如果没有,你是(或你的编译器坏了).在这种情况下,通常可以通过显式指定构建和主机架构来修复autoconf脚本,但有时您必须暂时禁用binfmt_misc …
标签:linux,mono,executable,cross-compilation 来源: https://codeday.me/bug/20190808/1621428.html