3

在 Microsoft Windows API 中,您可以使用SetUnhandledExceptionFilter为未处理的异常设置处理程序。该页面上提到的最大问题是:

如果在未调试的进程中发生异常,并且异常进入未处理的异常过滤器,则该过滤器将调用由 lpTopLevelExceptionFilter 参数指定的异常过滤器函数。

重点补充

这基本上意味着,如果进程正在调试,调试器会收到异常,并且我的过滤器会被跳过!

我可以使用 printfs 和 trial-n-error 以老式方式测试和调试我的 ExceptionFilter。

但我错过了什么吗?如果 ExceptionFilter 在调试器中被禁用,是否有一种交互式调试的好方法?

4

2 回答 2

3

查看KB173652的 Resolution 部分,该部分讨论将 main/WinMain 中的所有代码放在_try / _except 块中,如下所示。

void main (int argc, char **argv)
{
   __try
   {
   // all of code normally inside of main or WinMain here...

   }
   __except (MyUnFilter (GetExceptionInformation()))
   {
      OutputDebugString ("executed filter function\n");
   }
}

另一篇文章Debugging custom filters for unhandled exceptions描述了除上述技术之外的更多技术。我个人使用在异常过滤器中显示消息框然后附加调试器的方法。我使用IsDebuggerPresent来确定是否显示消息框。

于 2014-01-07T21:47:03.557 回答
2

我知道这篇文章已经存在了一段时间,但是,我只是偶然发现它正在寻找其他东西。我很高兴地说,如果过滤器存在于单独的 dll 中,用户 'abelenky' 的要求是可能的。您可以使用调试器调试未处理的异常过滤器。我已经做到了,方法如下:

  • 异常过滤器必须存在于单独的 dll 中。稍后你会明白为什么。

您需要向显示消息框的过滤器添加一些代码。我使用以下代码:

#ifdef _DEBUG
    AfxMessageBox (_T("At this time, you must attach the debugger to this process in order to debug the filter code."));
#endif

#ifdef 很重要,因为您不希望代码在 Release 构建中执行。我将上面的代码放在过滤器的最顶部。

调试过滤器

  1. 在 Visual Studio 中构建应用程序的发布版本(实例 #1)。
  2. 在 VS (#2) 的第二个实例中构建过滤器的调试版本。
  3. 将过滤器的调试版本复制到应用程序的发布文件夹。
  4. 从“调试”菜单“不进行调试”启动您的发布应用程序。
  5. 导致您的应用程序崩溃。
  6. 当调试消息框(上图)出现时,切换到 Visual Studio 的第二个实例 (#2)。
  7. 在 #2 实例中,在 Debug 中打开过滤器项目(如果它未打开)并将调试器附加到您的 Application 实例。
  8. 消息框显示后,在过滤器代码中设置断点。
  9. 关闭消息框,你的断点应该被命中。
  10. 继续调试您的代码。
于 2017-03-28T18:42:10.503 回答