PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : C# Form.OnLoad + Exception


DocEW
2009-06-18, 16:29:31
Hi,

ich habe gerade ein sehr merkwürdiges Verhalten von C# unter Visual Studio 2008 festgestellt: Wenn man die OnLoad-Methode eines Forms überschreibt und dort eine Exception wirft (oder unfreiwillig erzeugt), und das Programm im Debug-Modus (mit F5) startet, hält der Debugger nicht bei der Exception an! Bei STRG+F5 kommt die Exception ganz normal.
Kann mir das jemand erklären?

Das Beispiel-Form kann ansonsten leer sein, also so aussehen:
using System;
using System.Windows.Forms;

namespace DebugExceptionTest
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}

protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
throw new Exception("Ha!");
}
}
}
Danke für Tipps! :)

DocEW

Gnafoo
2009-06-18, 17:24:12
Ich habe mal den .NET Reflector angeworfen [1]. Soweit ich es sehe wird ein unterschiedlicher Callback benutzt, je nachdem, ob man mit Debugger startet, oder nicht. Im Debug-Mode landet man bei NativeWindow.DebuggableCallback, ohne Debugger bei NativeWindow.Callback. Der Unterschied ist, dass NativeWindow.Callback folgendes tut:


catch (Exception exception)
{
this.OnThreadException(exception);
}


Das wiederrum wird in Form.ControlNativeWindow behandelt und macht nach einigen Umwegen folgendes:


Application.OnThreadException(e);


Kann man auch ganz schön sehen, wenn man einfach mal "Application.OnThreadException(new Exception("Ha!"));" in OnLoad hineinschreibt. Die interessante Frage ist allerdings, warum die Exception in NativeWindow.Callback verlorengeht.

Der Call Stack im Debugger sagt, dass vor dem Callback eine Native to Managed Transition stattfindet. D. h. der Callback kommt von unmanaged Code. Ich nehme mal an, dass er dort auch "irgendwie" verlorengeht. Ohne Debugger wird die Exception eben vor diesem Übergang abgefangen, um den Fehler zu erzeugen.

Wenn ich mit den .NET debug symbols [2] versuche, durch den .NET-Code zu gehen, sieht es auch so aus, als ob dort die Exception verloren geht. In allen Methoden über der Transition werden brav die finally-Blöcke abgearbeitet und unter der Transition geht er einfach mit der nächsten Zeile weiter, hinter dem Aufruf einer Win32-Funktion aus System.Windows.Forms.SafeNativeMethods.

[1] http://www.red-gate.com/products/reflector/
[2] http://blogs.msdn.com/sburke/archive/2008/01/16/configuring-visual-studio-to-debug-net-framework-source-code.aspx

Edit: hab noch etwas interessantes dazu gefunden:
http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=357311


Hi,

This is a known bug with x64 versions of Windows and the way exceptions are handled. [...]

Thanks,
Visual Studio Debugger Team

DocEW
2009-06-19, 09:11:30
Ah, cool, danke für deine Mühe!
Hab' also nix falsch gemacht. ;)