在 Visual Studio 中按下“停止调试”按钮时拦截信号/事件

Posted

技术标签:

【中文标题】在 Visual Studio 中按下“停止调试”按钮时拦截信号/事件【英文标题】:Intercept signal / event when 'Stop Debugging' button is pressed in Visual Studio 【发布时间】:2014-09-16 19:09:33 【问题描述】:

背景:我正在为一个将格式化结果输出到指定目录的 API 编写一个 QA 自动化平台。此外,我还开发了一个用于分析这些结果的 GUI 应用程序。用户可以运行第二个应用程序来尝试分析测试结果,而我们的自动构建系统正在运行第一个应用程序修改/生成新的测试数据。为了避免颠簸,我让每个应用程序在进行修改时获取文件锁,并在完成后释放它们。在正常程序终止时,如果正在运行的应用程序获得了对数据目录的锁定,则将其释放。

问题:当任一工具过早存在时(用户按 CTRL-C、用户在调试器中停止应用程序或由于错误的 API/应用程序逻辑),我需要能够释放上述文件锁定正在测试中)。为了解决这个问题,我使用sigaction 实现了一个信号处理程序,它处理拦截致命信号(经过测试和工作),并通过Win32 函数SetConsoleCtrlHandler 实现了一个ctrl-c 处理程序。但是,我似乎无法找到一种方法来拦截用户在 Visual Studio 中按下 Stop Debugging 按钮的事件。我假设这个事件会产生类似 SIGKILL / SIGSTOP 的东西(不能通过 sigaction 处理),但我也希望有一些标准库或 Win32 功能来拦截这个事件并执行一些清理。你们知道处理这个事件的方法,甚至知道这个按钮究竟是做什么来杀死正在运行的应用程序的吗?

【问题讨论】:

该按钮将调用TerminateProcess。目标进程无法拦截它。然而,一个垂死的进程会自动释放所有的锁(以及所有的句柄和所有的内存)。什么不适合你? 由于文件锁是通过 nfs 获取的,我不能使用flock。我也不能使用 fnctl,因为它在 Windows 上不可用。我使用 mkdir / rmdir 如这篇文章所述:***.com/questions/6228915/… 或许在非Windows平台上使用F_SETLK/F_UNLCK fcntl锁,在windows上使用一些Win32锁功能会更好。你知道在 nfs 上工作的任何 Win32 文件锁定功能吗? 使用msdn.microsoft.com/en-us/library/windows/desktop/… 【参考方案1】:

如果您使用的是 boost,则可以使用 boost::interprocess::windows_shared_memory

保证在进程结束时释放。

在这种情况下,Boost 只是 Windows API 的一个简洁的包装器。它封装了 Windows Named Shared Memory API。

【讨论】:

以上是关于在 Visual Studio 中按下“停止调试”按钮时拦截信号/事件的主要内容,如果未能解决你的问题,请参考以下文章

Visual Studio:如何在修改成员变量时停止调试器?

停止在Visual Studio 2015中进行调试

Visual Studio 中的“停止调试”和“全部终止”有啥区别?

Visual Studio 2013 如何在停止调试Web程序后阻止IIS Express关闭

Visual Studio 2010:在断点处停止调试器过夜 = 在下一步后冻结

Visual Studio 2013 如何在停止调试Web程序后阻止IIS Express关闭