如何在.NET的WinForms应用SetUnhandledExceptionFilter工作? [英] How does SetUnhandledExceptionFilter work in .NET WinForms applications?

查看:239
本文介绍了如何在.NET的WinForms应用SetUnhandledExceptionFilter工作?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我工作的一个项目,以提高我们的生产调试功能。我们的目标是可靠地生产小型转储任何未处理的异常,异常是否托管或非托管,以及它是否发生在一个托管或非托管线程。

我们使用优秀 ClrDump 的库这个目前,但它并没有完全满足我们的确切特征,我想了解背后的异常过滤机制,所以我开始尝试这种自己。

我开始按照此博客文章中安装一个SEH处理自己:<一href="http://blogs.microsoft.co.il/blogs/sasha/archive/2007/12.aspx">http://blogs.microsoft.co.il/blogs/sasha/archive/2007/12.aspx.这种技术适用于控制台应用程序,但是当我尝试同样的事情从一个WinForms应用程序,我的过滤器没有要求任何种类的非托管异常。

有什么可以ClrDump做,我不是在做什么? ClrDump产生转储在所有情况下,因此,其例外滤波器仍然必须称为...

注:我知道ADPlus的的能力,我们也考虑过使用的AeDebug注册表项...这些也是可能性,但也有自己的权衡

谢谢, 戴夫

适用

  // code来自以下; HTTP://blogs.microsoft.co.il/blogs/sasha/archive/2007/12.aspx>
LONG WINAPI MyExceptionFilter(__在结构_EXCEPTION_POINTERS * ExceptionInfo)
{
   的printf(本机异常过滤器:%X \ N,ExceptionInfo-&GT; ExceptionRecord-&GT;例外code);

   蜂鸣(1000,1000);
   睡眠(500);
   蜂鸣(1000,1000);

   如果(oldFilter_ == NULL)
   {
      返回EXCEPTION_CONTINUE_SEARCH;
   }

   龙RET = oldFilter_(ExceptionInfo);
   的printf(其他处理函数返回%D \ N,RET);

   返回RET;
}



的#pragma管理

命名空间SEHInstaller
{
   公共引用类SEHInstall
   {
   上市:
      静态无效InstallHandler()
      {
         oldFilter_ = SetUnhandledExceptionFilter(MyExceptionFilter);
         的printf(已安装的处理程序旧=%×\ N,oldFilter_);
      }


   };
}
 

解决方案

Windows窗体有一个内置的异常处理程序的默认操作如下:

  • 在捕获一个未处理的托管异常时:
    • 在不附加调试器,和
    • 在异常窗口消息处理过程中出现,和
    • jitDebugging =虚假的app.config。
  • 显示对话框,用户和prevents应用程序终止。

您可以通过在App.config中设置的 jitDebugging = TRUE 禁用前的行为。这意味着,你最后一次机会停止应用程序终止是通过注册事件Application.ThreadException,如捕捉未处理的异常在C#:<​​/ P>

  Application.ThreadException + =新Threading.ThreadExceptionHandler(CatchFormsExceptions);
 

如果您不打算在这里捕捉未处理的异常,那么你将需要检查和/或更改注册表设置的 DbgJitDebugLaunchSetting 在HKLM \ Software.NetFramework。这有三个值,其中我知道之一:

  • 0:显示用户对话框,询问调试或终止
  • 1:通过为CLR处理让例外
  • 2:启动在DbgManagedDebugger注册表项中指定的调试器

在Visual Studio中,转到工具>选项>调试> JIT设置此键为0或2。但值为1,通常您希望最终用户的计算机上是什么。请注意,此注册表项,你讨论的CLR未处理的异常事件发生之前采取行动。

然后,您可以设置您讨论的本机异常过滤器。

I am working on a project to enhance our production debugging capabilities. Our goal is to reliably produce a minidump on any unhandled exception, whether the exception is managed or unmanaged, and whether it occurs on a managed or unmanaged thread.

We use the excellent ClrDump library for this currently, but it does not quite provide the exact features we need, and I'd like to understand the mechanisms behind exception filtering, so I set out to try this for myself.

I started out by following this blog article to install an SEH handler myself: http://blogs.microsoft.co.il/blogs/sasha/archive/2007/12.aspx. This technique works for console applications, but when I try the same thing from a WinForms application, my filter is not called for any variety of unmanaged exceptions.

What can ClrDump be doing that I'm not doing? ClrDump produces dumps in all cases, so its exception filter must still be called...

Note: I'm aware of ADPlus's capabilities, and we've also considered using the AeDebug registry keys... These are also possibilities, but also have their tradeoffs.

Thanks, Dave

// Code adapted from <http://blogs.microsoft.co.il/blogs/sasha/archive/2007/12.aspx>
LONG WINAPI MyExceptionFilter(__in struct _EXCEPTION_POINTERS *ExceptionInfo)
{
   printf("Native exception filter: %X\n",ExceptionInfo->ExceptionRecord->ExceptionCode);

   Beep(1000,1000);
   Sleep(500);
   Beep(1000,1000);

   if(oldFilter_ == NULL)
   {
      return EXCEPTION_CONTINUE_SEARCH;
   }

   LONG ret = oldFilter_(ExceptionInfo);
   printf("Other handler returned %d\n",ret);

   return ret;
}



#pragma managed

namespace SEHInstaller
{
   public ref class SEHInstall
   {
   public:
      static void InstallHandler()
      {    
         oldFilter_ = SetUnhandledExceptionFilter(MyExceptionFilter);
         printf("Installed handler old=%x\n",oldFilter_);
      }


   };
}

解决方案

Windows Forms has a built-in exception handler that does the following by default:

  • Catches an unhandled managed exception when:
    • no debugger attached, and
    • exception occurs during window message processing, and
    • jitDebugging = false in App.Config.
  • Shows dialog to user and prevents app termination.

You can disable the first behaviour by setting jitDebugging = true in App.Config. This means that your last chance to stop the app terminating is to catch the unhandled exception by registering for the event Application.ThreadException, e.g. in C#:

Application.ThreadException += new Threading.ThreadExceptionHandler(CatchFormsExceptions);

If you decide not to catch the unhandled exception here, then you will need to check and/or change the registry setting DbgJitDebugLaunchSetting under HKLM\Software.NetFramework. This has one of three values of which I'm aware:

  • 0: shows user dialog asking "debug or terminate".
  • 1: lets exception through for CLR to deal with.
  • 2: launches debugger specified in DbgManagedDebugger registry key.

In Visual Studio, go to Tools>Options>Debugging>JIT to set this key to 0 or 2. But a value of 1 is usually what you want on an end-user's machine. Note that this registry key is acted on before the CLR unhandled exception event that you discuss.

Then you can set the native exception filter that you discussed.

这篇关于如何在.NET的WinForms应用SetUnhandledExceptionFilter工作?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆