簡體   English   中英

具有SIGFPE的核心轉儲,用於非零除法

[英]Core dump with SIGFPE for non-zero division

我有一個可疑的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_timedouble (下面的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。

您代碼中的SIGFPE不是由於被零除,而是由於以下一些原因:

FPE_FLTOVF_TRAP:浮動溢出陷阱。
FPE_FLTUND_TRAP:浮動下溢陷阱。 (通常不啟用對浮動下溢的陷阱。)

巨集:int SIGFPE:

SIGFPE信號報告致命的算術錯誤。 盡管該名稱源自“浮點異常”,但該信號實際上涵蓋了所有算術錯誤,包括零除和溢出。 如果程序將整數數據存儲在隨后用於浮點運算的位置,則這通常會導致“無效運算”異常,因為處理器無法將數據識別為浮點數。

實際的浮點異常是一個復雜的主題,因為有許多類型的異常含義各有不同,並且SIGFPE信號無法區分它們。 IEEE二進制浮點算術標准(ANSI / IEEE Std 754-1985)定義了各種浮點異常,並要求使用合格的計算機系統來報告其發生情況。 但是,該標准未指定異常的報告方式,或操作系統可以為程序員提供的處理和控制方式。

因為:
NANOSECONDS_PER_SECOND = 1000000000.0並且elapsed_time = 919718因此elapsed_time /= (NANOSECONDS_PER_SECOND); => 919718 / 100 0000 000.0 == 0.0000919718 ,我確定這是SIGFPF的原因導致Floating underflow trap

浮動溢出陷阱不是一種情況,因為操作是分開的。

SIGFPE可能不一定要等到導致它的指令之后的一段時間才能看到。 當然,這令人困惑。

參見https://stackoverflow.com/a/2219339/1442050

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM