2013-07-31 1 views
2

I ont un processus qemu-kvm déversé avec méfiance noyau avec SIGFPE:vidage de la mémoire avec SIGFPE de division non nulle

Program terminated with signal 8, Arithmetic exception. 
#0 bdrv_exceed_io_limits (bs=0x7f75916b7270, is_write=false, nb_sectors=1) 
    at /usr/src/debug/qemu-kvm-0.12.1.2/block.c:3730 
3730  elapsed_time /= (NANOSECONDS_PER_SECOND); 

Lorsque elapsed_time est double (la valeur de sortie de gdb ci-dessous) et NANOSECONDS_PER_SECOND est une macro:

#define NANOSECONDS_PER_SECOND 1000000000.0 

Je ne peux pas penser à une raison qui pourrait causer SIGFPE. Une idée?

Scénario: J'utilise RHEL-6.5 comme hôte et tente de démarrer un invité Windows. Il est régulièrement reproductible avec la même commande.

backtrace complète:

(gdb) bt 
#0 bdrv_exceed_io_limits (bs=0x7ffff86f9270, is_write=false, nb_sectors=1) at /usr/src/debug/qemu-kvm-0.12.1.2/block.c:3730 
#1 bdrv_io_limits_intercept (bs=0x7ffff86f9270, is_write=false, nb_sectors=1) at /usr/src/debug/qemu-kvm-0.12.1.2/block.c:181 
#2 0x00007ffff7e0bf6d in bdrv_co_do_readv (bs=0x7ffff86f9270, sector_num=0, nb_sectors=1, qiov=0x7fffe8000ab8, flags=<value optimized out>) 
    at /usr/src/debug/qemu-kvm-0.12.1.2/block.c:2136 
#3 0x00007ffff7e0c293 in bdrv_co_do_rw (opaque=0x7fffe8000b00) at /usr/src/debug/qemu-kvm-0.12.1.2/block.c:3880 
#4 0x00007ffff7e125eb in coroutine_trampoline (i0=<value optimized out>, i1=<value optimized out>) 
    at /usr/src/debug/qemu-kvm-0.12.1.2/coroutine-ucontext.c:129 
#5 0x00007ffff5718ba0 in ??() from /lib64/libc.so.6 
#6 0x00007fffffffbf60 in ??() 
#7 0x0000000000000000 in ??() 

(gdb) disass 
    0x00007ffff7e0b6ae <+190>: mov 0x8a0(%rbx),%rax 
    0x00007ffff7e0b6b5 <+197>: test %rax,%rax 
=> 0x00007ffff7e0b6b8 <+200>: divsd 0x170660(%rip),%xmm0  # 0x7ffff7f7bd20 
    0x00007ffff7e0b6c0 <+208>: je  0x7ffff7e0b950 <bdrv_io_limits_intercept+864> 
    0x00007ffff7e0b6c6 <+214>: mov 0x888(%rbx),%rsi 

(gdb) x/gf 0x7ffff7f7bd20 
0x7ffff7f7bd20: 1000000000 

(gdb) p elapsed_time 
$3 = 919718 

(gdb) p $_siginfo 
$1 = {si_signo = 8, si_errno = 0, si_code = 6, _sifields = {_pad = {-136186690, 32767, 4244976, 0, -560757824, 32767, - 
    -560757344, 32767, 0, 0, 0, 0, 0, 0, 34884976, 0, -136186690, 32767, 34884976, 0, 4258127, 0, 0, 0, -55876128, 3265 
    -136186690, si_uid = 32767}, _timer = {si_tid = -136186690, si_overrun = 32767, si_sigval = {sival_int = 4244976, s 
    _rt = {si_pid = -136186690, si_uid = 32767, si_sigval = {sival_int = 4244976, sival_ptr = 0x40c5f0}}, _sigchld = {s 
     si_uid = 32767, si_status = 4244976, si_utime = -2408436515056123904, si_stime = -584917379700457473}, _sigfault 
    0x7ffff7e1f4be}, _sigpoll = {si_band = 140737352168638, si_fd = 4244976}}} 

Alors, quel pourrait être le problème avec cette instruction divsd? Toute suggestion sur la façon de le déboguer?

Réponse moi-même: C'est un bogue du noyau qui met accidentellement mxcsr à une mauvaise valeur, le noyau Linux déclenche le code SIGFPE INEXACT quand le bit n'est pas masqué correctement.

+0

Qu'est-ce que le type et la valeur 'elapsed_time'? –

+0

double, 919718, comme mis à jour dans la description de la question. – FamZheng

+0

Zheng Etes-vous sûr au moment de la faute de signal - attendre –

Répondre

4

SIGFPE dans votre code est pas dû à divisé par zéro, mais à cause de certaines raisons suivantes:

FPE_FLTOVF_TRAP: piège à débordement flottant.
FPE_FLTUND_TRAP: Piège à flux flottant flottant. (Piégeage de suite. Sousverse est normalement activé flottante)

Macro: int SIGFPE:

Le signal SIGFPE signale une erreur arithmétique fatale. Bien que le nom dérive de "l'exception à virgule flottante", ce signal couvre toutes les erreurs arithmétiques, y compris la division par zéro et le dépassement. Si un programme stocke des données entières dans un emplacement qui est ensuite utilisé dans une opération à virgule flottante , cela provoque souvent une exception «opération invalide» , car le processeur ne peut pas reconnaître les données sous la forme d'un nombre à virgule flottante .

Exceptions réelles à virgule flottante sont un sujet compliqué car il existe de nombreux types d'exceptions avec des significations subtilement différentes, et le signal SIGFPE ne les distingue pas. La norme IEEE pour l'arithmétique à virgule flottante binaire (norme ANSI/IEEE 754-1985) définit différentes exceptions à virgule flottante et requiert des systèmes informatiques conformes pour signaler leurs occurrences. Cependant, cette norme ne spécifie pas comment les exceptions sont signalées, ni quels types de manipulation et contrôle le système d'exploitation peut offrir au programmeur.

Parce que:
NANOSECONDS_PER_SECOND = 1000000000.0 et elapsed_time = 919718 si elapsed_time /= (NANOSECONDS_PER_SECOND);=>919718/100 0000 000.0 == 0.0000919718, je suis sûr que cela provoque Floating underflow trap cette raison de SIGFPF.

Le piège à trop-plein flottant ne peut pas être un cas car le fonctionnement est divisé.

Questions connexes