为什么这个程序有时会崩溃,有时候不会崩溃?

时间:2011-06-24 04:37:04

标签: winapi crash sendmessage heisenbug mandelbug

以下程序会关闭显示器。当我运行它时,有时会崩溃,而有时则不然。反汇编只指向0x00011000之类的随机位置,并且没有真实的信息。

如果我重新编译程序并运行它,重新编译的版本在我测试时运行正常。但是下次我真的需要使用它时,它会再次崩溃,我需要重新编译它...让我后悔做这件事。

我不知道如何始终如一地重现错误。(也就是说,除了我最迫切需要它并且看着它崩溃时运行它。)

这个程序中可能导致随机崩溃的原因是什么?

#include <Windows.h>
#include <tchar.h>

int WINAPI _tWinMain(HINSTANCE, HINSTANCE, LPTSTR, int)
{
    return SendMessage(HWND_BROADCAST, WM_SYSCOMMAND, SC_MONITORPOWER, 2);
}

我正在使用Windows 7 x64,并将其编译为32位程序。我相信我已经尝试了64位同样的东西,并得到了相同的结果,虽然我不是100%肯定。


编辑1:

  • 如果有人真的复制了这个,请发表评论让我知道,我很好奇其他人是否可以重现这一点。

  • 我目前正在测试一个略微裁剪的版本(不依赖于C运行时):

    #include <Windows.h>
    #pragma comment(linker, "/NoDefaultLib")
    #pragma comment(linker, "/Entry:mainCRTStartup")
    #pragma comment(linker, "/Subsystem:Windows")
    
    int mainCRTStartup()
    {
        return SendMessageW(HWND_BROADCAST, WM_SYSCOMMAND, SC_MONITORPOWER, 2);
    }
    
    /*
    Base64 version of this program, in case you want to use it:
    TVqQAAMAAAAEAAAA//8AALgAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwAAAAA4fug4AtAnNIbgBTM0hVGhpcyBwcm9ncmFtIGNhbm5vdCBiZSBydW4gaW4gRE9TIG1vZGUuDQ0KJAAAAAAAAAABkN3fRfGzjEXxs4xF8bOMhv7ujEbxs4xF8bKMRPGzjIb+0IxE8bOMhv7pjETxs4xSaWNoRfGzjAAAAAAAAAAAUEUAAEwBAQBYIgROAAAAAAAAAADgAA8BCwEHCgACAAAAAAAAAAAAAAgQAAAAEAAAACAAAAAAQAAAEAAAAAIAAAQAAAAAAAAABAAAAAAAAAAAIAAAAAIAAAAAAAACAAAEAAAQAAAQAAAAABAAABAAAAAAAAAQAAAAAAAAAAAAAAAoEAAAKAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAudGV4dAAAAHQAAAAAEAAAAAIAAAACAAAAAAAAAAAAAAAAAAAgAABgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABYEAAAAAAAAGoCaHDxAABoEgEAAGj//wAA/xUAEEAA99gbwPfYw8zMUBAAAAAAAAAAAAAAaBAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFgQAAAAAAAAQgJTZW5kTWVzc2FnZVcAAFVTRVIzMi5kbGwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==
    */
    

    目前,这个版本有效......但是,当我重新编译它时,前一个版本也是如此。如果事实证明这个没有崩溃,我会在这里发布。

  • 如果您想重现这一点,我的建议是:编译程序,让它腌制一两天。 :)当您使用计算机一段时间后,尝试运行该程序几次...当我尝试时,我通常得到一个错误,直到我重新编译程序。< / p>


编辑2:

出于某种原因,每当你想显示人们出现问题时,它就会神奇地得到解决。在这里同样的情况。我将继续尝试重现错误,但此刻,似乎工作正常。 :\(我怀疑它可能是因为安装了Windows 7 SP1,但我真的很怀疑......如果我发现我会发布在这里。)

对大家抱歉...


编辑3:

好的......当它发生时,无论何时你需要重现一个bug,你都不能。 :|

但是,至少我发现了其他内容:似乎发送消息的正确的窗口是GetShellWindow()返回的窗口。希望这对其他人有用。

3 个答案:

答案 0 :(得分:2)

也许您已经看过这个,但this article by Windows god Raymond Chen的要点是不建议以这种方式使用HWND_BROADCAST。我在一个不会被命名的网站上通过comments找到了这个,大意是你在这里使用的示例代码虽然很受欢迎,但却不是处理显示器掉电的正确方法。

这并不能解释为什么你会看到你所看到的确切内容,但它确实提供了一些证据证明有问题的代码是可疑的。

答案 1 :(得分:0)

配置您的病毒扫描程序,让应用程序单独使用,不要干扰它。

您的应用太靠近evil winmain,无法在此处忽略病毒扫描程序。

答案 2 :(得分:0)

唯一有意义的事情。如果你重新编译它的话,你的声明就是某些东西正在散列exe并以某种方式干扰它。 100个病毒扫描程序中有99个东西可以使用 - 但是你说你没有病毒扫描程序?

  1. 你构建了exe。它的哈希值为0x1234。
  2. 你运行它。病毒扫描程序对其进行哈希处理,允许它运行,然后确定它正在执行它不喜欢的操作(例如向所有窗口广播关闭消息)。
  3. 你再次运行它。病毒扫描程序说“看看0x1234再次启动;我打算修补它以阻止它广播关机消息,或者我可能只是阻止它运行”。
  4. 你重建了exe。它有一个新的哈希值0x4321(哈希值的变化完全是因为它有一个新的创建/修改日期)。
  5. 回到2。