Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/windows/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何保证清理代码在Windows C++;(信号、错误分配和关闭的窗口) 我有一个Windows C++控制台程序,如果我在程序结束时不调用 ReleSeDeRiver()/代码>,一些硬件进入坏状态,不能重新使用而不重新启动。 我想确保ReleaseDriver()即使程序异常退出也能运行,例如,如果我点击Ctrl+C或关闭控制台窗口_C++_Windows_Crash_Signals - Fatal编程技术网

如何保证清理代码在Windows C++;(信号、错误分配和关闭的窗口) 我有一个Windows C++控制台程序,如果我在程序结束时不调用 ReleSeDeRiver()/代码>,一些硬件进入坏状态,不能重新使用而不重新启动。 我想确保ReleaseDriver()即使程序异常退出也能运行,例如,如果我点击Ctrl+C或关闭控制台窗口

如何保证清理代码在Windows C++;(信号、错误分配和关闭的窗口) 我有一个Windows C++控制台程序,如果我在程序结束时不调用 ReleSeDeRiver()/代码>,一些硬件进入坏状态,不能重新使用而不重新启动。 我想确保ReleaseDriver()即使程序异常退出也能运行,例如,如果我点击Ctrl+C或关闭控制台窗口,c++,windows,crash,signals,C++,Windows,Crash,Signals,我可以使用signal()为SIGINT创建信号处理程序。虽然程序结束时会弹出一个恼人的错误“发生了一个未处理的Win32异常…”,但这工作正常 我不知道如何处理控制台窗口关闭的情况,而且(更重要的是)我不知道如何处理由坏内存访问等引起的异常 谢谢你的帮助 在Windows下,您可以通过调用创建未处理的异常筛选器。一旦完成,任何时候生成的异常都不会在应用程序中的某个地方处理,您的处理程序将被调用 您的处理程序可用于释放资源、生成转储文件(请参阅),或确保完成所需的任何操作 请注意,关于如何编写异

我可以使用
signal()
SIGINT
创建信号处理程序。虽然程序结束时会弹出一个恼人的错误“发生了一个未处理的Win32异常…”,但这工作正常

我不知道如何处理控制台窗口关闭的情况,而且(更重要的是)我不知道如何处理由坏内存访问等引起的异常


谢谢你的帮助

在Windows下,您可以通过调用创建未处理的异常筛选器。一旦完成,任何时候生成的异常都不会在应用程序中的某个地方处理,您的处理程序将被调用

您的处理程序可用于释放资源、生成转储文件(请参阅),或确保完成所需的任何操作

请注意,关于如何编写异常处理程序函数,存在许多“陷阱”。特别是:

  • 您不能调用任何CRT函数,例如
    new
  • 不能执行任何基于堆栈的分配
  • 如果您在处理程序中执行了导致异常的任何操作,Windows将立即终止您的应用程序,方法是从应用程序的背面撕下骨骼。你再也没有机会优雅地关机了
  • 您可以调用许多Windows API函数。但是你不能
    sprintf
    new
    delete
    。。。简而言之,如果它不是WINAPI函数,那么它可能不安全


    由于以上所有原因,建议将处理程序函数中的所有变量设置为静态变量。您将无法使用sprintf,因此必须在初始化期间提前格式化字符串。请记住,调用处理程序时,机器处于非常不稳定的状态。

    如果我没有弄错,您可以通过setConsoletrlHandler检测控制台是否关闭或程序是否使用Ctrl+C终止:

    #include <windows.h>
    
    BOOL CtrlHandler(DWORD)
    {
        MessageBox(NULL, "Program closed", "Message", MB_ICONEXCLAMATION | MB_OK);
        exit(0);
    }
    
    int main()
    {
        SetConsoleCtrlHandler((PHANDLER_ROUTINE)&CtrlHandler, TRUE);
        while (true);
    }
    
    #包括
    波尔·特拉汉德勒(德沃德)
    {
    MessageBox(空,“程序关闭”,“消息”,MB|U图标连接| MB|U OK);
    出口(0);
    }
    int main()
    {
    SetConsoletrlHandler((PHANDLER_例程)和CtrlHandler,TRUE);
    虽然(正确);
    }
    
    如果您担心异常,比如bad_alloc,您可以将main包装成try块。catch <代码> STD::异常和< /> >,它应该是所有抛出异常的基类,但是您也可以用“代码> catch(…)”/<代码>捕获任何C++异常。但是,除了这些例外,并不是所有的都丢失了,您应该弄清楚抛出的是什么以及为什么

    避免未定义的行为也有帮助。:)

    您不能(保证代码运行)。你可能会失去动力,然后什么也跑不了。CPU的一级指令缓存可能会崩溃,那么代码将以随机方式失败


    运行清理代码最可靠的方法是在一个单独的进程中,该进程监视第一个对象的退出(只是进程句柄上的WaitForSingleObject)。一个单独的看门狗进程尽可能接近保证(但仍有人可能终止您的看门狗进程)。

    在用户模式下,您所做的任何事情,包括违反所有异常筛选规则,都不会导致BSOD。只有硬件故障或内核代码中的错误才能做到这一点。@Ben:我想我已经做到了,但我会假设我的内存有问题。@John:用户模式代码当然可以做一些不寻常的事情来暴露内核错误,但内核错误仍然是原因。感谢John,这看起来很完美。是的,使用这种方法,我可以在控制台关闭时执行一些清理代码,谢谢