我有一个qemu-kvm进程可疑核心倾倒了SIGFPE:
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);
其中elapsed_time
为double
(下面gdb输出中的值)和NANOSECONDS_PER_SECOND
是一个宏:
#define NANOSECONDS_PER_SECOND 1000000000.0
我想不出应该如何导致SIGFPE的原因。任何线索?
场景:我正在使用RHEL-6.5作为主机并尝试启动Windows guest虚拟机。它可以通过相同的命令稳定地重现。
完全回溯:
(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}}}
那么,这个divsd
指令会出现什么问题?有关如何调试它的任何建议吗?
自己回答:这是一个内核错误,它将mxcsr意外地设置为某个错误的值,当没有正确屏蔽该位时,Linux内核会触发SIGFPE代码INEXACT。
答案 0 :(得分:4)
代码中的SIGFPE不是由于除以零而是由于以下原因:
FPE_FLTOVF_TRAP:浮动溢出陷阱 FPE_FLTUND_TRAP:浮动下溢陷阱。 (通常不启用捕获浮动下溢。)
SIGFPE信号报告致命的算术错误。虽然名字 实际上是从“浮点异常”派生出来的 涵盖所有算术错误,包括除零和溢出。 如果程序将整数数据存储在随后在a中使用的位置 浮点运算,这通常会导致“无效操作” 异常,因为处理器无法将数据识别为 浮点数。
实际的浮点异常是一个复杂的主题,因为 有许多类型的异常具有微妙的不同含义,并且 SIGFPE信号不区分它们。 IEEE标准 用于二进制浮点运算(ANSI / IEEE Std 754-1985)定义 各种浮点异常并要求符合计算机 报告其发生的系统。但是,这个标准没有 指定如何报告异常,或者处理和处理什么类型 控制操作系统可以提供给程序员。
由于:
NANOSECONDS_PER_SECOND
= 1000000000.0
和elapsed_time
= 919718
所以elapsed_time /= (NANOSECONDS_PER_SECOND);
=&gt; 919718 / 100 0000 000.0
== {{1} },我确信这会导致 0.0000919718
成为SIGFPF的原因。
浮动溢出陷阱不可能是一种情况,因为操作是分开的。
答案 1 :(得分:1)
SIGRE可能不一定会在导致它之后的某个时间看到。这当然令人困惑。