Application.ThreadException vs AppDomain.UnhandledException
Asked Answered
P

3

12

First some background: I have a multi-threaded WinForms application that is doing interop to native dlls. This application crashes sometimes with unhandled exception and we are trying to investigate why does it happen. In order to facilitate it, I am creating a global exception handler and I plan to generate process dumpfile from it.

Now coming towards question: as of now this application has handler for Application.ThreadException but it still crashes with unhandled exception. I am thinking of adding a handler for AppDomain.UnhandledException also although I am not sure if its going to help. Are there any possible unhandled exception in this scenario that will not be caught by Application.ThreadException?

Paulino answered 24/5, 2011 at 18:19 Comment(1)
S
24

Yes, Application.ThreadException can only trap exceptions that are raised in the UI thread. In code that's run due to Windows notifications. Or in technical terms, the events that are triggered by the message loop. Most any Winforms event fit this category.

What it does not trap are exceptions raised on any non-UI thread, like a worker thread started with Thread.Start(), ThreadPool.QueueUserWorkItem or a delegate's BeginInvoke() method. Any unhandled exception in those will terminate the app, AppDomain.UnhandledException is the last gasp.

Going further down-hill, hardware exceptions that are raised in an unmanaged thread by native code that never made any managed CLR call can not be detected with any CLR mechanism. An AccessViolation (exception code 0xc0000005) is the most common cause of death. The only way to trap those is through the Windows API, SetUnhandledExceptionFilter(). This is hard to get right.

You can disable Application.ThreadException with Application.SetUnhandledExceptionMode(). Which is a wise thing to do, giving the user the Continue option doesn't make a lot of sense. Now all exceptions in managed threads behave the same, use AppDomain.UnhandledException to log them.

Sycophant answered 24/5, 2011 at 19:12 Comment(0)
A
8

Application.ThreadException will only be raised for unhandled exceptions on WinForms UI threads (see here.) Adding a handler for AppDomain.UnhandledException could help in this case (though with some caveats, as described in the remarks section here.)

Amphibolite answered 24/5, 2011 at 18:25 Comment(0)
E
3

I highly recommend that you use the OS minidump generation instead of your own. This is for several reasons:

  1. Generating a minidump from within the same process is extremely problematic and not always possible.
  2. By the time ThreadException or UnhandledException is started, the exception stack has already been unwound. Generating a minidump at that point will just point you to the handler, not the source of the exception.

If your app is in the field, use WER. If you're doing in-house testing, use ProcDump. You can also just copy the minidump file while the Error Reporting dialog is active.

P.S. There are some exceptional conditions - most notably when doing p/Invoke - where neither ThreadException nor UnhandledException will work.

P.P.S. If you have a debuggable scenario, then try turning on the Managed Debugging Assistants relating to p/Invoke.

Edelman answered 24/5, 2011 at 18:33 Comment(3)
Yeah I am generating OS minidumps although I prefer to use AdPlus to generate these dumps. Thanks for advice though :)Paulino
Let me clarify: it's not a good idea to have your code (in the same process) create the minidump. Quoting from the MiniDumpWriteDump documentation: MiniDumpWriteDump should be called from a separate process if at all possible, rather than from within the target process being dumped. This is especially true when the target process is already not stable. For example, if it just crashed. ... MiniDumpWriteDump may not produce a valid stack trace for the calling thread.Edelman
Having WER or ProcDump create the minidumps for you avoids those problems.Edelman

© 2022 - 2024 — McMap. All rights reserved.