如何保证清理代码在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下,您可以通过调用创建未处理的异常筛选器。一旦完成,任何时候生成的异常都不会在应用程序中的某个地方处理,您的处理程序将被调用 您的处理程序可用于释放资源、生成转储文件(请参阅),或确保完成所需的任何操作 请注意,关于如何编写异常处理程序函数,存在许多“陷阱”。特别是:
new
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,这看起来很完美。是的,使用这种方法,我可以在控制台关闭时执行一些清理代码,谢谢