当前位置: 首页 > 面试题库 >

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

冯峻
2023-03-14
问题内容

我正在尝试为两个不同的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)

程序源如下:

int main()
{
        return(0);
}

在Celeron设备上,此程序在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.

我该怎么做才能确定导致此问题的原因?尝试静态链接到某个版本的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。

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

组装输出:

[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_HASH动态标签?我的猜测是二进制文件使用GNU_HASH,而您ld.so太旧了,无法理解。对GNU哈希部分的支持是在2006年左右添加到glibc的,并且主线发行版在2007年或2008年左右才成为仅GNU哈希的发行版。您的Centrino发行glibc
2003年 ,它早于GNU哈希。

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

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

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

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



 类似资料:
  • 我试图为两个不同的Linux环境构建一个简单的C程序。在一个设备上程序运行良好,在另一个设备上程序产生浮点异常。该程序除了从main返回0外什么也不做,这让我相信与启动代码有一些不兼容的地方,也许是ABI? 该程序是用gcc编译的,具有以下构建规范: 使用内置规格。目标:i386-redhat-linux配置为:../configure--prefix=/usr--mandir=/usr/shar

  • 给定一个非负整数的列表,将它们排列成最大的数。 例如,给定[3,30,34,5,9],形成的最大数是9534330。 注意:结果可能很大,因此需要返回一个字符串,而不是整数。 它给出了浮点异常。 我曾试着找到解决办法,但没能找到。我是cpp的初学者,任何帮助都会很好。

  • 我的程序应该接受一个浮点变量,然后退出。然而,我正在练习一些异常处理的东西,发现了一个问题。当您在这个程序中输入一个字母时,程序当然会抛出一个InputMismatchException,但它会陷入无限循环。我认为我的问题是基于我对try-catch语句和异常处理的误解。 如果我使用不同的变量类型,就不会出现这个问题,所以我不确定这是逻辑错误还是浮点变量的问题。

  • 我目前正在研究余弦的近似值。由于最终的目标设备是一个使用32位浮点ALU/LU的自开发设备,并且有一个专门的C编译器,所以我不能使用C库的数学函数(cosf,...)。我的目标是编写在精度和指令/周期数量方面不同的各种方法。 我已经尝试了很多不同的近似算法,从fdlibm开始,taylor展开,pade近似,remez算法使用maple等等.... 但是一旦我只使用浮点精度来实现它们,精度就会有很

  • 我只需要在Python中舍入浮点数的最后2个正数 EX: 0.000000302329303- 这是否可能以类似圆形的简单方式实现?

  • 问题内容: 我正在寻找一种将数字转换为字符串格式的方式,删除任何多余的“ .0” 输入数据是浮点数和字符串的混合。所需的输出: 0->‘0’ 0.0->‘0’ 0.1->‘0.1’ 1.0->‘1’ 我想出了以下生成器表达式,但是我想知道是否有更快的方法: 进行真值检查可防止0变成空字符串。 编辑:我现在或多或少可以接受的解决方案是这样的: 似乎没有一种优雅的方法可以在python中处理这种(相当