web-dev-qa-db-fra.com

Recherche de la cause de System.AccessViolationException

Notre application connaît l'étrange System.AccessViolationException fatale. Nous les voyons lorsque nous avons configuré l'événement AppDomain.CurrentDomain.UnhandledException pour consigner l'exception.

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

L'exception elle-même ne semble pas contenir plus d'informations que le message "Tentative de lecture ou d'écriture de la mémoire protégée. Ceci indique souvent qu'une autre mémoire est corrompue."

  • Quelles mesures pouvons-nous prendre maintenant pour trouver la cause du problème?
  • Existe-t-il un moyen de déterminer l'adresse illégale ou la valeur du pointeur à l'origine du crash?
  • Pouvons-nous savoir quel code de bibliothèque natif était à l'origine du problème?
  • Y a-t-il plus de débogage/traçage que nous pouvons activer?

MISE À JOUR

  • Cela peut-il être dû à une utilisation antérieure non sécurisée de l'API WinForms?
30
chillitom

Ce que vous rencontrez est l'équivalent exact de "Le programme a rencontré un problème et va maintenant se fermer", sauf qu'il est détecté par le runtime .NET, plutôt que par le système d'exploitation.

En regardant la trace de la pile, elle n'est pas déclenchée par votre code, ce qui me fait penser qu'elle provient d'un thread de travail généré par une bibliothèque que vous utilisez ou un contrôle personnalisé.

La seule façon de suivre quelque chose comme ça serait d'exécuter les bibliothèques natives sous un débogueur, qui devrait piéger la violation d'accès avant qu'elle ne se propage à la couche CLR. Cela peut être facile ou difficile.

Si le code natif est votre propre projet, la manière la plus simple de le configurer consiste à placer à la fois le projet .NET et le projet C++ dans la même solution et à vous assurer que le projet .NET fait référence au projet C++. Si vous publiez plus de détails sur votre environnement, je pourrai peut-être vous donner des conseils plus spécifiques.

6
Mike Caron

La trace de pile pointe vers des données incorrectes dans le paramètre MSG du messager de répartition natif. Avez-vous essayé de charger les symboles à partir de Microsoft et de vérifier les paramètres de cette trace de pile.

Sans connaître les commandes de votre interface utilisateur et quels que soient les événements auxquels vous vous êtes connecté, il sera difficile de déterminer quel est exactement le problème.

3
Steve Mitcham

J'ai eu un problème similaire et contrairement à @BartRead, de manière cohérente. Pour moi, certains codes CLI fonctionnaient bien dans une simple application Windows Forms, mais quand je l'ai mis dans un écosystème de plugins plus large (multithread), les messages devaient être pompés avec Application.Run ou Application.DoEvents. Si vous avez accès au code pompé, le meilleur pari (ce qui a fonctionné pour moi) était de commenter de plus en plus de morceaux du code tout en conservant la fonctionnalité. Il s'est avéré que je n'avais pas GC :: alloué un rappel/délégué et alors qu'il était épinglé et toujours référencé, il avait été déplacé en mémoire ou directement signalé pour la collecte.

si vous utilisez GC Alloc, assurez-vous de nettoyer après vous-même!

3
David

j'ai eu ce problème lors de l'exécution d'une procédure stockée à l'aide d'ADO. cette erreur a deux causes:

  1. chaîne de connexion incorrecte.
  2. type de paramètre erreur de correspondance (passage d'un long pour db-int32 ou long à nvarchar (10) qui est plus court)
2
Apex ND

Le stacktrace ne vous dit rien : . Pouvez-vous mettre à jour vos packages pour voir si l'exception a disparu? J'ai vu System.AccessViolationException avec None-Threadsafe Com-Objects lors de l'accès aux propriétés à partir d'un thread de travail. Alors oui, je peux imaginer l'exception est due à l'utilisation d'une version antérieure non threadsafe de certaines API.

J'ai géré la situation en ajoutant --- (Attributs

[HandleProcessCorruptedStateExceptions]
[SecurityCritical]

à la méthode, dans laquelle j'accède à ces propriétés en conflit à partir de l'objet COM. J'ai aussi dû ajouter le

<legacyCorruptedStateExceptionsPolicy enabled="true" />

Configuration de mon app.config, et a été en mesure de détecter ces exceptions et de les gérer à bon escient.

Plus d'informations Exceptions d'état corrompu MS Docs En gérant les exceptions d'état corrompu et ne fermez pas le processus, vous quittez la voie, où "CLR offre des garanties assez solides sur la correction du programme et la sécurité de la mémoire".

Crédits à https://stackoverflow.com/a/4759831/1196586

0
gReX