2011-01-05 82 views
0

我知道這很難相信,但我對此100%認真對待。MacBook Pro,Windows XP,VS 2008 Express Edition上原始C程序的損壞行爲

當我在運行Windows XP Professional 32位SP3的MacBook Pro(Core 2 Duo P8600)上以發行模式編譯下面的代碼時,運行可執行文件,儘快printf命中因爲我觸摸觸摸板(不是玩笑) - 這絕對不會發生。

我上傳了一個包項目文件的Visual Studio,包括彙編清單和自述文件包括附加信息:

www.pedram-azad.de/WeirdProblem.zip

任何人都可以複製他的MacBook Pro還是同樣的問題(其他任何筆記本電腦)?任何人都可以在彙編中看到什麼可能是問題?

我的猜測是,觸摸板驅動程序以某種方式設法操縱負責浮點比較的寄存器。用整數,問題不會發生。

任何想法發生在這裏將是非常受歡迎的。

Pedram

#include <stdio.h> 

int main() 
{ 
    while (true) 
    { 
     float x = 1.0f; 

     for (int i = 0; i < 50; i++) 
     { 
      if (0.0f < x) 
       x = 0.0f; 
     } 

     if (x == 1.0f) 
      printf("bad: %.2f\n", x); 
    } 

    return 0; 
} 

這裏是上面的代碼集列表,由Visual Studio產生2008速成版:

; Listing generated by Microsoft (R) Optimizing Compiler Version 15.00.30729.01 

    TITLE c:\Dokumente und Einstellungen\azad\Desktop\WeirdProblem\main.cpp 
    .686P 
    .XMM 
    include listing.inc 
    .model flat 

INCLUDELIB MSVCRT 
INCLUDELIB OLDNAMES 

PUBLIC [email protected][email protected]@bad?3?5?$CF?42[email protected] ; `string' 
PUBLIC [email protected] 
PUBLIC [email protected] 
PUBLIC [email protected] 
PUBLIC _main 
EXTRN __imp__printf:PROC 
EXTRN __fltused:DWORD 
; COMDAT [email protected][email protected]@[email protected] 
; File c:\dokumente und einstellungen\azad\desktop\weirdproblem\main.cpp 
CONST SEGMENT 
[email protected][email protected]@[email protected] DB 'bad: %.2f', 0aH, 00H ; `string' 
CONST ENDS 
; COMDAT [email protected] 
CONST SEGMENT 
[email protected] DD 000000000r   ; 0 
CONST ENDS 
; COMDAT [email protected] 
CONST SEGMENT 
[email protected] DQ 00000000000000000r ; 0 
CONST ENDS 
; COMDAT [email protected] 
CONST SEGMENT 
[email protected] DD 03f800000r   ; 1 
; Function compile flags: /Ogtpy 
CONST ENDS 
; COMDAT _main 
_TEXT SEGMENT 
_x$3834 = -4      ; size = 4 
_main PROC      ; COMDAT 

; 4 : { 

    push ebp 
    mov ebp, esp 
    and esp, -64    ; ffffffc0H 
    fld1 
    sub esp, 60     ; 0000003cH 
    fldz 
    push esi 
    fldz 
    mov esi, DWORD PTR __imp__printf 
    jmp SHORT [email protected] 
[email protected]: 

; 10 :  { 
; 11 :   if (0.0f < x) 
; 12 :    x = 0.0f; 
; 13 :  } 
; 14 : 
; 15 :  if (x == 1.0f) 

    fstp ST(0) 
    fxch ST(2) 
[email protected]: 
    fxch ST(2) 
    mov ecx, 10     ; 0000000aH 
    fst DWORD PTR _x$3834[esp+64] 
    fld DWORD PTR _x$3834[esp+64] 
[email protected]: 
    fcom ST(2) 
    fnstsw ax 
    test ah, 65     ; 00000041H 
    jne SHORT [email protected] 
    fstp ST(0) 
    fxch ST(2) 
    fst DWORD PTR _x$3834[esp+64] 
    fld DWORD PTR _x$3834[esp+64] 
    fxch ST(1) 
    fxch ST(3) 
    fxch ST(1) 
[email protected]: 
    fcom ST(2) 
    fnstsw ax 
    test ah, 65     ; 00000041H 
    jne SHORT [email protected] 
    fstp ST(0) 
    fxch ST(2) 
    fst DWORD PTR _x$3834[esp+64] 
    fld DWORD PTR _x$3834[esp+64] 
    fxch ST(1) 
    fxch ST(3) 
    fxch ST(1) 
[email protected]: 
    fcom ST(2) 
    fnstsw ax 
    test ah, 65     ; 00000041H 
    jne SHORT [email protected] 
    fstp ST(0) 
    fxch ST(2) 
    fst DWORD PTR _x$3834[esp+64] 
    fld DWORD PTR _x$3834[esp+64] 
    fxch ST(1) 
    fxch ST(3) 
    fxch ST(1) 
[email protected]: 
    fcom ST(2) 
    fnstsw ax 
    test ah, 65     ; 00000041H 
    jne SHORT [email protected] 
    fstp ST(0) 
    fxch ST(2) 
    fst DWORD PTR _x$3834[esp+64] 
    fld DWORD PTR _x$3834[esp+64] 
    fxch ST(1) 
    fxch ST(3) 
    fxch ST(1) 
[email protected]: 
    fcom ST(2) 
    fnstsw ax 
    test ah, 65     ; 00000041H 
    jne SHORT [email protected] 
    fstp ST(0) 
    fxch ST(2) 
    fst DWORD PTR _x$3834[esp+64] 
    fld DWORD PTR _x$3834[esp+64] 
    fxch ST(1) 
    fxch ST(3) 
    fxch ST(1) 
[email protected]: 

; 5 : while (true) 
; 6 : { 
; 7 :  float x = 1.0f; 
; 8 : 
; 9 :  for (int i = 0; i < 50; i++) 

    sub ecx, 1 
    jne [email protected] 

; 10 :  { 
; 11 :   if (0.0f < x) 
; 12 :    x = 0.0f; 
; 13 :  } 
; 14 : 
; 15 :  if (x == 1.0f) 

    fld ST(1) 
    fucomp ST(1) 
    fnstsw ax 
    test ah, 68     ; 00000044H 
    jp [email protected] 
    fstp ST(2) 

; 16 :   printf("bad: %.2f\n", x); 

    sub esp, 8 
    fstp ST(2) 
    fstp ST(1) 
    fstp QWORD PTR [esp] 
    push OFFSET [email protected][email protected]@[email protected] 
    call esi 

; 17 : } 

    fld1 
    fldz 
    add esp, 12     ; 0000000cH 
    fldz 
    jmp [email protected] 
_main ENDP 
_TEXT ENDS 
END 
+0

我不會稱之爲惡意行爲,因爲該程序沒有積極地嘗試做錯事。無論如何,我使用GCC 4.5.2在Linux上進行了測試,並且printf從未被調用過。 – kmm 2011-01-05 14:08:39

+0

這可能是微軟提醒你在正確的硬件上運行錯誤的操作系統的方式。 FWIW:在使用GCC 4.5.2編譯的MacOS X 10.6.5(Core 2 Duo芯片)上運行時,代碼沒有顯示任何不良行爲。 – 2011-01-05 14:41:01

+0

您是否嘗試將開關撥動到「更多魔法」? – derkyjadex 2011-01-05 15:11:32

回答

0

我怎麼看不到觸摸板驅動程序將能夠產生這種行爲。

我的感覺是這是某種硬件問題。你有沒有超頻你的MacBook?一旦超頻,CPU可以開始做各種奇怪的事情(Eric Raymond has some war stories to tell of this)。如果你不超頻,也許你的CPU太熱了?檢查冷卻通風口可能是一個好主意。或者,也許它只是一個片狀CPU。

如果它 CPU,爲什麼只有當你觸摸觸摸板纔會發生?純粹的猜測,但也許從觸摸板耗電降低CPU電壓剛剛足以導致它做愚蠢的事情...

+0

我還沒有超頻我的MacBook。我不認爲CPU變得太熱,因爲這種情況在啓動後也會發生。它也不會在Mac OS X下發生,所以我會假設CPU是好的。 什麼也讓我困惑,如果我用Visual Studio 6編譯相同的代碼,它不會發生。 有趣的想法與降低CPU電壓的功率消耗。我不懷疑這是這樣的。問題是:爲什麼只有使用特定的操作系統和特定的編譯器纔會發生? – 2011-01-05 15:27:12

+0

觸摸板驅動程序可能會導致這樣的事情並不令人驚訝 - 觸摸板將是驅動程序需要進行浮點運算的極少數設備之一。 – caf 2011-01-06 03:55:02

+0

觸摸板驅動程序使用FPU是合理的。但就我的理解而言,驅動程序不應該爲其他任務(例如用戶應用程序)破壞FPU的狀態。我會說它必須是下列之一:(1)操作系統的錯誤,(2)編譯器錯誤,或(3)硬件錯誤。 – 2011-01-06 11:08:24

1

可能與FPU和優化有關。如果將x定義爲volatile float或編譯爲/O0,會發生這種情況嗎?如果確實如此,那麼可能有bug的驅動程序會改變FPU的狀態。

+0

'volatile'使得它不經常發生,並且/ Od(意味着VC 2008,所有優化都被停用)將發生的頻率降到最低。一個有問題的驅動程序是否可以在切換到用戶應用程序之後,在沒有操作系統恢復狀態的情況下更改FPU的狀態? – 2011-01-05 21:47:16

+0

好吧,理論上它不應該發生,但是你所看到的看起來非常像它正在發生。我對Windows驅動程序的瞭解不足以真正提示爲什麼...... – StasM 2011-01-05 21:53:15

相關問題