MacBook Pro、Windows XP、VS 2008 Express Edition 上原始 C 程序的损坏行为

发布于 2024-10-10 14:51:51 字数 4676 浏览 2 评论 0原文

我知道这很难相信,但我对此百分百认真。

当我在本机运行 Windows XP Professional 32 位 SP3 的 MacBook Pro (Core 2 Duo P8600) 上以发布模式使用 Visual Studio 2008 Express Edition 编译下面的代码时,运行可执行文件,只要我触摸触摸板(不是开玩笑)——这绝对不应该发生。

有人可以在他的 MacBook Pro(或任何其他笔记本电脑)上重现同样的问题吗?有人能在装配清单中看到可能存在什么问题吗?

我的猜测是触摸板驱动程序以某种方式设法操纵负责浮点比较的寄存器。对于整数,则不会出现该问题。

任何关于这里发生的事情的想法都会受到欢迎。

#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 Express Edition 生成:

; 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  ??_C@_0L@LNNNMCPH@bad?3?5?$CF?42f?6?$AA@    ; `string'
PUBLIC  __real@00000000
PUBLIC  __real@0000000000000000
PUBLIC  __real@3f800000
PUBLIC  _main
EXTRN   __imp__printf:PROC
EXTRN   __fltused:DWORD
;   COMDAT ??_C@_0L@LNNNMCPH@bad?3?5?$CF?42f?6?$AA@
; File c:\dokumente und einstellungen\azad\desktop\weirdproblem\main.cpp
CONST   SEGMENT
??_C@_0L@LNNNMCPH@bad?3?5?$CF?42f?6?$AA@ DB 'bad: %.2f', 0aH, 00H ; `string'
CONST   ENDS
;   COMDAT __real@00000000
CONST   SEGMENT
__real@00000000 DD 000000000r           ; 0
CONST   ENDS
;   COMDAT __real@0000000000000000
CONST   SEGMENT
__real@0000000000000000 DQ 00000000000000000r   ; 0
CONST   ENDS
;   COMDAT __real@3f800000
CONST   SEGMENT
__real@3f800000 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 $LN7@main
$LN43@main:

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

    fstp    ST(0)
    fxch    ST(2)
$LN7@main:
    fxch    ST(2)
    mov ecx, 10                 ; 0000000aH
    fst DWORD PTR _x$3834[esp+64]
    fld DWORD PTR _x$3834[esp+64]
$LN5@main:
    fcom    ST(2)
    fnstsw  ax
    test    ah, 65                  ; 00000041H
    jne SHORT $LN4@main
    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)
$LN4@main:
    fcom    ST(2)
    fnstsw  ax
    test    ah, 65                  ; 00000041H
    jne SHORT $LN14@main
    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)
$LN14@main:
    fcom    ST(2)
    fnstsw  ax
    test    ah, 65                  ; 00000041H
    jne SHORT $LN15@main
    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)
$LN15@main:
    fcom    ST(2)
    fnstsw  ax
    test    ah, 65                  ; 00000041H
    jne SHORT $LN16@main
    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)
$LN16@main:
    fcom    ST(2)
    fnstsw  ax
    test    ah, 65                  ; 00000041H
    jne SHORT $LN17@main
    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)
$LN17@main:

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

    sub ecx, 1
    jne $LN5@main

; 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  $LN43@main
    fstp    ST(2)

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

    sub esp, 8
    fstp    ST(2)
    fstp    ST(1)
    fstp    QWORD PTR [esp]
    push    OFFSET ??_C@_0L@LNNNMCPH@bad?3?5?$CF?42f?6?$AA@
    call    esi

; 17   :    }

    fld1
    fldz
    add esp, 12                 ; 0000000cH
    fldz
    jmp $LN7@main
_main   ENDP
_TEXT   ENDS
END

I know this is hard to believe, but I am 100% serious about this.

When I compile the code below with Visual Studio 2008 Express Edition in Release mode on my MacBook Pro (Core 2 Duo P8600) with Windows XP Professional 32 bit SP3 running natively, run the executable, the printf is hit sporadically as soon as I touch the touchpad (no joke) - which should definitely never happen.

Can anybody reproduce the same problem on his MacBook Pro (or any other laptop)? Can anybody see in the assembly listing what might be the problem?

My guess is that the touchpad driver somehow manages to manipulate a register that is responsible for the floating point comparison. With integers, the problem does not occur.

Any idea what is going on here would be very welcome.

#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;
}

Here is the assembly listing for the code above, produced by Visual Studio 2008 Express Edition:

; 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  ??_C@_0L@LNNNMCPH@bad?3?5?$CF?42f?6?$AA@    ; `string'
PUBLIC  __real@00000000
PUBLIC  __real@0000000000000000
PUBLIC  __real@3f800000
PUBLIC  _main
EXTRN   __imp__printf:PROC
EXTRN   __fltused:DWORD
;   COMDAT ??_C@_0L@LNNNMCPH@bad?3?5?$CF?42f?6?$AA@
; File c:\dokumente und einstellungen\azad\desktop\weirdproblem\main.cpp
CONST   SEGMENT
??_C@_0L@LNNNMCPH@bad?3?5?$CF?42f?6?$AA@ DB 'bad: %.2f', 0aH, 00H ; `string'
CONST   ENDS
;   COMDAT __real@00000000
CONST   SEGMENT
__real@00000000 DD 000000000r           ; 0
CONST   ENDS
;   COMDAT __real@0000000000000000
CONST   SEGMENT
__real@0000000000000000 DQ 00000000000000000r   ; 0
CONST   ENDS
;   COMDAT __real@3f800000
CONST   SEGMENT
__real@3f800000 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 $LN7@main
$LN43@main:

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

    fstp    ST(0)
    fxch    ST(2)
$LN7@main:
    fxch    ST(2)
    mov ecx, 10                 ; 0000000aH
    fst DWORD PTR _x$3834[esp+64]
    fld DWORD PTR _x$3834[esp+64]
$LN5@main:
    fcom    ST(2)
    fnstsw  ax
    test    ah, 65                  ; 00000041H
    jne SHORT $LN4@main
    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)
$LN4@main:
    fcom    ST(2)
    fnstsw  ax
    test    ah, 65                  ; 00000041H
    jne SHORT $LN14@main
    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)
$LN14@main:
    fcom    ST(2)
    fnstsw  ax
    test    ah, 65                  ; 00000041H
    jne SHORT $LN15@main
    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)
$LN15@main:
    fcom    ST(2)
    fnstsw  ax
    test    ah, 65                  ; 00000041H
    jne SHORT $LN16@main
    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)
$LN16@main:
    fcom    ST(2)
    fnstsw  ax
    test    ah, 65                  ; 00000041H
    jne SHORT $LN17@main
    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)
$LN17@main:

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

    sub ecx, 1
    jne $LN5@main

; 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  $LN43@main
    fstp    ST(2)

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

    sub esp, 8
    fstp    ST(2)
    fstp    ST(1)
    fstp    QWORD PTR [esp]
    push    OFFSET ??_C@_0L@LNNNMCPH@bad?3?5?$CF?42f?6?$AA@
    call    esi

; 17   :    }

    fld1
    fldz
    add esp, 12                 ; 0000000cH
    fldz
    jmp $LN7@main
_main   ENDP
_TEXT   ENDS
END

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

靑春怀旧 2024-10-17 14:51:51

我不明白触摸板驱动程序如何能够产生这种行为。

我的感觉是这是某种硬件问题。您对 MacBook 进行过超频吗?一旦你超频,CPU 就会开始做各种奇怪的事情 (

如果CPU,为什么只有在触摸触摸板时才会出现这种情况?纯粹是猜测,但也许触摸板的功耗会降低 CPU 电压,足以导致它做一些愚蠢的事情......

I don't see how the touchpad driver would be able to produce this kind of behaviour.

My feeling is that this is a hardware issue of some kind. Have you overclocked your MacBook, by any chance? The CPU can start doing all sorts of strange things once you overclock it (Eric Raymond has some war stories to tell of this). If you're not overclocking, maybe your CPU is just getting too hot? Might be a good idea to check the cooling vents. Or maybe it's just a flaky CPU.

If it is the CPU, why does it happen only when you touch the touchpad? Pure speculation, but maybe the power drain from the touchpad lowers the CPU voltage just enough to cause it to do silly things...

凉月流沐 2024-10-17 14:51:51

可能与FPU和优化有关。如果将x定义为易失性浮点或使用/O0编译,会发生这种情况吗?如果是这样,可能有问题的驱动程序会更改 FPU 的状态。

May have something to do with FPU and optimizations. Does it happen if you define x as volatile float or compile with /O0? If it does, maybe buggy driver changes the state of the FPU.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文