L’application tombe en panne avec «Erreur interne dans le runtime .NET»

Nous avons une application écrite contre .NET 4.0 qui, au cours du week-end, est tombée en panne, en mettant le message suivant dans le journal des événements:

Application: Infrastructure Framework PnrResortingeverService.exe: v4.0.30319
Description: le processus a été interrompu en raison d’une erreur interne dans le .NET Runtime à l’adresse IP 791F9AAA (79140000) avec le code de sortie 80131506.

Cela se trouve dans une boîte Windows Server 2003 R2 Standard Edition. Googler cette erreur n’a rien révélé de pertinent. Par exemple, cela ne se produit pas dans VS Studio, mais dans une boîte de production. lorsque le service a finalement été redémarré, il n’a plus rencontré de problèmes.

Comment procéder pour diagnostiquer un bogue dans le runtime .NET?

avec code de sortie 80131506

C’est un méchant, ExecutionEngineException. À partir de .NET 4.0, cette exception met immédiatement fin au programme. La cause générique est la corruption de l’état du tas récupéré. Ce qui est à son tour invariablement causé par du code non géré. L’emplacement exact dans le code auquel cette exception est générée n’est pas utile, la corruption se produisant généralement bien avant que le dommage ne soit détecté.

Trouver la cause exacte de cela va être difficile. Examinez tout code non géré que votre service pourrait utiliser. Suspecter des problèmes d’environnement s’il n’y a pas de candidat évident, les scanners malveillants se comportent mal. Si elle se répète très mal, alors suspectez des problèmes matériels comme des erreurs de mémoire vive.

Un bogue dans l’implémentation simultanée de Garbage Collection sur x64 .Net 4 peut provoquer ce problème, comme indiqué dans l’entrée suivante de la base de connaissances Microsoft:

ExecutionEngineException se produit lors du nettoyage de la mémoire

Vous devez d’abord faire une exploration approfondie de minidump pour vous assurer que le problème est survenu lors d’une collecte de ordures.

L’emplacement minidump se trouve généralement dans une entrée de rapport d’erreurs Windows dans le journal des événements à la suite de l’entrée en panne. Ensuite, amusez-vous avec WinDbg!

La documentation la plus récente sur l’utilisation de l’élément de configuration , pour désactiver la récupération de place en arrière-plan simultanée ou (dans .NET 4 et ultérieure), est disponible ici .

J’ai rencontré des “erreurs internes” dans le runtime .NET qui se sont avérées être dues à des bogues dans mon code; ne le pensez pas simplement parce qu’il s’agissait d’une “erreur interne” dans le runtime .NET qu’il n’ya pas de bogue dans votre code comme cause principale. Toujours toujours toujours blâmer votre propre code avant de blâmer quelqu’un d’autre.

J’espère que vous avez des informations de journalisation et d’exception / trace pour vous indiquer où commencer à chercher, ou que vous pouvez répéter l’état du système avant la panne.

Pour ceux qui arrivent de Google, j’ai finalement rencontré cette question SO , et cette réponse spécifique a résolu mon problème. J’ai contacté Microsoft pour le correctif via le chat en direct sur support.microsoft.com et ils m’ont envoyé un lien vers le correctif par courrier électronique.

Peut-être un bogue avec le code GC simultané http://support.microsoft.com/kb/2679415

Après des années de lutte contre ce problème dans un certain nombre d’applications, il semble que Microsoft l’ait finalement accepté en tant que bogue dans .NET 4 CLR, ce qui provoque ce problème. http://support.microsoft.com/kb/2640103 .

Je l’avais déjà “réparé” en forçant le ramasse-miettes à s’exécuter en mode serveur (gcServer enabled = “true” dans app.config) comme décrit dans l’article de Microsoft lié à Think Before Coding. Cela oblige essentiellement tous les threads de l’application à faire une pause pendant la collecte, éliminant ainsi la possibilité que d’autres threads accédant à la mémoire soient manipulés par le GC. Je suis heureux de constater que mes années de recherche en vain d’un “bug” dans mon code ou d’autres bibliothèques non gérées par des tiers n’ont été que vaines, car le bogue réside dans le code de Microsoft, pas le mien.

Dans mon cas, cette exception s’est produite lorsque l’espace disque était terminé et que .NET ne peut pas allouer de mémoire dans la mémoire virtuelle Windows.

Dans le journal des événements, j’ai vu cette erreur:

Application popup: Windows – Mémoire virtuelle minimale trop faible: votre système ne dispose plus de mémoire virtuelle. Windows augmente la taille de votre fichier de pagination de mémoire virtuelle. Pendant ce processus, les demandes de mémoire pour certaines applications peuvent être refusées.

Et erreur précédente:

Le disque C: est à la capacité ou presque. Vous devrez peut-être supprimer certains fichiers.

Framework Version: v4.0.30319 Description: le processus a été arrêté en raison d’une exception non gérée. Informations sur les exceptions: System.Reflection.TargetInvocationException

J’ai fait face à cette erreur, l’application fonctionnait correctement sur certains PC et sur certains PC donnant l’erreur ci-dessus. Je désinstalle le Framework 4.5 et réinstallez-le pour résoudre mon problème.

Acclamation.

Je ne suis pas sûr que cela puisse aider tout le monde, mais je pourrais contourner cela en courant

 devenv.exe /ResetSettings 

… dans le chemin {Visual_Studio_root}\Common7\Ide

J’ai eu les erreurs suivantes dans le journal des événements et VS se contentait de planter et de redémarrer tout le temps:

 Faulting application name: devenv.exe, version: 14.0.25123.0, time stamp: 0x56f22f32 Faulting module name: clr.dll, version: 4.7.2115.0, time stamp: 0x59af88f2 Exception code: 0xc0000005 Fault offset: 0x0015f90e Faulting process id: 0x3a7c Faulting application start time: 0x01d353463eaf0c36 Faulting application path: C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\IDE\devenv.exe Faulting module path: C:\Windows\Microsoft.NET\Framework\v4.0.30319\clr.dll Report Id: a232f984-6e80-4f61-9003-e18a035c8f93 Faulting package full name: Faulting package-relative application ID: 

Dans mon cas, le problème était une bibliothèque C ++ / CLI dans laquelle il y avait un appel à NtQuerySystemInformation ; pour une raison quelconque, parfois (et dans des circonstances mystérieuses ), quand il a été appelé, le tas CLR a été corrompu et l’application est tombée en panne.

J’ai résolu le problème en utilisant un “tas personnalisé” créé avec HeapCreate et en y allouant les tampons utilisés par cette fonction.

Dans mon cas, cette erreur s’est produite lors de la connexion à l’application SAP Business One 9.1. Dans les événements Windows, j’ai pu trouver un autre événement d’erreur en plus de celui signalé par l’OP:

 Nome dell'applicazione che ha generato l'errore: SAP Business One.exe, versione: 9.10.160.0, timestamp: 0x551ad316 Nome del modulo che ha generato l'errore: clr.dll, versione: 4.0.30319.34014, timestamp: 0x52e0b784 Codice eccezione: 0xc0000005 Offset errore 0x00029f55 ID processo che ha generato l'errore: 0x1d7c Ora di avvio dell'applicazione che ha generato l'errore: 0x01d0e6f4fa626e78 Percorso dell'applicazione che ha generato l'errore: C:\Program Files (x86)\SAP\SAP Business One\SAP Business One.exe Percorso del modulo che ha generato l'errore: C:\Windows\Microsoft.NET\Framework\v4.0.30319\clr.dll ID segnalazione: 3fd8e0e7-52e8-11e5-827f-74d435a9d02c Nome completo pacchetto che ha generato l'errore: ID applicazione relativo al pacchetto che ha generato l'errore: 

La machine exécute Windows 8.1, avec .NET Framework 4.0 installé et sans la version 4.5. Comme il semblait de l’Internet qu’il pourrait s’agir d’un bogue dans .NET 4, j’ai essayé d’ installer .NET Framework 4.5.2 et j’ai résolu le problème.

Cela peut être une exception survenant dans le finaliseur. Si vous faites le Pattern de ~ Class () {Dispose (false); } cochez ce que vous disposez en tant que ressource non gérée. Il suffit de mettre un essai.Catch là-bas et ça devrait aller.

Nous avons trouvé le problème car nous avons eu cette erreur mystérieuse sans journaux. Nous avons fait le schéma habituel d’utilisation d’un “void Dispose (bool disposing)”.

En examinant les réponses à cette question sur le finaliseur, nous avons trouvé un endroit où la disposition des ressources non gérées pourrait générer une exception.

Il se trouve que quelque part, nous n’avons pas disposé l’object correctement, donc le finaliseur a pris en charge le contenu des ressources non gérées.

Dans ce cas, nous utilisions l’API Kafka Rest pour nettoyer le client de Kafka. Semble que cela a fait une exception à un moment donné, alors que ce problème s’est produit.

Toutes les 5-10 minutes, mon pool d’applications restait bloqué avec ce code de sortie. Je ne veux pas gâcher votre confiance dans le Garbage Collector, mais la solution suivante a fonctionné pour moi.

J’ai ajouté un Job qui appelle GC.GetTotalMemory(true) toutes les minutes.

Je suppose que, pour une raison quelconque, le CPG n’inspecte pas assez souvent la mémoire pour le grand nombre d’objects jetables que j’utilise.