【发布时间】:2018-01-25 12:51:35
【问题描述】:
您可能听说过 StoneKnifeForth,这是 kragen 的一个项目:https://github.com/kragen/stoneknifeforth。它是一个充当小型 Forth 解释器的 Python 程序和一个充当 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
这显然不是一个非常有趣的错误消息,所以我想我会 strace 它:
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 标头是错误的不知何故,除了以下两个有趣的花絮:
- 在 32 位 qemu 下运行良好
- 如果我
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
【问题讨论】:
-
请显示来自
readelf -l的输出。问题可能出在PT_LOAD段上,而不是 ELF 标头。 -
@EmployedRussian 我的朋友 Tom 今天早些时候帮助找到了这个问题。我会尽快尝试发布一个自我回答。
-
@EmployedRussian 我已经发布了一个解释问题的答案。
标签: linux linux-kernel binary segmentation-fault elf