Исключение с плавающей запятой (SIGFPE) на ' int main () {return (0);}'
Я пытаюсь построить простую программу на C для двух различных сред Linux. На одном устройстве программа работает нормально, на другом устройстве программа генерирует исключение с плавающей запятой. Программа ничего не делает, но возвращает 0 из main, что заставляет меня полагать, что существует некоторая несовместимость с исходным кодом, возможно, ABI?
программа компилируется с gcc со следующими спецификациями сборки:
используя встроенные спецификации. Цель: i386-redhat-linux Настроен: ../configure --prefix= / usr --mandir= / usr / share/man --infodir=/usr/доли/информация опцией --enable-общий опцией --enable-потоки=в POSIX --включить-проверки=релиз-с-системой-библиотека zlib --включить-__базе cxa_atexit-отключить-libunwind-исключения опцией --enable-Debian установщикам-многофайловую опцией --enable-языки=С,с++,язык,параметр obj-с++,Java,Фортран ада опцией --enable-Java с-авт=ГТК --отключить-дсси --отключить-плагин --с-Ява-дом=в/usr/lib в/в jvm/java-машины 1.4.2-транспорт-1.4.2.0/JRE с-с-ЦП=родовой опции --host=i386 в-в RedHat-Linux для резьбы модель: POSIX и ССЗ версия 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 , %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
2 ответа:
это будет звучать как очень длинный выстрел...но вы можете попробовать следующее?
$ readelf -a fail
и искать динамический тег GNU_HASH? Я предполагаю, что двоичный использует
GNU_HASH
, а какld.so
слишком стар, чтобы понять это. Поддержка раздела GNU hash была добавлена в glibc около 2006 года, а магистральные дистрибутивы стали GNU-hash-только в 2007 или 2008 году. Твой Центриноglibc
С 2003, который предшествует хэшированию GNU.если
ld.so
не понимает хэш GNU, вместо этого он попытается использовать старый раздел ELF hash, который пуст. В частности, я подозреваю, что ваш крах происходит в эта строка вelf/do-lookup.h
:for (symidx = map->l_buckets[hash % map->l_nbuckets];
поскольку компоновщик предположительно не понимает хэши GNU,
l_nbuckets
будет 0, что приведет к аварии. Обратите внимание, чтоmap
большая структура с около 100 элементами структуры, иl_nbuckets
это около 90-го члена структуры в новойld.so
(0x164 = 4*89
, так в старшихld.so
вероятно, именно этот элемент).чтобы увидеть, если это окончательно проблема, построить с
-Wl,--hash-style=sysv
или-Wl,--hash-style=both
и посмотреть, если авария уходит.
поскольку он работает на атоме, но не на старом Celeron, я бы подумал, что проблема может быть с оптимизацией компилятора, генерирующей код, который Celeron не может выполнить. Попробуйте выполнить компиляцию с флагом-O0. Кроме того, я бы предложил добавить-march=i686, чтобы явно указать архитектуру. Кроме того, чтобы помочь изолировать проблему, я бы также предложил отключить привязку к среде выполнения C++ и JAVA.
вы создали эту тестовую программу один раз и запустили ее на каждом устройстве, или вы построили другой исполняемый файл для каждого устройства? Если вы создаете один исполняемый файл, у вас могут быть разные версии libc, libstdc++ на двух устройствах или на устройствах против вашей машины сборки.