How MDBG process Unhandled Exception

Hi All,

I use MDBG to debug a .NET application, which throws Unhandled Exception from some code.

MDBG could capture it easily. It give below hints.

STOP: Unhandled Exception thrown

Exception=...

... ...

This is unhandled exception, continuing will end the process

But i want to let debuggee popup up an Unhandled Exception Dialog, then give the user a choice about whether continue or quit. It is the default behavior when CLR meet Unhandled Exception.

When i debug the application within VS2005, it will popup the dialog. But when i use MDBG debug the application, then type "go", the process will end immediately.

So i want to know how to modify MDBG to get the same effect as VS2005

Thanks.

ding



Answer this question

How MDBG process Unhandled Exception

  • WarehouseMan

    Hi Ding, thanks for your answers.

    Just to double check, you are using .NET 2.0 and VS 2005, right I did some more experiments and I think I understand what you're seeing now. Here's what I think is happening - correct me if I get any of the details wrong:

    You're starting your winforms app OUTSIDE the debugger (eg. Ctrl-F5 launch or run from command line), and then after the program has started you're attaching the debugger. Then when it crashes, VS gives you the message "DivisionByZeroException was unhandled by user code" (not "DivisionByZeroException was unhandled"). You can then continue and get the winforms unhandled exception dialog box.

    Assuming that is the correct scenario, here's what's going on. When you start the application, WinForms doesn't see a debugger and so it uses the non-debugging version. Specifically, when in a WinForms callback, you can see System.Windows.Forms.NativeWindow.Callback on the stack. When a Debugger is attached on startup, WinForms uses System.Windows.Forms.NativeWindow.DebuggableCallback instead. The difference between Callback and DebuggableCallback is that Callback catches the exception and invokes "Application.ThreadContext.OnThreadException", where DebuggableCallback doesn't catch the exception at all. This means that in normal debugger scenarios the exception remains unhandled and shows up as an unhandled exception. The motivation here is that when under a debugger they want to give you the chance to see the exception at the point it occurred, instead of unwinding to Callback and stopping in the exception dialog. So the question becomes then, when you attach a debugger later, how is VS giving you an "unhandled exception" notification at all This is where the "by user code" part is important. You have the "Just-my-code" debugging feature enabled, and so VS sees that an exception was thrown that escapes your code and conveniently stops for you even though the exception is handled by WinForms (we call this a "JMC-unhandled exception"). Since this isn't really an "unhandled exception", you can still continue and get into the OnThreadException code (real unhandled exceptions cannot be continued without terminating the process).

    So we're finally back to your original question of how to make MDbg do this. First of all, if you attach MDbg to your winforms app after it has started, you will get the "non-debugging" WinForms behavior where WinForms will pop an unhandled exception dialog for you. However, in this case MDbg doesn't stop at all by default when the exception is thrown because it's not an unhandled exception (and MDbg doesn't have any JMC support built-in). There are several options for getting MDbg to stop here:

    1. you could stop on all first-chance exceptions ("catch ex"), but you'll probably stop on a lot of other things you don't want to
    2. You could put a breakpoint inside of the WinForms Callback routine so you break when an exception gets there. However by then the exception has already unwound the stack so it's probably too late.
    3. You could add JMC support to MDbg and do exactly what VS does. This would take a bit of work, but isn't overly complex. Basically I think it would boil down to using the JMC APIs (eg. ICorDebugModule2::SetJMCStatus) to mark which code regions you want to consider "my code", and then using the exception notification (ICorDebugManagedCallback2::Exception) to see when the exception is escaping user code and stop there. I don't know the details of how to do this off the top of my head, but if you decide to go down this route I can help you through it.

    Alternately, if all you want to do is recover from an unhandled exception, in many situations you can also use the debugger to intercept the exception. Eg., you could do this even when using the "DebuggableCallback" version of WinForms (launch instead of attach). Again, MDbg has no built in support, but you could write an extension (or modify MDbg itself) to use ICorDebugThread2::InterceptCurrentException to unwind the stack back up to the winform callback, but no further - allowing the winforms thread to keep running.

    I hope this is helpful. Let me know if you need more help implementing one of these solutions...

    Rick


  • magicalclick

    Hi Rick,

    Thank for your fast response.

    The Unhandle Exception Dialog is in Winform Application. So It is 2nd dialog type you talked. The exception is just a simple one: DividedByZero. When i run the winform application without debugger, it will popup the dialog. Also when i run the debuggee within VS005, the Unhandled Exception will catch by VS firstly. If i click "Continue", the debuggee will popup the same dialog also. Then i can choose whether "continue" or "ingore".

    But if i do the same thing in MDBG(after catch the exception, just click go command), the dialog is disappear. And the debuggee is exit directly.

    So i wonder is it a way to let MDBG has the same effect with VS.

    Thanks.

    ding


  • sagan69

    Hi Rick,

    I forget to answer some of your questions.

    For Winforms applications, an unhandled exception on the GUI event thread will cause WinForms to pop up its own unhandled exception notification window ("Unhandled exception has occurred in your application. If you click Continue, the application will ignore this error and attempt to continue..."). Since this is actually inside of Winforms on the GUI event thread, Winforms can give you the option of ignoring the unhandled exception and continuing. Is this what you'd like to be able to do with a debugger attached

    Yes

    As far as I know, whenver a debugger is attached (VS or MDbg) WinForms won't give you that unhandled exception dialog (this is by design to ensure a good debugging experience - we want the exception to look unhandled, not get unwound to the handler in WinForms). Are you seeing that exact same dialog when running under the VS debugger If so, perhaps VS is doing something special I'm not aware of (I'm not a VS expert, but I've tried several things and haven't been able to get it to do this). Are you using VB or C# Do you have the "enable the exception assistant" option (tools->options->debugging) enabled

    I use C# to write the demo application, and "enable the exception assistant" is enabled.

    VS does have its own exception assistant dialog box, and can (in many situations) allow you to ignore an unhandled exception and continue excecution at some location. Is it just continuing from an unhandled exception that you'd like to be able to do from within a debugger

    Yes. I hope to have the same effect with VS. Also i think the "Unhandled Exception" dialog popups up in debuggee even it is debugged by VS. It is not a fake dialog created by VS. So i wonder how VS do it.

    Thanks.

    ding


  • Sanchit Bahal

    HI Rick,

    Thank for your kindly explanation.

    Yes, I attach the process withs VS. And VS gives you the message "DivisionByZeroException was unhandled by user code" (not "DivisionByZeroException was unhandled"). it is "JMC-unhandled exception" as you said.

    When i add set JMC in MDBG, It has the attach behavior as VS. I think your answer is helpful. It solved my question. It is cool.

    BTW, I still have a small question to ask.

    When i debug one executive file from VS directly (instead of attach it), It must use "DebuggableCallback" version of WinForms. The Exception Dialog becomes "DivisionByZeroException was unhandled". If i press "continue" button in VS, the same exception is popup again. It never stop to report the same exception, until i stop the debuggee. On the other side, After "DivisionByZeroException was unhandled" is captured in MBD, it will end debuggee at first time after i type "go" in MDBG .

    Do you know why it is different Does VS use some special trick to achieve it

    Thanks.

    ding


  • Sergei Dorogin

    Hi Ding,

    I'm glad that helped.

    VS is definiately doing something special to get the repeated unhandled exception behavior you're seeing. I'm not positive, but I suspect it's unwinding the exception and using SetIp to position the IP back before the instruction that threw. The idea here is probabably that the developer may want to change some memory value, or (using edit-and-continue) some code and retry the operation. This scenario is especially popular in Visual-Basic style RAD development. Intercepting the exception and using SetIp shouldn't be too hard to add to MDbg if you want (supporting EnC is a lot more work - see http://blogs.msdn.com/jmstall/archive/2005/02/19/376666.aspx).

    If you want to find out for sure exactly what VS is doing, we can either ask on a Visual Studio forum, or attach a debugger to VS and watch the calls to key ICorDebug APIs like SetIp.

    Rick


  • Alex-MyRpg

    Hi,

    There are several different types of unhandled exception dialog boxes which have all sorts of different behavior depending on the scenario. It's not quite clear to me which one you're referring to and what you'd like to be able to do. Here's a description of the various dialog boxes that can happen on an unhandled exception.

    When V2.0 .NET program has an unhandled exception (and is not running under a debugger) the CLR invokes the windows error reporting logic (aka Watson) which pops up the dialog box that says "foo.exe has encountered a problem and needs to close". This may give buttons for Close, Debug, send report, etc., but does not have an option to continue. Is this the dialog box you're talking about that you'd like to see while debugging Whenever a debugger is attached, I believe the CLR will never invoke watson, and so there is no way to get this dialog box when a debugger is attached.

    For Winforms applications, an unhandled exception on the GUI event thread will cause WinForms to pop up its own unhandled exception notification window ("Unhandled exception has occurred in your application. If you click Continue, the application will ignore this error and attempt to continue..."). Since this is actually inside of Winforms on the GUI event thread, Winforms can give you the option of ignoring the unhandled exception and continuing. Is this what you'd like to be able to do with a debugger attached

    As far as I know, whenver a debugger is attached (VS or MDbg) WinForms won't give you that unhandled exception dialog (this is by design to ensure a good debugging experience - we want the exception to look unhandled, not get unwound to the handler in WinForms). Are you seeing that exact same dialog when running under the VS debugger If so, perhaps VS is doing something special I'm not aware of (I'm not a VS expert, but I've tried several things and haven't been able to get it to do this). Are you using VB or C# Do you have the "enable the exception assistant" option (tools->options->debugging) enabled

    VS does have its own exception assistant dialog box, and can (in many situations) allow you to ignore an unhandled exception and continue excecution at some location. Is it just continuing from an unhandled exception that you'd like to be able to do from within a debugger

    Rick


  • How MDBG process Unhandled Exception