你可能听说过kragen的一个项目StoneKnifeForth:https://github.com/kragen/stoneknifeforth。它是一个Python程序,充当一个小的Forth解释器和一个充当Forth编译器的Forth程序。因此,您可以使用这两个一起构建Forth编译器二进制文件。
在将StoneKnifeForth移植到C ++(https://github.com/tekknolagi/stoneknifecpp)之后,我注意到StoneKnifeForth(或者各种)在64位Linux上生成的所有二进制文件都是段错误。也就是说,如果你克隆stoneknifecpp并运行:
make
./l01compiler # produced by the Forth program
您将获得以下内容:
willow% ./l01compiler
[1] 31614 segmentation fault ./l01compiler
显然,这不是一个非常有趣的错误信息,所以我想我会把它分开:
willow% strace ./l01compiler
execve("./l01compiler", ["./l01compiler"], [/* 110 vars */]) = -1 EPERM (Operation not permitted)
--- SIGSEGV {si_signo=SIGSEGV, si_code=SI_KERNEL, si_addr=0} ---
+++ killed by SIGSEGV +++
[1] 31615 segmentation fault (core dumped) strace ./l01compiler
得到了......更多信息。看起来ELF标题错误以某种方式,除了以下两个有趣的花絮:
sudo ./l01compiler
我有点不知道为什么会这样,即使在互联网上搜索32位和64位Linux内核之间的ELF标头格式之间可能存在差异等等。如果有人有任何信息,我会很高兴
我附上了标题:
willow% readelf -h l01compiler
ELF Header:
Magic: 7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00
Class: ELF32
Data: 2's complement, little endian
Version: 1 (current)
OS/ABI: UNIX - System V
ABI Version: 0
Type: EXEC (Executable file)
Machine: Intel 80386
Version: 0x1
Entry point address: 0x1e39
Start of program headers: 52 (bytes into file)
Start of section headers: 0 (bytes into file)
Flags: 0x0
Size of this header: 52 (bytes)
Size of program headers: 32 (bytes)
Number of program headers: 1
Size of section headers: 40 (bytes)
Number of section headers: 0
Section header string table index: 0
答案 0 :(得分:1)
非常感谢Tom Hebb(tchebb)确认我的怀疑并弄明白这一点。从this commit可以看出,问题是起源地址太低了。它与32位或64位无关,而是与早期内核与新内核相关。
较新的内核增加了 PolicyNumber AgentName Premium Transaction Type
A Brien 1,000 New Business 1
A Brien -1,000 Cancelled 1
B Michael 500 New Business 0
C David 600 New Business 0
D Tom 800 New Business 1
D Tom -800 Endorsement 1
sysctl参数,这意味着旧的源会禁止程序启动。这解释了为什么vm.mmap_min_addr
有效。正如Tom解释的那样,“除非你使用KVM支持调用qemu,否则qemu是一个模拟器而不是虚拟机管理程序,所以它模拟软件中的整个地址空间和虚拟内存子系统,并且可能不会强加任何加载地址限制。”