32 Stimmen

Suche nach der Ursache von System.AccessViolationException

In unserer Anwendung kommt es zu der seltsamen fatalen System.AccessViolationException. Wir sehen diese, da wir das Ereignis AppDomain.CurrentDomain.UnhandledException zur Protokollierung der Ausnahme konfiguriert haben.

Exception: System.AccessViolationException: Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
   at System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg)
   at System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(IntPtr dwComponentID, Int32 reason, Int32 pvLoopData)
   at System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)
   at System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)
   at System.Windows.Forms.Application.Run(Form mainForm)
   at Bootstrap.Run() in e:\build-dir\src\Bootstrap.cs:line 25

Die Ausnahme selbst scheint nicht mehr Informationen zu enthalten als die Meldung "Es wurde versucht, geschützten Speicher zu lesen oder zu schreiben. Dies ist oft ein Hinweis darauf, dass anderer Speicher beschädigt ist."

  • Welche Schritte können wir nun unternehmen, um der Ursache des Problems auf den Grund zu gehen?
  • Gibt es eine Möglichkeit, die illegale Adresse oder den Zeigerwert zu ermitteln, der den Absturz verursacht hat?
  • Können wir herausfinden, welcher native Bibliothekscode das Problem verursacht hat?
  • Gibt es mehr Debugging/Verfolgung, die wir aktivieren können?

UPDATE

  • Könnte dies durch eine frühere, nicht thread-sichere Verwendung der WinForms-API verursacht werden?

7voto

Mike Caron Punkte 14061

Was Sie erleben, ist das genaue Äquivalent zu "Das Programm hat ein Problem festgestellt und wird jetzt geschlossen", außer dass es von der .NET-Laufzeitumgebung und nicht vom Betriebssystem abgefangen wird.

Mit Blick auf die Stack-Trace, es ist nicht durch Ihren Code ausgelöst, was mich denken lässt, dass es von einem Worker-Thread von einer Bibliothek, die Sie verwenden oder ein benutzerdefiniertes Steuerelement erzeugt kommt.

Die einzige Möglichkeit, so etwas zu verfolgen, besteht darin, die nativen Bibliotheken unter einem Debugger auszuführen, der die Zugriffsverletzung aufspüren sollte, bevor sie in die CLR-Schicht gelangt. Dies kann einfach oder schwer sein.

Wenn es sich bei dem nativen Code um Ihr eigenes Projekt handelt, ist es am einfachsten, sowohl das .NET-Projekt als auch das C++-Projekt in dieselbe Projektmappe aufzunehmen und sicherzustellen, dass das .NET-Projekt auf das C++-Projekt verweist. Wenn Sie mehr Details über Ihre Umgebung angeben, kann ich Ihnen vielleicht genauere Ratschläge geben.

3voto

Steve Mitcham Punkte 5131

Der Stack-Trace weist auf fehlerhafte Daten im MSG-Parameter des nativen Dispatch-Messengers hin. Haben Sie versucht, die Symbole von Microsoft zu laden und die Parameter dieses Stack Trace zu überprüfen.

Ohne die Steuerelemente Ihrer Benutzeroberfläche zu kennen und ohne zu wissen, mit welchen Ereignissen Sie verbunden sind, ist es schwierig festzustellen, wo genau das Problem liegt.

3voto

David Punkte 427

Ich hatte ein ähnliches Problem und im Gegensatz zu @BartRead, konsequent. Für mich, einige CLI-Code funktionierte gut in einer einfachen Windows-Forms-App, aber wenn ich es in einem Larager-Plugin-Ökosystem (multithreaded) die Nachrichten benötigt Pumpen mit Application.Run oder Application.DoEvents. Wenn Sie Zugriff auf den Code haben, der gepumpt wird, ist es am besten, immer mehr Teile des Codes auszukommentieren (was bei mir funktioniert hat), während die Funktionalität erhalten bleibt. Es stellte sich heraus, dass ich einen Callback/Delegate nicht GC::Alloc'd hatte und während er angeheftet war und immer noch referenziert wurde, wurde er im Speicher verschoben oder direkt zur Abholung markiert.

Wenn Sie GC Alloc benutzen, räumen Sie hinter sich auf!

2voto

Apex ND Punkte 430

Ich hatte dieses Problem beim Ausführen einer gespeicherten Prozedur mit ADO. Dieser Fehler hatte zwei Ursachen:

  1. schlechte Verbindungszeichenfolge.
  2. Fehlanpassung des Parametertyps (Übergabe eines long für db-int32 oder long für nvarchar(10), was kürzer ist)

2voto

gReX Punkte 1479

Der Stacktrace sagt Ihnen nichts :-(. Können Sie Ihre Pakete aktualisieren, um zu sehen, ob die Ausnahme verschwunden ist? Ich habe System.AccessViolationException mit None-Threadsafe Com-Objects gesehen, wenn ich von einem Workerthread auf Properties zugreife. Also ja, ich kann mir vorstellen, dass die Ausnahme durch die Verwendung einer früheren nicht-threadsicheren Version von irgendeiner API verursacht wird.

Ich habe die Situation gemeistert, indem ich Folgendes hinzugefügt habe Attribute

[HandleProcessCorruptedStateExceptions]
[SecurityCritical]

zu der Methode, in der ich auf diese widersprüchlichen Eigenschaften des COM-Objekts zugreife. Außerdem musste ich die

<legacyCorruptedStateExceptionsPolicy enabled="true" />

Einstellung zu meiner app.config, und war dann in der Lage, diese Ausnahmen zu fangen, und klug behandeln.

Mehr Informationen Ausnahmen bei beschädigtem Zustand MS Docs Indem Sie Corrupted State Exceptions behandeln und den Prozess nicht beenden, verlassen Sie den Weg, auf dem "die CLR einige ziemlich starke Garantien für Programmkorrektheit und Speichersicherheit bietet".

Kredite an https://stackoverflow.com/a/4759831/1196586

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X