Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/72.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
检测程序终止(C、Windows)_C_Windows_Process_Termination - Fatal编程技术网

检测程序终止(C、Windows)

检测程序终止(C、Windows),c,windows,process,termination,C,Windows,Process,Termination,我有一个程序,在完成之前必须执行某些任务。问题是,有时程序会因异常而崩溃(如无法访问数据库等)。 现在,有没有办法检测异常终止,并在终止前执行一些代码 谢谢 非常感谢您的代码。如果它仅适用于Windows,那么您可以使用SEH(),或VEH(,但它仅适用于XP/2003及以上版本)这取决于您如何处理“异常”。若您正确地处理它们并从程序中退出,则可以使用atexit()注册要在退出时调用的函数 如果出现真正的异常终止,如segfault,则该功能将不起作用 不了解Windows,但在兼容POSIX

我有一个程序,在完成之前必须执行某些任务。问题是,有时程序会因异常而崩溃(如无法访问数据库等)。 现在,有没有办法检测异常终止,并在终止前执行一些代码

谢谢


非常感谢您的代码。

如果它仅适用于Windows,那么您可以使用SEH(),或VEH(,但它仅适用于XP/2003及以上版本)

这取决于您如何处理“异常”。若您正确地处理它们并从程序中退出,则可以使用
atexit()
注册要在退出时调用的函数

如果出现真正的异常终止,如segfault,则该功能将不起作用

不了解Windows,但在兼容POSIX的操作系统上,您可以安装信号处理程序来捕获不同的信号,并采取相应措施。当然,您无法捕获
SIGKILL
SIGSTOP


信号API是ANSI C的一部分,因为C89,所以Windows可能支持它。有关详细信息,请参阅
signal()
syscall。

对不起,不是windows程序员。但也许

_onexit()
注册程序终止时要调用的函数


首先,尽管这一点相当明显:您永远不会有一个完全健壮的解决方案——总有人可以点击电源线来终止您的进程。因此,你需要一个折衷方案,你需要仔细规划折衷方案的细节

更健壮的解决方案之一是将相关代码放入包装程序中。包装程序调用您的“真实”程序,等待其进程终止,然后——除非您的“真实”程序明确表示它已正常完成——运行清理代码。这在测试线束之类的东西中相当常见,测试程序可能会崩溃或中止,或者以意外的方式死亡

如果有人对你的包装器函数执行TerminateProcess,你仍然很难知道会发生什么,如果这是你需要担心的事情的话。如有必要,您可以通过在Windows中将其设置为服务,并在其死机时使用操作系统的功能重新启动它来解决此问题。(这只是稍微改变了一点;有人仍然可以停止服务。)在这一点上,您可能需要通过创建文件等持久性操作来表示成功完成。

有一些关于通过挂接NT内部来防止最终进程尝试的内容,但您真正想要的是看门狗或对等进程(合理的方法)或某种拦截灾难性事件的方法(相当危险)

编辑:有一些原因使这变得困难,但有可能拦截或阻止终止进程的尝试。我知道你只是想在退出前进行清理,但一旦有人发布了一个不能立即终止的进程,就会有人要求立即终止它,以此类推。无论如何,要沿着这条路走下去,请查看上面链接的帖子,并在其中搜索一些关键字以获取更多信息。钩子或过滤器NtTerminateProcess等等。我们在这里讨论内核代码、设备驱动程序、防病毒、安全性、恶意软件、rootkit之类的东西。在这方面有帮助的书有,和,当然。这些东西编写起来不太难,但要做到恰到好处却相当敏感,而且可能会带来意想不到的副作用

也许会有用?受Vista和Server 2008及更高版本的支持

ApplicationRecoveryCallback回调函数应用程序定义的回调函数,用于在应用程序遇到未处理的异常或变得无响应时保存数据和应用程序状态信息

在使用SetUnhandledExceptionFilter时,建议为使其可靠工作,在内存中修补该方法是确保调用筛选器的唯一方法。建议改为使用uuu try/uuuu except包装。无论如何,本文中有一些示例代码和对SetUnhandledExceptionFilter的过滤调用的讨论


另外,请参见Aweasome Factor,以了解AddVectoredExceptionHandler

1的一些示例代码。Win32

Win32 API包含通过函数执行此操作的方法,如下所示:

LONG myFunc(LPEXCEPTION_POINTERS p)
{
     printf("Exception!!!\n");     
     return EXCEPTION_EXECUTE_HANDLER;
}

int main()
{
     SetUnhandledExceptionFilter((LPTOP_LEVEL_EXCEPTION_FILTER)&myFunc);    
     // generate an exception !
     int x = 0;
     int y = 1/x;
     return 0;
}
2。POSIX/Linux


我通常通过函数执行此操作,然后适当地处理SIGSEGV信号。您还可以处理SIGTERM信号和SIGINT,但不能处理SIGKILL(通过设计)。您可以使用获取回溯来查看是什么导致了该信号

几年前,我在ddj.com上发表了一篇关于“事后调试”的文章

它包括用于windows和unix/linux检测异常终止的源代码。根据我的经验,使用SetUnhandledExceptionFilter安装的windows处理程序并不总是调用。在许多情况下,它被调用,但我从客户那里收到了相当多的日志文件,其中不包括来自已安装处理程序的报告,即访问冲突是原因


我认为这可能会有所帮助。你有一个样本片段吗?-但这是最简单的一个,网络上有更复杂的崩溃处理程序(例如,在CodeProject上)。我尝试过,看起来不错,但如果我杀死了进程(从任务管理器等),它不会检测到。从MSDN:如果进程被TerminateProcess终止,则进程的所有线程都会立即终止,而没有机会运行其他代码。这意味着线程不会在终止处理程序块中执行代码。此外,不会通知已连接的DLL进程正在分离。“.谢谢,但这没什么帮助。我能赶上正常的终止。谢谢。我以前见过。有两个问题,tho。1) 我必须支持XP。2) 我不需要从车祸中恢复过来。我只需要保存一些文件并在关闭应用程序之前关闭数据库连接(正常或崩溃之前)。明白了。加了一些