'int main(){return(0);上的浮点异常(SIGFPE);}'


71

我正在尝试为两个不同的Linux环境构建一个简单的C程序。在一个设备上,程序运行正常,在另一设备上,程序生成浮点异常。该程序除了从main返回0之外什么都不做,这使我相信与启动代码也许不兼容,也许是ABI?

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

使用内置规格。目标:i386-redhat-linux配置为:../configure --prefix = / usr --mandir = / usr / share / man --infodir = / usr / share / info --enable-shared --enable-threads = posix --enable-checking = release --with-system-zlib --enable -__ cxa_atexit --disable-libunwind-exceptions --enable-libgcj-multifile --enable-languages = c,c ++,objc,obj-c ++ ,java,fortran,ada --enable-java-awt = gtk --disable-dssi --disable-plugin --with-java-home = / usr / lib / jvm / java-1.4.2-gcj-1.4。 2.0 / jre --with-cpu = generic --host = i386-redhat-linux线程模型:posix gcc版本4.1.2 20080704(Red Hat 4.1.2-52)

程序源如下:

在Celeron设备上,此程序在GDB下生成以下内容:

以下是我可以考虑收集的详细信息,以帮助您发现正在发生的事情:

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.

我该怎么做才能确定导致此问题的原因?尝试静态链接到某个版本的libc怎么样?

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

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

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

组装输出:


6
甚至gcc 4.1.2确实很旧。当前的GCC版本是4.7!
Basile Starynkevitch 2012年

3
GCC已进入Firefox带来的修订版地狱。您很快就会看到,几天之内我们将面对GCC 25.3!

1
它可能也是libclibstdc++相关的。两者都有非常简单的初始化代码。我会安装他们的-dbg软件包,并尝试使用它gdb来调试问题。祝你好运,您将需要它。
Basile Starynkevitch 2012年

4
x/1i $eip当您在GDB下获得FPE时可以这样做吗?
ninjalj 2012年

4
@Chimera:不,这是一个非常糟糕的主意。最有可能的是,此后不久它将再次崩溃,但是即使您可以运行它,也可能会在完全不相关的地方随机引发其他故障。
亚当·罗森菲尔德

Answers:


125

这听起来像是很远的事情...但是您可以尝试以下方法吗?

并寻找GNU_HASH动态标签?我的猜测是二进制文件使用GNU_HASH,而您ld.so太旧了,无法理解。对GNU哈希部分的支持是在2006年左右添加到glibc的,而主线发行版在2007年或2008年左右才开始是仅GNU哈希的。您的Centrino版本glibc2003年的,它早于GNU哈希。

如果ld.so不能理解GNU哈希,它将尝试改用旧的ELF哈希部分,该部分为空。特别是,我怀疑您的崩溃发生在此行中elf/do-lookup.h

由于链接器可能无法理解GNU哈希,因此l_nbuckets将其设置为0,从而导致崩溃。请注意,这map是一个具有约100个结构元素的大型结构,并且l_nbuckets在较新的结构中ld.so0x164 = 4*89,在较旧的结构中,该结构ld.so可能恰好是该成员)位于结构的第90个成员附近。

要查看这是否最终是问题,请使用-Wl,--hash-style=sysv或进行构建,-Wl,--hash-style=both并查看崩溃是否消失。


谢谢。。。当我早上到办公室时,请尝试一下。
Chimera 2012年

22
哇。哇 很好的分析。+1,无论它是否能解决OP的问题
2012年

2
是的-这是一个很好的尝试,应该是对的(即使海报的名字似乎永远都没有结束)。+1。
马丁·詹姆斯

31
先生,您有出色的心理调试技巧。雷蒙·陈(Raymond Chen)将为此感到自豪。
亚当·罗森菲尔德

12
你摇滚!那就是问题所在。使用-Wl进行编译时,-hash-style = both都会生成一个在旧环境和新环境中均可运行的可执行文件。
Chimera 2012年

4

由于它可以在ATOM上运行,而不能在较旧的Celeron上运行,因此我认为问题可能出在编译器优化上,该优化生成了Celeron无法执行的代码。尝试使用标志-O0进行编译。另外,我建议添加-march = i686以明确声明该体系结构。另外,为帮助隔离问题,我还建议禁用与C ++运行时和JAVA的链接。

您是否只构建了该测试程序一次并在每个设备上运行它,还是为每个设备构建了一个不同的可执行文件?如果要构建一个可执行文件,则在这两个设备上或在与您的构建机器相对应的设备上,可能具有不同版本的libc,libstdc ++。


1
编译标志没有区别,结果相同。是的,在一台机器上构建并在两个不同的设备上运行可执行文件。Atom设备环境正在运行libc 2.5(与构建计算机上的libc 2.5相同)。但是,可执行文件失败的设备具有libc 2.3.2。那么libc 2.3.2和libc 2.5可能存在一些向后兼容性问题?
Chimera 2012年

glibcxx或libstdc ++呢?另外,您是否静态链接这些库中的任何一个?我建议尝试针对libc 2.3.2的最低公分母以及该设备对于c ++的所有优势进行构建。
syplex 2012年

2
没有静态链接任何东西。[jrn @ localhost〜] $ ldd失败linux-gate.so.1 =>(0x0098f000)libc.so.6 => /lib/libc.so.6(0x00bb0000)/lib/ld-linux.so.2( 0x00b91000)
Chimera

针对较旧版本的libc(即2.3.2)进行构建。这很可能导致您的问题。
syplex 2012年

是的,这也是我的怀疑,但是,我们正在尝试寻找一种方法来将构建环境升级到较新的库等,但是仍然能够创建与具有不同版本的libc的多个设备兼容的可执行文件。因此,我们可能会陷于困境,而最终的解决方案是硬着头皮,为较旧的旧设备升级环境。
Chimera 2012年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.