Linux执行32位动态链接程序触发SIGSEGV错误排查求助
32位动态链接程序运行崩溃问题排查
我的Linux系统中运行多数32位软件时出现异常:仅静态链接的C/C程序及最简C程序可正常执行,所有动态链接的C程序、依赖非标准C库的动态链接C程序均触发段错误。
错误示例
运行简单32位动态链接C++程序时,gdb输出:
(gdb) run Starting program: /media/34GB/ciencias exatas/test-32bit Program received signal SIGSEGV, Segmentation fault. 0x000044ae in ?? ()
回溯信息:
(gdb) backtrace #0 0x000044ae in ?? () #1 0xf7eb5854 in ?? () #2 0xf7fde66e in dl_main (phdr=0x8048034, phnum=8, user_entry=0xffffd3cc, auxv=0xffffd50c) at rtld.c:2203 #3 0xf7fefb89 in _dl_sysdep_start (start_argptr=0xffffd460, dl_main=0xf7fdc490 <dl_main>) at ../elf/dl-sysdep.c:241 #4 0xf7fdf6fe in _dl_start_final (arg=0xffffd460) at rtld.c:331 #5 _dl_start (arg=<optimized out>) at rtld.c:557 #6 0xf7fdba87 in _start () from /usr/lib32/ld-2.17.so
相关命令
编译命令:
g++ -m32 -o test-32bit test-32bit.cpp -Wl,--dynamic-link=/usr/lib32/ld-2.17.so
执行命令:
LD_LIBRARY_PATH=/media/34GB/Arquivos-de-Programas-Linux/Gcc-4.9.4/lib32/ gdb ./test-32bit
问题范围
Dosbox、Snes9x等自行编译的32位程序均出现相同错误。推测原因是混合了64位与32位辅助库(如rtld),源于手动从零搭建系统32位支持的操作:
- 编译32位glibc并安装在系统标准目录外,在/usr/lib32创建其库文件的符号链接
- 编译带multilib支持的gcc,在/usr/lib32创建libstdc++.so.6的符号链接
- 在/usr/local/bin创建gcc、g++的符号链接,最后执行ldconfig
补充信息
Edit1: info shared输出
Program received signal SIGSEGV, Segmentation fault. 0x000044ae in ?? () (gdb) info shared From To Syms Read Shared Object Library 0xf7fdb7e0 0xf7ff342c Yes /usr/lib32/ld-2.17.so 0xf7f24d70 0xf7f98aa8 No /media/34GB/Arquivos-de-Programas-Linux/Gcc-4.9.4/lib32/libstdc++.so.6 0xf7e9c550 0xf7ec7c88 No /media/34GB/Arquivos-de-Programas-Linux-32bit/Glibc-2.17/lib/libm.so.6 0xf7e7f000 0xf7e92ca8 No /media/34GB/Arquivos-de-Programas-Linux/Gcc-4.9.4/lib32/libgcc_s.so.1 0xf7cd2280 0xf7dffa0c No /media/34GB/Arquivos-de-Programas-Linux-32bit/Glibc-2.17/lib/libc.so.6
Edit2: info proc mappings输出
process 2087 Mapped address spaces: Start Addr End Addr Size Offset objfile 0x8048000 0x8049000 0x1000 0x0 /media/34GB/demos/test-32bit 0x8049000 0x804a000 0x1000 0x0 /media/34GB/demos/test-32bit 0xf7cb9000 0xf7cbb000 0x2000 0x0 0xf7cbb000 0xf7e76000 0x1bb000 0x0 /media/34GB/Arquivos-de-Programas-Linux-32bit/Glibc-2.17/lib/libc-2.17.so 0xf7e76000 0xf7e79000 0x3000 0x1ba000 /media/34GB/Arquivos-de-Programas-Linux-32bit/Glibc-2.17/lib/libc-2.17.so 0xf7e79000 0xf7e7b000 0x2000 0x1bd000 /media/34GB/Arquivos-de-Programas-Linux-32bit/Glibc-2.17/lib/libc-2.17.so 0xf7e7b000 0xf7e7d000 0x2000 0x0 0xf7e7d000 0xf7e97000 0x1a000 0x0 /media/34GB/Arquivos-de-Programas-Linux/Gcc-4.9.4/lib32/libgcc_s.so.1 0xf7e97000 0xf7e98000 0x1000 0x19000 /media/34GB/Arquivos-de-Programas-Linux/Gcc-4.9.4/lib32/libgcc_s.so.1 0xf7e98000 0xf7edd000 0x45000 0x0 /media/34GB/Arquivos-de-Programas-Linux-32bit/Glibc-2.17/lib/libm-2.17.so 0xf7edd000 0xf7edf000 0x2000 0x45000 /media/34GB/Arquivos-de-Programas-Linux-32bit/Glibc-2.17/lib/libm-2.17.so 0xf7edf000 0xf7fcc000 0xed000 0x0 /media/34GB/Arquivos-de-Programas-Linux/Gcc-4.9.4/lib32/libstdc++.so.6.0.20 0xf7fcc000 0xf7fd1000 0x5000 0xed000 /media/34GB/Arquivos-de-Programas-Linux/Gcc-4.9.4/lib32/libstdc++.so.6.0.20 0xf7fd1000 0xf7fda000 0x9000 0x0 0xf7fda000 0xf7fdb000 0x1000 0x0 [vdso] 0xf7fdb000 0xf7ffc000 0x21000 0x0 /media/34GB/Arquivos-de-Programas-Linux-32bit/Glibc-2.17/lib/ld-2.17.so 0xf7ffc000 0xf7ffe000 0x2000 0x20000 /media/34GB/Arquivos-de-Programas-Linux-32bit/Glibc-2.17/lib/ld-2.17.so 0xfffe9000 0xffffe000 0x15000 0x0 [stack]
Edit3: glibc编译命令
CC="gcc -m32 -march=core2 -mtune=core2 -O2" ../configure --prefix=/media/34GB/Arquivos-de-Programas-Linux-32bit/Glibc-2.17/ --build=x86_64-linux-gnu --host=i686-gnu-linux --enable-kernel-2.6.32 --enable-profile
排查与修复建议
- 修正glibc编译参数:编译glibc时
--host=i686-gnu-linux存在拼写错误,正确的32位主机参数应为i686-linux-gnu,该错误可能导致编译出的库存在兼容性问题,需重新编译glibc。 - 统一动态链接器路径:编译时直接指定glibc安装目录下的ld.so,而非系统目录的符号链接,避免路径不一致导致的库混合加载:
g++ -m32 -o test-32bit test-32bit.cpp -Wl,--dynamic-linker=/media/34GB/Arquivos-de-Programas-Linux-32bit/Glibc-2.17/lib/ld-2.17.so - 清理冲突符号链接:删除/usr/lib32下手动创建的glibc和libstdc++符号链接,改用
LD_LIBRARY_PATH统一指定32位库路径,确保程序加载的是自定义编译的32位库。 - 调试动态链接过程:使用
LD_DEBUG=all ./test-32bit输出动态链接的详细日志,查看库加载顺序、符号解析是否存在异常,定位崩溃前的具体操作。 - 验证库版本兼容性:确认gcc 4.9.4与glibc 2.17的版本匹配性,虽然两者理论兼容,但需检查编译时的依赖链是否正确。
- 静态链接测试:编译程序时添加
-static参数,确认静态链接的32位C++程序是否能正常运行,进一步区分是动态链接器问题还是库本身的问题。
内容的提问来源于stack exchange,提问作者user2752471
相关产品推荐
相关产品推荐

