Подтвердить что ты не робот

Исключение с плавающей запятой (SIGFPE) в 'int main() {return (0); }"

Я пытаюсь создать простую программу C для двух разных сред Linux. На одном устройстве программа работает нормально, на другом устройстве программа генерирует исключение с плавающей запятой. Программа не делает ничего, кроме возврата 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, С++, objc, obj-С++, 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:

[[email protected] 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
============
[[email protected] 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
==========
[[email protected] ~]# 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.

Вопрос в том, что вызывает это явно плохое поведение? Что-то должно быть несовместимо с чем-то другим?

Сборка:

[[email protected] ~]$ 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
4b9b3361

Ответ 1

Это будет звучать как очень длинный снимок... но можете ли вы попробовать следующее?

$ readelf -a fail

и найдите динамический тег GNU_HASH? Я предполагаю, что двоичный файл использует GNU_HASH, а ваш ld.so слишком стар, чтобы понять его. Поддержка хэш-секции GNU была добавлена ​​в glibc около 2006 года, а магистральные дистрибутивы стали GNU-хешем - только в 2007 или 2008 году. Ваш 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 находится вокруг 90-го члена структуры в новой ld.so (0x164 = 4*89, поэтому в более раннем ld.so это, вероятно, именно этот элемент).

Чтобы убедиться, что это окончательно проблема, постройте с помощью -Wl,--hash-style=sysv или -Wl,--hash-style=both и посмотрите, не исчез ли авария.

Ответ 2

Поскольку он работает на ATOM, но не на старшем Celeron, я думаю, проблема может заключаться в генерации кода оптимизации компилятора, который не может выполнить Celeron. Попробуйте выполнить компиляцию с флагом -O0. Кроме того, я бы предложил добавить -march = i686, чтобы явно указать архитектуру. Кроме того, чтобы помочь изолировать проблему, я также предлагаю отключить связь со средой выполнения С++ и JAVA.

Вы построили эту тестовую программу один раз и запустили ее на каждом устройстве, или вы создали другой исполняемый файл для каждого устройства? Если вы строите один исполняемый файл, у вас могут быть разные версии libc, libstdС++ на двух устройствах или на устройствах против вашей машины сборки.