我正在try 为两种不同的Linux环境构建一个简单的C程序.在一台设备上,程序运行正常,在另一台设备上,程序生成浮点异常.该程序只从main返回0,这让我相信它与启动代码可能ABI不兼容?

该程序使用gcc编译,具有以下构建规范:

使用内置规格.目标:i386 redhat linux配置了:

节目来源如下:

int main()
{
        return(0);
}

在赛扬设备上,该程序在GDB下生成以下内容:

[root@n00200C30AA2F jrn]# /jrn/gdb fail GNU gdb Red Hat Linux (5.3post-0.20021129.18rh) (gdb) run Starting program: /jrn/fail 

Program received signal SIGFPE, Arithmetic exception. 0x40001cce in ?? () (gdb) bt
#0  0x40001cce in ?? ()
#1  0x4000c6b0 in ?? ()
#2  0x40000cb5 in ?? ()

以下是我认为可以收集的详细信息,以帮助了解正在发生的事情:

CELERON:  ( fails on this device )
2.6.8 #21 Mon Oct 1 11:41:47 PDT 2007 i686 i686 i386 GNU/Linux
============
[root@n00200C30AA2F proc]# cat cpuinfo 
processor       : 0
vendor_id       : GenuineIntel
cpu family      : 6
model           : 9
model name      : Intel(R) Celeron(R) M processor          600MHz
stepping        : 5
cpu MHz         : 599.925
cache size      : 512 KB
fdiv_bug        : no
hlt_bug         : no
f00f_bug        : no
coma_bug        : no
fpu             : yes
fpu_exception   : yes
cpuid level     : 2
wp              : yes
flags           : fpu vme de pse tsc msr mce cx8 sep mtrr pge mca cmov pat clflush dts acpi mmx fxsr sse sse2 tm pbe
bogomips        : 1179.64

GNU C Library stable release version 2.3.2, by Roland McGrath et al.
Compiled by GNU CC version 3.2.2 20030222 (Red Hat Linux 3.2.2-5).
Compiled on a Linux 2.4.20 system on 2003-03-13.
Available extensions:
        GNU libio by Per Bothner
        crypt add-on version 2.1 by Michael Glad and others
        linuxthreads-0.10 by Xavier Leroy
        BIND-8.2.3-T5B
        libthread_db work sponsored by Alpha Processor Inc
        NIS(YP)/NIS+ NSS modules 0.19 by Thorsten Kukuk

ATOM:  ( works fine on this device )
2.6.35 #25 SMP Mon Mar 12 09:02:45 PDT 2012 i686 i686 i386 GNU/Linux
==========
[root@n00E04B36ECE5 ~]# cat /proc/cpuinfo 
processor       : 0
vendor_id       : GenuineIntel
cpu family      : 6
model           : 28
model name      : Genuine Intel(R) CPU N270   @ 1.60GHz
stepping        : 2
cpu MHz         : 1599.874
cache size      : 512 KB
fdiv_bug        : no
hlt_bug         : no
f00f_bug        : no
coma_bug        : no
fpu             : yes
fpu_exception   : yes
cpuid level     : 10
wp              : yes
flags           : fpu vme de tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe nx constant_tsc up arch_perfmon pebs bts aperfmperf pni dtes64 monitor ds_cpl est tm2 ssse3 xtpr pdcm movbe lahf_lm
bogomips        : 3199.74
clflush size    : 64
cache_alignment : 64
address sizes   : 32 bits physical, 32 bits virtual
power management:


GNU C Library stable release version 2.5, by Roland McGrath et al.
Compiled by GNU CC version 4.1.2 20080704 (Red Hat 4.1.2-44).
Compiled on a Linux 2.6.9 system on 2009-09-02.
Available extensions:
        The C stubs add-on version 2.1.2.
        crypt add-on version 2.1 by Michael Glad and others
        GNU Libidn by Simon Josefsson
        GNU libio by Per Bothner
        NIS(YP)/NIS+ NSS modules 0.19 by Thorsten Kukuk
        Native POSIX Threads Library by Ulrich Drepper et al
        BIND-8.2.3-T5B
        RT using linux kernel aio
Thread-local storage support included.

我可以做些什么来确定导致此问题的原因? try 静态链接到某个版本的libc怎么样?

在GDB下发生故障后,我执行:

(gdb) x/1i $eip
0x40001cce:     divl   0x164(%ecx)
(gdb) info reg
eax            0x6c994f 7117135
ecx            0x40012858       1073817688
edx            0x0      0
ebx            0x40012680       1073817216
esp            0xbffff740       0xbffff740
ebp            0xbffff898       0xbffff898
esi            0x8049580        134518144
edi            0x400125cc       1073817036
eip            0x40001cce       0x40001cce
eflags         0x10246  66118
cs             0x73     115
ss             0x7b     123
ds             0x7b     123
es             0x7b     123
fs             0x0      0
gs             0x0      0
(gdb) x/1wx 0x164+$ecx
0x400129bc:     0x00000000
(gdb) 

根据我收到的帮助,由于某种原因,libc启动代码似乎被0除以.

现在的问题是,是什么导致了这种明显的不良行为?一定有什么东西和其他东西不兼容?

Assembly output:

[jrn@localhost ~]$ more fail.s
        .file   "fail.c"
        .text
.globl main
        .type   main, @function
main:
        leal    4(%esp), %ecx
        andl    $-16, %esp
        pushl   -4(%ecx)
        pushl   %ebp
        movl    %esp, %ebp
        pushl   %ecx
        movl    $0, %eax
        popl    %ecx
        popl    %ebp
        leal    -4(%ecx), %esp
        ret
        .size   main, .-main
        .ident  "GCC: (GNU) 4.1.2 20080704 (Red Hat 4.1.2-52)"
        .section        .note.GNU-stack,"",@progbits

推荐答案

这听起来像是一个非常遥远的机会...但是你能试试下面的方法吗?

$ readelf -a fail

寻找GNU_哈希动态标签?我猜二进制使用GNU_HASH,而你的ld.so太老了,无法理解它.glibc在2006年左右增加了对GNU哈希部分的支持,而主线发行版在2007年或2008年左右才开始使用GNU哈希.你的迅驰glibc来自2003,这比GNU哈希早.

如果ld.so不理解GNU散列,它将try 使用旧的ELF散列部分,该部分为空.特别值得一提的是,我怀疑您的坠机时间是在this line in elf/do-lookup.h:00:

for (symidx = map->l_buckets[hash % map->l_nbuckets];

由于链接器可能不理解GNU散列,所以l_nbuckets应该是0,从而导致崩溃.请注意,map是一个具有大约l_nbuckets个 struct 元素的大型 struct ,而l_nbuckets在较新的ld.so中大约是 struct 的第90个成员(0x164 = 4*89,因此在较旧的ld.so中可能正好是这个成员).

要查看这是否是问题所在,请使用-Wl,--hash-style=sysv-Wl,--hash-style=both构建,然后查看崩溃是否消失.

C++相关问答推荐

在Windows上构建无聊的SSL x64

为什么PLT表中没有push指令?

如何在C中只使用一个带双方括号([i][j])访问语法的malloc来分配动态大小的2d数组?

使用NameSurname扫描到两个单独的字符串

为什么STM32G474RE上没有启用RCC PLL

C中的指针增量和减量(*--*++p)

如何将常量char*复制到char数组

调用mProtection将堆栈上的内存设置为只读,直接导致程序SIGSEGV

Flose()在Docker容器中抛出段错误

初始成员、公共初始序列、匿名联合和严格别名如何在C中交互?

循环中的静态变量与块中的变量和循环

C:如何将此代码转换为与数组一起使用?

不确定如何处理此编译错误

无法识别C编程语言的语法,如书中所示

静态初始化顺序失败是否适用于C语言?

如何摆脱-WIMPLICIT-Function-声明

C编译和运行

C中的空指针是什么(_N)?

在C中使用字符串时是否不需要内存分配?

OpenGL 中的非渐变 colored颜色 变化