Debugger stoppt nicht bei Fehlern

  • VB.NET

Es gibt 16 Antworten in diesem Thema. Der letzte Beitrag () ist von thefiloe.

    Debugger stoppt nicht bei Fehlern

    Hallo zusammen!

    Folgender simpler Code:

    VB.NET-Quellcode

    1. Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    2. Dim a(2) As String
    3. a(3) = "Hallo"
    4. End Sub


    Egal, was ich mache, der Debugger bleibt einfach nicht mehr beim Fehler stehen. Beim Konfigurations-Manager ist der Debug-Modus eingestellt und die Visual-Studio Einstellungen habe ich unter "Extras/Einstellungen exportieren oder importieren" komplett zurücksetzen lassen. Ein Upgrade von VS 2008 auf VS 2010 hat ebenfalls nicht geholfen. Ausserdem sind unter "Debuggen/Ausnamen" im rechten Feld unter "Vom Benutzercode unbehandelt" alle Checkboxes an. Der Fehler wird im Ausgabefenster auch angezeigt, aber kein Fensterchen, keine Unterbrechung. Im Gegenteil: Die fehlerhafte Routine wird einfach ignoriert und alle weiteren Programmzeilen in der gleichen Routine werden nicht mehr ausgeführt. Bei obrigem Beispiel wird sogar die Form angezeigt.

    Der Witz an der Sache:
    Pack ich nen Button auf die Form, packe fehlerhaften Code in das Click-Ereignis und drücke anschließend den Button, dann bemerkt der Debugger auf einmal den Fehler, unterbricht das Programm und zeigt mit den Fehler. Das tut er allerdings nicht im Form_Load-Ereignis.

    Ich habe schon mind. 5 Stunden gegoogled und keinen funktionierenden Lösungsvorschlag gefunden.

    Bitte, bitte helft mir. Ich bin für jeden Tipp dankbar!!!
    hmm, die spontan verdächtigen Eigenschaften hast Du ja schon untersucht
    - PC Booten + neues Projekt anlegen, passiert es dort genauso ?
    - unter Projekteigenschaften Debuggen steht "Projekt starten" und Visualstudio Hostingprozess aktivieren ?
    - mal in einer Kommandobox oder unter Ausführen "devenv.exe /ResetSettings" eingegeben ?
    - irgendetwas im Ereignisprotokoll ?

    Mehr fällt mir zu dieser Stunde auch nicht ein ...

    Nachtrag: gerade gesehen , dass Du schon vor Weihnachten Probleme mit Deinem Debugger gepostet hattest. Als Abhilfe hattest Du einen Upgrade auf VS 2010 genannt, was wohl leider überhaupt nichts bringt wenn Dir irgendwo Registry-Werte zerschossen hattest (TuneUp?). Die Frage ist, ob Du hier nicht mal wirklich eine Neuinstallation in Betracht ziehen solltest, und zwar auf ein frische installiertes System um Registry Probleme ausschliessen zu können.

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Kangaroo“ ()

    Vielen Dank erstmal für deinen Versuch mir zu helfen. Echt verrückt: Im Internet gibt's hin und wieder Personen mit dem gleichen Fehler und nirgends einen Lösungsweg. Vielleicht finden wir bei vb-paradise ja einen...

    Zu deinen Lösungsvorschlägen:
    - In neuen Projekten bleibt der Fehler nach wie vor.
    - unter Projekteigenschaften Debuggen sind "Projekt starten" und Visualstudio Hostingprozess aktiviert
    - "devenv.exe /ResetSettings" hat zwar die Einstellungen resettet, brachte aber nichts.
    - Welches Ereignisprotokoll meinst du?
    - TuneUp & Co benutze ich mit Absicht nicht.

    Das komische ist ja, dass der Fehler im Direktfenster erkannt wird:
    "Eine Ausnahme (erste Chance) des Typs "System.IndexOutOfRangeException" ist in WindowsApplication1.exe aufgetreten."
    Nur stoppt der Debugger nicht, sonder verlässt ohne Fehlermeldung einfach die Routine. Und wie schon gesagt: Wird der fehlerhafte Code in einem Button-Click-Ereignis ausgelöst, dann klappt's mit einmal: Der Debugger stoppt den Code und macht mich auf den Fehler aufmerksam. Als ob der Debugger nur den Start der Anwendung verpennt.

    Hat jemand noch eine Idee? Und sei es auch nur eine klitzekleine Idee? *bettel* Habe keine Lust Windows 7 neu zu installieren. :(
    Win x64?

    Dann: stackoverflow.com/questions/15…at-does-not-crash-the-pro
    bzw: connect.microsoft.com/VisualSt…bugging-in-vb2008-express

    Gerade mal getestet:
    Throw New Exception in Form_Load

    VS 2010 Pro auf Win7x64 -> first chance exc, Debugger läuft drüber
    VS 2008 Pro auf Win7x64 -> wie oben

    VS 2008 Pro auf Vista x86 -> Debugger bleibt in der Zeile stehen

    scheint obiges also zu stimmen und man kann machen nix ;)


    More info:
    connect.microsoft.com/VisualSt…-x64-development-machines
    Von Paul C Betts am 27.07.2010 um 14:00 bereitgestellt
    There is now a hotfix for Windows that corrects this issue, please see:

    support.microsoft.com/kb/976038

    and for the details, read the blog post at:

    blog.paulbetts.org/index.php/2…llback-exceptions-in-x64/

    evtl mal checken?

    ... done ;)

    Bei MS mal nach dem Hotfix geschaut. Den kann man sich per EMAIL schicken lassen. Ist nämlich eigentlich Teil des SP1 für Win7 ... und das ist ja noch nicht public.
    Also einfach mal auf das SP1 warten!


    Finally
    blog.paulbetts.org/index.php/2…llback-exceptions-in-x64/
    (s.oben)
    Da steht es GANZ genau erklärt, warum es so ist, wann es passiert etc. Ist im Prinzip kein "Bug", sondern mehr ne Art Design-Entscheidung. Der "Fix" ermöglicht es dann nur dieses Verhalten nach eigenen Wünschen zu ändern - oder halt nicht

    Dieser Beitrag wurde bereits 3 mal editiert, zuletzt von „picoflop“ ()

    Vielen Dank picoflop für deine ausführliche Suche. Du scheinst dich sehr gut auszukennen. Diese Artikel habe ich in der Tat noch nicht gefunden. Und: Ja, ich nutze wirklich Windows 7 64 für den Heim-PC.

    Dummerweise funktioniert der Hotfix auch nicht ganz wie gewünscht. Nach der Installation, des setzen des Regitry-Eintrags und des anschliessenden Startens des fehlerhaften Quellcodes bekomme ich eine Windows-Fehlermeldung über eine unbehandelte Ausnahme. Kurz darauf blinkt der normalerweise erscheinende Debugger kurz auf und verschwindet direkt wieder. In 1 von 5 Fällen schmiert das ganze VS ab.

    Evtl. klappts ja mit dem hier erwähnten API-Aufruf . Aber dann müsste man prüfen, ob ich gerade debugge, weil der API-Aufruf aufgrund des fehlendes Windows-Patches auf Client-Seite dann ja ins leere gehen würde. Evtl. dann so:

    VB.NET-Quellcode

    1. If Debugger.IsAttached Then
    2. Dim dwFlags As DWORD
    3. If GetProcessUserModeExceptionPolicy(AddressOfdwFlags) Then
    4. ' turn off bit 1
    5. SetProcessUserModeExceptionPolicy(dwFlags And Not PROCESS_CALLBACK_FILTER_ENABLED)
    6. End If
    7. End If


    Das wäre meine letzte Hoffnung, das Problem irgendwie in den Griff zu kriegen.

    Ich bin API-mässig leider nicht so bewandert. Wie krieg ich die Verknüpfung zur Kernel32.dll denn hin, damit obriger API-Aufgruf funzt?

    Du scheinst dich sehr gut auszukennen.

    Nö, aber ich google sehr gut ;)

    Hast du auch das mit dem Windows7 Manifest ausprobiert? Dazu stand ja mW auch was in dem Blog
    msdn.microsoft.com/en-us/library/dd371711(v=vs.85).aspx


    Wie krieg ich die Verknüpfung zur Kernel32.dll denn hin

    Du meinst sowas?
    devtrain.de/news.aspx?artnr=709

    Beim importieren von API-Funktionen bitte beachten, dass viele Beispiele vür VB6 sind, und dann dann denken das VB6 int 16 bit sind und .Net Int sind 32 bit. Selbiges bei long vs long.

    Ungetestet ... !!!

    <DllImport("kernel32.dll")> Private Shared Function GetProcessUserModeExceptionPolicy(ByRef dw As Int32) As Boolean
    <DllImport("kernel32.dll")> Private Shared Function SetProcessUserModeExceptionPolicy(Byval dw As Int32) As Boolean

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „picoflop“ ()

    Die Manifest-Datei habe ich auch bearbeitet und für Windows 7 angepasst. Leider auch ohne Erfolg. Mit dem Hotfix scheint es mir so, als würde VS die Exception zu spät empfangen. Deshalb kommt ein Fehlerbildschirm, dass eine unbehandelte Ausnahme aufgetreten ist. Klicke ich dort auf "Ok", dann sieht man für einen kurzen Augenblick den richtigen Debugger, der auf den falschen Code zeigt. Danach war's das.

    Thx für den API-Anstoss. Der Code wäre dann z.Z. wie folgt:

    VB.NET-Quellcode

    1. <DllImport("KERNEL32.DLL")> Public Shared Function GetProcessUserModeExceptionPolicy(ByVal dw As Int32) As Boolean
    2. End Function
    3. <DllImport("KERNEL32.DLL")> Public Shared Function SetProcessUserModeExceptionPolicy(ByVal dw As Int32) As Boolean
    4. End Function
    5. Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    6. If Debugger.IsAttached Then
    7. Dim dwFlags As DWORD
    8. If GetProcessUserModeExceptionPolicy(AddressOfdwFlags) Then
    9. ' turn off bit 1
    10. SetProcessUserModeExceptionPolicy(dwFlags And Not PROCESS_CALLBACK_FILTER_ENABLED)
    11. End If
    12. End If
    13. End Sub


    Nur: Was soll jetzt DWORD für ein Datentyp sein und was gebe ich den Funktionen überhaupt für Überhabewerte? ?(

    Enixus schrieb:

    Was soll jetzt DWORD für ein Datentyp sein

    "Doppel-Wort" = 32 Bit
    An die "Get" übergibst du einen beliebigen Int32. Wert egal, da der als ByRef übergeben wird und quasi die aktuelle Einstellung zurückliefert. Beim Set setzt du dann das entsprechende Bit (OR) in diesem Wert oder löscht es (AND NOT) - das Bit in diesem Fall ist "0x1" also "1".

    Nachtrag:
    WAHRSCHEINLICH ist es da beste, den Fehler zum "umgehen"?
    d.h. problematischen Code gar nicht erst ins LoadEvent packen? Oder - weiß nicht ob das geht/hilft - den eigentlichen Code in einen Thread packen auf diesen Thread warten.

    VB.NET-Quellcode

    1. Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    2. Dim t As New System.Threading.Thread(AddressOf foo)
    3. t.Start()
    4. t.Join()
    5. End Sub
    6. Private Sub foo()
    7. Debug.Print("throw exception")
    8. Throw New Exception
    9. End Sub

    So wird jedenfalls der Debugger aufgerufen. Wird natürlich Frickelkram, wenn man auf den GUI-Thread zugreifen muss (wegen invoke etc)

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „picoflop“ ()

    Datt lüppt alles trotzdem nich`so wirklich. Mein API-Aufruf scheint scheint selbst schon wieder fehlerhaft zu sein. Ich hoffe auf das Win 7 SP1.

    Fänd ich extrem blöd, wenn Microsoft das nicht gebacken bekäme.

    Dank dir sehr für deine kompetente Hilfe, Picoflop! :) Jetzt heisst es nur noch: Daumen drücken! :)

    Enixus schrieb:

    Ich hoffe auf das Win 7 SP1.

    Ich würde wirklich besser versuchen, den Fehler zu "umgehen". Ganz offensichtlich ist es bei x64 nicht trivial, wenn ein Fehler im onLoad auftritt. Also sollte man dafür sorgen, dass dort NIE ein Fehler auftreten kann. Also entweder in einem separaten Thread ausführen (s.oben) oder eine Art "Init" Funktion schreiben die NACH dem Form Load explizit aufgerufen werden muss. Wobei das mit dem Thread "einfacher" ist, weils nach außen hin quasi unsichtbar ist. Und durch das Thread.Join ist das verhalten praktisch das gleiche wie bei einem normalen _Load wo der komplette Code im Load event steht.
    In der Form_Load ist das nun mal leider so.
    Schieb die "fehlerhafte" Prozedur in eine Button_Click() und schon knallt es. :D

    VB.NET-Quellcode

    1. Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    2. Dim a(2) As Integer
    3. a(4) = 4 ' es passiert nichts
    4. End Sub
    5. Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
    6. Dim a(2) As Integer
    7. a(4) = 4 ' es knallt
    8. End Sub
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    VB-Fragen über PN / Konversation werden ignoriert!
    Ich hab mir jetzt geholfen, indem ich mir einen Timer mit sehr kurzem Intervall erstelle, aber auch nur, wenn "Debugger.IsAttached = True" ist. Und falls Debugger.IsAttached = false, dann wird die Routine direkt aufgerufen.

    Einen eigenen Thread aufzumachen würde zu krasse Änderungen an meinem bisherigen Code verlangen. Ich müsste sehr viele Form-Objekte viá Delegaten verfügbar machen. Da hab ich irgendwie gar kein Bock drauf. :)

    Das SP1 für Win7 ist ja bereits geleaked. Kann also nicht mehr lange dauern, bis das offizielle SP raus ist. Bin gespannt, ob das Fehlverhalten dann weg ist.

    Enixus schrieb:

    Ich hab mir jetzt geholfen, indem ich mir einen Timer mit sehr kurzem Intervall erstell

    I is not friend of timer ... ;)

    VB.NET-Quellcode

    1. Private Delegate Sub dfoo()
    2. Private Sub foo()
    3. Debug.Print("foo" & System.Threading.Thread.CurrentThread.ManagedThreadId)
    4. Throw New Exception
    5. End Sub
    6. Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
    7. Debug.Print("load" & System.Threading.Thread.CurrentThread.ManagedThreadId)
    8. BeginInvoke(New dfoo(AddressOf foo))
    9. End Sub

    So gehts auch und das dürfte den kleinsten footprint haben. An der ThreadID kann man sehen, dass man immer noch im GUI-Thread ist, also kein Problem mit Controls etc.

    EDIT: Blöd ich bin ... ;)

    VB.NET-Quellcode

    1. Private Delegate Sub dfoo()
    2. Private Sub foo()
    3. Debug.Print("foo" & System.Threading.Thread.CurrentThread.ManagedThreadId)
    4. Throw New Exception
    5. End Sub
    6. Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
    7. Debug.Print("load" & System.Threading.Thread.CurrentThread.ManagedThreadId)
    8. Invoke(New dfoo(AddressOf foo))
    9. Debug.Print("Done with load")
    10. End Sub

    So gehts super und ist EXAKT das "normale" Verhalten (Invoke statt BeginInvoke!). D.h. "Load" ist nicht beendet bevor "foo" läuft (load -> foo -> load !) und der Debugger funzt trotzdem. Ob's im Debugger läuft oder nicht braucht man IMHO kaum zu prüfen, weil der Overhead durch Invoke nicht so groß ist.

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „picoflop“ ()

    Vielen Dank für diesen tollen Ratschlag. Hoffentlich sucht er nach mehr als 3 Jahren nicht noch immer nach dem selben Problem.


    Opensource Audio-Bibliothek auf github: KLICK, im Showroom oder auf NuGet.