【发布时间】:2014-04-18 19:46:18
【问题描述】:
假设 32 位支持已加载到给定的 64 位 LINUX 安装:
32 位 LINUX 2.6 可执行文件能否在 LINUX 3.2 机器上可靠运行? (是的,重述标题)显然不是!
对 32 位程序有哪些限制(在什么样的程序方面,而不是在 4GB 限制等方面)?
-
是否有特定的标记文件、可执行文件、系统调用可以提前检查以确定这一点,以便脚本可以通知用户系统配置不正确?然后我可以编写一个脚本,比如“canirunhere”,它可以让用户明白这一点,而不是仅仅得到一些奇怪的浮点异常崩溃。
- 尝试运行程序(在脚本内)并查看它是否崩溃不是一个选项,因为该程序可能只是在执行除以零!
背景故事:
我有一个用于 2.6 LINUX 的 32 位二进制构建,它展示了经典的不兼容堆栈跟踪(见下文)。它适用于某些机器,例如 x86_64 Linux 3.2 机器(本例中为 3.2.0-8),但不适用于其他机器,例如 AMD64 Linux 3.2 机器(本例中为 3.2.44-3)。
必要信息:
程序在动态加载程序本身中死亡。以下是信息的“文件”和“uname -a”位:
文件:
ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), for GNU/Linux 2.6.9, dynamically linked (uses shared libs), not stripped
非功能系统:
3.2.44-3.2.0.3.1-amd64-10846333 #1 SMP Wed May 29 13:08:01 UTC 2013 x86_64 GNU/Linux
FUNCTIONAL 系统,一个 x86_64 运行 Ubuntu 的虚拟机:3.2.0-58-generic #88-Ubuntu SMP Tue Dec 3 17:37:58 UTC 2013 x86_64 x86_64 x86_64 GNU/Linux
注意 Ubuntu 系统最初不支持 32 位程序,因此 I had to follow the instructions on the (now sadly dead) link in this previous question. (click here) 我无法在非功能机器上执行相同的任务,尽管缺少“找不到文件”错误意味着 32-理论上有位支持。
堆栈跟踪:
Program received signal SIGFPE, Arithmetic exception.
0xf7feb876 in do_lookup_x () from /lib/ld-linux.so.2
(gdb) where
#0 0xf7feb876 in do_lookup_x () from /lib/ld-linux.so.2
#1 0xf7febc07 in _dl_lookup_symbol_x () from /lib/ld-linux.so.2
#2 0xf7fed251 in _dl_relocate_object () from /lib/ld-linux.so.2
#3 0xf7fe7108 in dl_main () from /lib/ld-linux.so.2
#4 0xf7ff58f1 in _dl_sysdep_start () from /lib/ld-linux.so.2
#5 0xf7fe3c33 in _dl_start () from /lib/ld-linux.so.2
#6 0xf7fe3817 in _start () from /lib/ld-linux.so.2
Strace 输出: 根据响应者的建议,这里是 strace 的输出(不是完全相同的程序,所以地址会略有不同),这证实了它是在动态加载中,希望有助于缩小原因。
strace ./porgram
execve("./program", ["./program"...], [/* 63 vars */]) = 0
brk(0) = 0x80ea000
access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory)
mmap2(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xf77c5000
access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory)
open("/etc/ld.so.cache", O_RDONLY) = 3
fstat64(3, {st_mode=S_IFREG|0644, st_size=47552, ...}) = 0
mmap2(NULL, 47552, PROT_READ, MAP_PRIVATE, 3, 0) = 0xf77b9000
close(3) = 0
access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory)
open("/lib/tls/i686/cmov/libc.so.6", O_RDONLY) = 3
read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0\320\222"..., 512) = 512
fstat64(3, {st_mode=S_IFREG|0755, st_size=1265332, ...}) = 0
mmap2(NULL, 1275268, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0xf7681000
mmap2(0xf77b2000, 16384, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x130) = 0xf77b2000
mmap2(0xf77b6000, 9604, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0xf77b6000
close(3) = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xf7680000
set_thread_area({entry_number:-1 -> 12, base_addr:0xf76806b0, limit:1048575, seg_32bit:1, contents:0, read_exec_only:0, limit_in_pages:1, seg_not_present:0, useable:1}) = 0
--- SIGFPE (Floating point exception) @ 0 (0) ---
【问题讨论】:
-
尝试
strace你的执行。 -
感谢您的建议,这是结果太大,无法放在这里,将其添加到上面的信息中。
-
Mark Gerolimatos,你能在你的 32 位二进制文件上运行
ldd吗?什么是较旧的 32 位 linux(哪个版本的 ubuntu)?如果较新的 64 位 Linux 没有相同版本的 32 位 glibc,您应该使用静态链接软件...
标签: linux x86 x86-64 glibc strace