代码之家  ›  专栏  ›  技术社区  ›  Andreas

为什么我的x64程序在Windows上会自动崩溃?

  •  4
  • Andreas  · 技术社区  · 7 年前

    int main(int argc, char *argv[])
    {
        *((int *) 0) = 1;
        return 0;
    }
    

    显然,写入$0会导致内存访问错误。当用Visual C将这个程序编译成32位可执行文件并运行它时,Windows 7清楚地表明这个程序已经崩溃了:(德语系统)

    Screenshot

    然而,当用Visual C将程序编译为64位可执行文件时,它只是静静地崩溃。不会弹出系统对话框通知用户程序刚刚崩溃。

    这是x64二进制文件的正常行为还是我的Windows7配置有问题?我认为当程序崩溃时,操作系统应该清晰地显示给用户,而不是静静地杀死它们。。。

    编辑 :对于所有声称编译器可能只是优化空指针访问的人,下面是程序集。您可以看到非法内存访问存在于其中,并且在运行程序后它也显示在Windows的应用程序日志中。

    ; Listing generated by Microsoft (R) Optimizing Compiler Version 15.00.30729.01 
    
    include listing.inc
    
    INCLUDELIB LIBCMT
    INCLUDELIB OLDNAMES
    
    PUBLIC  main
    ; Function compile flags: /Odtp
    _TEXT   SEGMENT
    argc$ = 8
    argv$ = 16
    main    PROC
    ; File d:\test.c
    ; Line 2
        mov QWORD PTR [rsp+16], rdx
        mov DWORD PTR [rsp+8], ecx
    ; Line 3
        mov DWORD PTR ds:0, 1      ; here we go folks
    ; Line 4
        xor eax, eax
    ; Line 5
        ret 0
    main    ENDP
    _TEXT   ENDS
    END
    

    :我也证实了 HKEY_CURRENT_USER\Software\Microsoft\Windows\Windows Error Reporting\DontShowUI 设置为0。因此,Windows被显式配置为报告崩溃。但它只针对x86二进制文件,而不是x64二进制文件。是的,对于x64二进制文件,崩溃会在应用程序日志中报告,但错误对话框(请参见上面的屏幕截图)只显示x86二进制文件,而不显示x64二进制文件,尽管 DontShowUI

    编辑3 :我在不同的Windows系统上做过测试。结果如下:

    Windows 7: x86 shows crash dialog, x64 doesn't (as described above)
    Windows 8: both x86 and x64 show the crash dialog
    Windows 10: neither x86 nor x64 show the crash dialog
    

    2 回复  |  直到 7 年前
        1
  •  2
  •   alk    7 年前

    行为 *((int *) 0) = 1; ,因此您的整个程序是 未定义 .

    一些编译器可能会优化您的代码以 int main{} :gcc已经在高优化设置上优化了一段时间的未定义语句。也许这就是64位编译行为的原因?

        2
  •  2
  •   Kuba hasn't forgotten Monica    7 年前

    假设发出的代码确实包含对地址为零的内存的访问,那么二进制文件将崩溃。Windows不能保证显示崩溃消息 suppressed via group policy ,例如。

    进程本身可以使用 SetErrorMode WerRegisterRuntimeExceptionModule werapi.h .

    推荐文章