如何保证清理代码在Windows C ++(SIGINT,错误的分配和closures的窗口)中运行

我有一个Windows C ++控制台程序,如果我在程序结束时没有调用ReleaseDriver() ,某些硬件会进入不良状态,无法重新启动。 我想确保即使程序exception退出, ReleaseDriver()运行,例如,如果我Ctrl+C或closures控制台窗口。

我可以使用signal()SIGINT创build信号处理程序。 这工作正常,虽然随着程序结束,它popup一个恼人的错误“未处理的Win32exception发生…”。

我不知道如何处理被closures的控制台窗口的情况,(更重要的是)我不知道如何处理由于内存访问不良等引起的exception。

谢谢你的帮助!

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

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

请注意,围绕着如何编写异常处理函数的问题有很多“疑难杂症”。 尤其是:

  1. 您不能调用任何CRT功能,如new
  2. 你不能执行任何基于堆栈的分配
  3. 如果你在你的处理程序中做了任何导致异常的东西,Windows会立即终止你的应用程序,把它的骨头从背后取出。 你没有进一步的机会关闭优雅。

您可以调用许多Windows API函数。 但是你不能sprintfnewdelete …总之,如果不是WINAPI函数,可能是不安全的。

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

如果我没有弄错,你可以通过SetConsoleCtrlHandler检测控制台是否关闭或者用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); } 

如果你担心异常,像bad_alloc,你可以将main包装到try块中。 捕获std::exception&它应该是所有抛出的异常的基类,但是你也可以用catch (...)捕获任何C ++异常。 但是,除了这些例外,并不是所有的东西都丢失了,你应该弄清楚是什么被抛出,为什么。

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

你不能(保证代码运行)。 你可能会失去权力,那么什么都不会运行。 你的CPU的L1指令缓存可能会被炸,那么你的代码将会随机失败。

运行清理代码最确定的方法是在一个单独的进程中监视第一个进程的句柄(只是WaitForSingleObject)。 一个单独的看门狗进程是尽可能接近你的保证(但有人仍然可以终止你的看门狗)。