kb2679415 und ExecutionEngineException occurs during Garbage Collection

Beantwortet kb2679415 und ExecutionEngineException occurs during Garbage Collection

  • Mittwoch, 15. August 2012 15:38
     
     

    Es wird beobachtet, dass eine Applikation in unregelmäsigen Abständen von mehreren Tagen auf einer x64 Hardware "crashed".

    Diese Applikation lassete das System dauerhaft mit ca. 70% aus.

    Genauer, es gibt einen crash in der .NET Runtime:
    "Description: The process was terminated due to an internal error in the .NET Runtime at IP 000007FEF2EB99FC (000007FEF2DA0000) with exit code 80131506."

    Über eine Suche mit dem exit code = 80131506 (bedeutet nach eigener Recherche = ExecutionEngineException) gelangt man auf

    http://msdn.microsoft.com/en-us/library/system.executionengineexception(v=vs.90).aspx
    http://support.microsoft.com/kb/2679415
    und den kb2679415 http://support.microsoft.com/kb/2679415

    Wie kann man herausfinden ob dieser KB2679415 bei den beobachteten "crashes" vorliegt oder nicht ?

    Hier noch ein paar Details zum Crash aus dem EventView:

    ------------------------------------------------------------------------------------------------------
    Level Date and Time Source Event ID Task Category
    Error 09.08.2012 11:44:12 Application Error 1000 (100) "Faulting application name: App.exe, version: 1.0.0.223, time stamp: 0x5021ec3b
    Faulting module name: clr.dll, version: 4.0.30319.544, time stamp: 0x4ee99e7c
    Exception code: 0xc0000005
    Fault offset: 0x00000000001199fc
    Faulting process id: 0x22c8
    Faulting application start time: 0x01cd75747a129bbc
    Faulting application path: D:\App.exe
    Faulting module path: C:\Windows\Microsoft.NET\Framework64\v4.0.30319\clr.dll
    Report Id: c59012ee-e206-11e1-8221-e4115be5ef37"
    ------------------------------------------------------------------------------------------------------
    Error 09.08.2012 11:44:09 .NET Runtime 1023 None Application: App.exe
    Framework Version: v4.0.30319
    Description: The process was terminated due to an internal error in the .NET Runtime at IP 000007FEF2EB99FC (000007FEF2DA0000) with exit code 80131506.
    ------------------------------------------------------------------------------------------------------

Alle Antworten

  • Mittwoch, 15. August 2012 16:46
    Beantworter
     
     Vorgeschlagene Antwort

    Hallo Horst,

    um es genauer zu bestimmen müsste man den Dump anschauen.

    Der KB 2679415 ist (wie leider häufiger heutzutage) nicht besonders aussagefähig.
    Es gibt einen weiteren Artikel:
    FIX: "Faulting module name: clr.dll" error message when you run a Microsoft .NET Framework 4-based application
    der einen Hotfix bezüglich des GC enthält. Inwieweit er nun in MS12-035  (wäre : 4.0.30319.544) eingeflossen ist,
    lässt sich durch den engen Datumsrahmen schwer beantworten.

    Am aktuellsten dürfte derzeit sein[1]: Hotfix Rollup 2714396 is available for the .NET Framework 4

    Summa Summarum: Eine Klärung könnte nur durch den Microsoft Support erfolgen.

    Gruß Elmar

    [1] lt. http://www.mskbfiles.com/mscorlib.dll.php

  • Mittwoch, 15. August 2012 17:14
     
     Beantwortet Enthält Code

    Hallo,

    Wie kann man herausfinden ob dieser KB2679415 bei den beobachteten "crashes" vorliegt oder nicht ?

    Zunächst könnte man in der Anwendungskonfigurationsdatei die gleichzeitige (concurrent) Garbage Collection deaktivieren:

    <configuration>
       <runtime>
           <gcConcurrent enabled="false"/>
       </runtime>
    </configuration>

    Bei dieser Art von GC, kommt es schon mal zu Problemen auf x64-Systemen mit reichlich Speicher und Multikernprozessoren, wie ich in diesem englischsprachigen Thread erfahren durfte. Wie Du dort sehen kannst, haben wir über unmanaged Debugging und SOS versucht, dem Problem auf den Grund zu gehen. Es stellte sich heraus, dass das Allokationsmuster (zu viele Allokationen in zu kurzer Zeit bei aktivierter konkurrenter GC) zum Fehler führte. Wenn die Deaktivierung gleichzeitiger GC nicht zum Erfolg führt, handelt es sich nicht um den in KB2679415 genannten Fall.

    Gruß
    Marcel

  • Freitag, 17. August 2012 10:04
     
     

    Hallo Elmar,
    Danke für deine hilfreiche Antworten.
    Die aktuelsten Hotfixe zu installieren kann "nie" schaden.
    Gerne würde auch den dump anschauen.
    Welchen dump wäre es und wie schaltet man diesen ein.
    Ich denke es handelt sich um einen dump von der clr?
    Gruß

    Horst

  • Freitag, 17. August 2012 10:36
    Besitzer
     
     

    Hallo Horst SIEMENS,

    Eine Liste der Versionen der CLR 4.0 kannst Du im folgenden Artikel finden: Version history of the CLR 4.0

    Habe noch folgendes gefunden: https://connect.microsoft.com/VisualStudio/feedback/details/720374/faulting-module-name-clr-dll-error-message-when-you-run-a-microsoft-net-framework-4-based-application („The internal error is pretty general and can be caused by multiple factors. In order to efficiently investigate your issue I would need you to provide us dumps of the crashing process. Please contact me personally at Mihai dot Stoicescu at Microsoft dot com and I can give you more details on how to collect and transfer crash dumps to us.)

    Was die Dumps angeht lies folgenden Artikel: Automatically Capturing a Dump When a Process Crashes

    Grüße,

    Robert


    Robert Breitenhofer, MICROSOFT  Twitter Facebook
    Bitte haben Sie Verständnis dafür, dass im Rahmen dieses Forums, welches auf dem Community-Prinzip „Entwickler helfen Entwickler“ beruht, kein technischer Support geleistet werden kann oder sonst welche garantierten Maßnahmen seitens Microsoft zugesichert werden können.

  • Montag, 20. August 2012 10:03
     
     

    Hallo Robert,

    danke für die Hinweise. Für Tests stehen mir zwei Testserver zur Verfügung.
    Verwendet wird dabei seit Freitag die neuste clr (569).

    Ein Server, configuriert mit
     <runtime>
          
    <gcConcurrent enabled="true"/>
      
    </runtime>
    zeigt schon seinen ersten crash -->
    Description: The process was terminated due to an internal error in the .NET Runtime at IP 000007FEF32A094C (000007FEF3090000) with exit code 80131506.
    Der andere Server, configuriert mit
     <runtime>
          
    <gcConcurrent enabled="false"/>
      
    </runtime>
    zeigte noch keinen crash.
    Auf beiden Servern is das JIT-Debugging aktiviert, wie in deinem Link beschrieben.
    Daher habe ich nun ein dump file mit ca. 1,3 GB ... :-), aus dem obrigen Crash erhalten.

    Die spannende Frage was und wie kann man aus diesem dump file herraus lesen.
    Gibt es einen Hinweise darin in Richtung --> kb2679415
    Oder in eine andere Richtung ?

    Grüße,

    Horst

  • Montag, 20. August 2012 10:50
    Besitzer
     
     
    Die spannende Frage was und wie kann man aus diesem dump file herraus lesen.
    Gibt es einen Hinweise darin in Richtung --> Oder in eine andere Richtung ?

    Hallo Horst SIEMENS,

    Versuch Dich mal in Verbindung mit Mihai Stoicescu (CLR Team von Microsoft) setzten. So wie er hier sagt: („The internal error is pretty general and can be caused by multiple factors. In order to efficiently investigate your issue I would need you to provide us dumps of the crashing process. Please contact me personally at Mihai dot Stoicescu at Microsoft dot com and I can give you more details on how to collect and transfer crash dumps to us.“)

    Grüße,

    Robert


    Robert Breitenhofer, MICROSOFT  Twitter Facebook
    Bitte haben Sie Verständnis dafür, dass im Rahmen dieses Forums, welches auf dem Community-Prinzip „Entwickler helfen Entwickler“ beruht, kein technischer Support geleistet werden kann oder sonst welche garantierten Maßnahmen seitens Microsoft zugesichert werden können.

  • Dienstag, 21. August 2012 08:33
     
     

    Hallo Robert,
    ich habe die Hoffnung, dass man auch hier auf dem Forum Unterstützung / Tips bekommt,
    zwecks Auswertung eines "Crash Dump Files" einer .Net Applikation mit: "The process was terminated due to an internal error in the .NET Runtime".

    Mit Mihai Stoicescu habe ich versucht in Verbindung zu kommen,
    leider noch ohne Rückantwort von Mihiai,
    bevor ich meine letzte Antwort hier auf diesem Thread schrieb.

    Sorry dass ich dies nicht vermerkt habe.

                Grüße, Horst

  • Dienstag, 21. August 2012 09:37
    Beantworter
     
     

    Hallo Horst,

    wenn man sich mit Low-Level Debugging noch nicht beschäftigt hat,
    ist so ein Fall nicht unbedingt der beste Einstieg.
    Sinnvoller könnte sein, einen Support Case aufzumachen und die Dumps von Microsoft auswerten zu lassen.

    Für Eigenversuche lies Dir mal durch:
    Intro to WinDBG for .NET Developers

    Tips for successful .NET Debugging with WinDBG

    Collecting crash dumps

    Gruß Elmar

  • Dienstag, 21. August 2012 10:00
     
     

    Hallo Horst,

    Ich gehe davon aus, dass eure Anwendung in einer engen Bearbeitungsschleife viele Allokationen macht und Referenzen auf die erstellten Objekte zu lange am Leben hält (gcroot), z.B. über eine List<T> oder über Finalizer (korrigiere mich bitte, wenn ich mit meinen Annahmen falsch liege).

    Wenn der GC nun konkurrent arbeitet, wegen der engen Bearbeitungsschleife jedoch nicht zum Zuge kommt, werden die erstellten <T>-Instanzen sehr schnell zu älteren Generationen promotet, was ihre Einsammlungs-Wahrscheinlichkeit noch weiter verringert. Da Speicher auf x64-Systemen kein Problem ist, könnte es bei diesem Allokationsmuster dazu kommen, dass CLR-Auflistungen, Strukturen oder Verarbeitungs-Limits an ihre Grenzen kommen.

    Nichts von alledem könnt ihr beheben. Ihr könnt lediglich dafür sorgen, dass nicht gebrauchte Referenzen so schnell wie möglich freigegeben werden und dass dass der GC regelmäßig eine Verarbeitungszeitspanne bekommt, um die "Leichen" zeitnah zu entfernen. Manchmal ist es hilfreich die Schleife über Thread.Sleep für kurze Zeit anzuhalten, aber das Wie muss man von Fall zu Fall entscheiden, je nachdem, was eure Anwendung so macht. Ohne genaueres zu wissen, stochert man im Dunkeln. Es könnte sich erweisen, dass eine konkurrente GC überhaupt nicht sinnvoll ist, dass man mit GC-Benachrichtigungen arbeiten muss usw.

    Ich glaube kaum, dass ihr Interesse am Debuggen des Kernels oder der CLR habt. Das könnte eher für das CLR-Team interessant sein. Für die Post-Mortem-Isolierung der Fehlerquelle solltet ihr deshalb ein MINIDUMP machen. Ein Minidump ist viel kleiner, erlaubt euch aber dennoch die Fehlerquelle mittels WinDbg und SOS zu isolieren indem ihr den Ausführungspfad analysiert, der zur Ausnahme führte.

    Und falls Mihai Stoicescu nicht antwortet (sie haben wohl alle viel zu tun zur Zeit), würde ich dich bitten, eine kleine Anwendung rauszuisolieren, die das Problem reproduziert und sie auf SkyDrive zu posten. Ich werde mir beides ansehen. Sollte ich nichts finden, werde ich mich bemühen, jemanden vom CLR-Team zu bekommen, der ein Auge drauf wirft. Eine kleine Anwendung und ein Minidump sollten für die Diagnose ausreichend sein.

    Gruß
    Marcel

  • Dienstag, 21. August 2012 10:05
    Besitzer
     
     

    Hallo Horst SIEMENS,

    Melde Dich bitte wenn Mihai keine Rückantwort schreibt. Es kann sein weil er in USA ist und eine andere Zeit hat (PST – Pacific Standard Time).

    Ich kann Dir noch empfehlen folgenden Diskussionsfaden durchzugehen: Random AppCrashes in clr.dll with .NET 4.0

    Die Dump Datei kannst Du auf SkyDrive hochladen und den Link zur Datei kannst Du posten überall wo Du im brauchst…oder mit der SkyDrive App (https://apps.live.com/skydrive/app/9a65e47d-606a-4816-a246-90f54bf7a3ea)

    Ich schaue auch noch auf diesem Thread weil ich sehen möchte ob das nicht ein Bug sein kann in der CLR von .NET 4.0.

    Genau wie Elmar sagt: „the next thing would be to collect full dumps and open a paid support case with us. If this happens to be a bug you will will get a complete refund for the support case of course. Please visit this link to see the various paid support options that are available to better meet your needs:  http://support.microsoft.com/default.aspx?id=fh;en-us;offerprophone.“

    Auch noch für den Einstieg in der „Debugging Welt“ J : How to analyze dumps with windbg 101

    Grüße,

    Robert


    Robert Breitenhofer, MICROSOFT  Twitter Facebook
    Bitte haben Sie Verständnis dafür, dass im Rahmen dieses Forums, welches auf dem Community-Prinzip „Entwickler helfen Entwickler“ beruht, kein technischer Support geleistet werden kann oder sonst welche garantierten Maßnahmen seitens Microsoft zugesichert werden können.

  • Donnerstag, 23. August 2012 08:02
     
     

    Hallo Marcel,

    deine Vermutungen sind richtig unsere "App" bzw. Service ist Speicher intensiv. Es werden Daten von Netzwerkdevices angefordert und auf Festplatte geschrieben. Bei z.B. 64 Netzwerkdevices kommen da 270MBit/sec zusammen. Intern werden z.B. IList<>, ICollection<>, EventHandler<> .. intensive benuzt. Auch das "empfohlene" Dispoe Pattern =>"is used only for objects that access unmanaged resources. ", siehe http://msdn.microsoft.com/en-us/library/fs2xkftw(v=vs.100).aspx, wurde bei entsprechennden Objekten umgesetzt.
    Einen ersten Kontakt zu Mihai Stoicescu ist zu Stande gekommen.
    Welche Antworten aus einer Dump-Analyze sind aus deiner Erfahrung zu erreichen/ zu erzielen ?

    Grüße

    Horst

    P.S. Danke für deine obrige detalierte Antwort !

  • Freitag, 24. August 2012 07:26
     
     

    Hallo Horst,

    Schwer zu sagen ohne Code und Dump. Ich würde vermutlich im Wesentlichen die Arbeit des GC bis zum Zeitpunkt der Ausnahme nachvollziehen wollen: Wie sieht der GC-Heap aus, wie sind die Objekte auf Generationen verteilt, wie sieht's mit den Threads, mit der Finalisierung aus.

    Wenn ich euer Setting richtig verstehe, verwendet eure Anwendung eine Hintergrund-GC (konkurrent weil Mehrkern-System, .NET 4.0, Windows-Dienst). Auf einem 64bit-System sollte (virtueller) Speicher weniger ein Problem sein, der Speicherdruck kommt hier normalerweise - wenn überhaupt - von der verwalteten Seite. Die GC wird normalerweise angestoßen sobald der verfügbare Speicherplatz auf dem verwalteten Heap für die Generation 0 nicht mehr ausreicht. Höhere Generationen werden nur eingesammelt, wenn ihre maximale Größe erreicht ist, auf 64-bit Systemen kann das sehr lange dauern.

    Wenn ihr das Dispose-Pattern richtig implementiert habt, werden die nativen Ressourcen über Dispose(true) freigegeben und die Objektreferenzen verrotten nie auf der Finalisierungs- bzw. f-reachable Queue weil GC.SuppressFinalize in der Patternimplementierung schon vorher aufgerufen wurde. Damit solltet ihr auch kein Problem mit nativen Ressourcen haben (es sei denn ihr verwendet mehr als 16 Millionen Handles, wovon ich nicht ausgehe).

    Konkurrente GC ist vor allem für interaktive Anwendungen gedacht, wo der Benutzer eine flüssige, latenzfreie User-Experience erwartet. In einem Dienst der keine Daten für die UI liefert macht konkurrente GC weniger Sinn. Sie ist nur da um ältere Generationen auf einem separaten Thread einzusammeln während die .NET-Anwendung weiterhin neue Allokationen machen kann. Für euer speicher- und CPU-intensives Szenario ist eine konkurrente GC vermutlich aber der falsche Ansatz: Ob die Generation 2 nun auf einem separaten Thread eingesammelt wird oder nicht, ist nicht von Belang wennn alle Prozessorkerne voll ausgelastet sind (weil die Verarbeitung der Nachrichten von euren Devices wahrscheinlich so gut wie keine Verarbeitungspausen mit sich bringt, wo der GC einkicken könnte).

    Der GC könnte noch bei der Rückkehr aus dem Aufruf nativer Methoden und beim Schließen von AppDomains einkicken, aber darüber war bisher nie die Rede, so dass ich vermuten muss, dass dies hier nicht der Fall ist.

    Die einzigen Verarbeitungspausen, die ich in euerer Anwendung vermute, sind die beim Schreiben auf die Festplatte. Wenn die Datenmenge klein ist und ihr nur einige wenige Bytes auf SSD-Festplatten o.ä. schreibt, oder wenn das Schreiben asynchron vorgenommen wird, hat die GC bei diesem Allokations-Tempo keine Chance sich einzuklinken.

    Der GC versucht zum einen das Working-Set einer Anwendung klein zu halten (markieren, einsammeln, kompaktieren), zum anderen die Zeit für die GC zu minimieren. Aber dazu braucht der GC natürlich selber Rechenzeit (er muss mit dem Jitter, dem EE Stack-Walker, der Handle-Tabelle und der Finalisierungsqueue kommunizieren, eigenen Recherchen anstellen und dann natürlich noch seinen Reinigungs-Job erledigen).

    So, wie mir meine Zauberkugel die Situation im Augenblick schildert, sieht es eher nach einem architekturellen Problem aus, das entweder über die Deaktivierung des konkurrenten Hintergrund-GCs oder über eine Producer-Consumer-Queue gelöst werden könnte (evtl. Multiproducer-Single-Consumer-Queue), die dem GC die nötige Zeit verschafft, seine adaptiven Heuristiken in Ordnung zu bringen.

    Bitte halte uns auf dem Laufenden bezüglich der Analyse von Mihai Stoicescu.

    Gruß
    Marcel

  • Montag, 27. August 2012 12:08
     
     

    Hallo Marcel,

    ich konnte Mihai Stoicescu zwei Crash Dump Files zur Verfügung stellen.
    Ich bin sehr froh und dankbar, dass er eine Analyse damit durchgeführt hat,
    seine Rückmeldung war:
    "It seem that the issue you see here is a known issue fixed in CLR 4.5".
    Mit der Empfehlung den workaround:
    <gcConcurrent enabled="false"zu benutzen.
    Natürlich wünscht man sich als Entwickler mehr technische Rückmeldung über
    die Analyse selbst. Wie wurde analysiert (z.B. mit WinDbg ? welche commands ?), was hat man dabei genauer gesehen (z.B. Korrupter CLR Heap/Stack ? oder .. ) etc.

    Wir überlegen zur Zeit, wie wir mit dieser Erkenntnis umgehen.
    Da unsere Softwarekomponente nur eine "Sub-Komponente", in einen großeren Softwaregebilde darstellt, dürfte es schwer fallen, das ganze Softwaregebilde auf 4.5 um zustellen.

    Den workaround <gcConcurrent enabled="false"/>
    zu benutzen scheint auf den ersten Blick einfacher. Aus deiner Erfahrung herraus welche negative Einflüsse sind hier zu erwarten z.B. in Richtung Performance ?
    Und was passiert bei dieser konfiguration bei einem "GC Zyklus", wird dann die Applikation "ausgebremst" bzw. kurz "verdrängt" ?

    Viele Grüße,

    Horst

  • Montag, 27. August 2012 17:48
    Beantworter
     
     

    Hallo Horst,

    beim konkurrenten GC wird ein eigener Thread verwendet, wodurch die Anwendung häufig besser reagieren kann, der GC selbst ist insgesamt langsamer, da komplexer (und fehleranfälliger wie gesehen). Beim Standard-GC werden die Anwendungsthreads angehalten, wodurch die Anwendung kurzzeitig als "eingefroren" erscheinen kann - was aber eher bei Benutzeroberflächen auffällt. Eine relativ gute Beschreibung:
    http://stackoverflow.com/questions/2583644/difference-between-background-and-concurrent-garbage-collection

    Zur weiteren Lektüre empfehle ich Dir: Garbage Collection und Leistung (und wenn möglich den gesamten Themenblock)
    Über die Speicherleistungsindikatoren kannst Du, ohne in die Tiefen einzusteigen, herausfinden, welchen Einfluss der GC auf die Anwendung hat.

    Was WinDbg angeht: Wie oben schon geschrieben, braucht es einige Zeit sich damit anzufreunden und keine Scheu vor Hexadezimalwerten sowie etwas Kenntnisse von Assembler etc. sind dabei hilfreich. Und Real Debugging TM (dort kd => Kernel Debugger) muss man wie Raymond Chen schon lieben ;-)
    Leute, die bei Microsoft in der Entwicklung arbeiten, haben den nicht zu überbietenden Vorteil, dass sie die Quellen im Zugriff haben, und so sollte man deren Dienste annehmen, wenn sie sie anbieten!

    Von der Seite eines .NET Anwendungsprogrammierers ist es eher sinnvoll, sich mit dem CLR Profiler auseinander zu setzen. Sehr häufig sind wenige Stellen der Anwendung entscheidend für die Performance (bzw. das Fehlen derselben).

    Und solltest Du damit einige Dinge finden, die Du Dir nicht erklären kannst bzw. wo Du Optimierungsmöglichkeiten siehst, so wird sich hier jemand finden der sich gerne damit beschäftigt...

    Gruß Elmar


  • Montag, 3. September 2012 07:59
     
     Beantwortet

    Hallo,

    das Testsytem läuft mit der Einstellung
     <gcConcurrent enabled="false"/>
    seit zwei Wochen ohne CLR Crash. Die Dump File Analyse zeigt auch in die selbe Richtung. Vielen Dank an alle für die Unterstützung und den sehr
    interessanten Links.

    Grüße

    Horst

    • Als Antwort markiert Horst SIEMENS Montag, 3. September 2012 08:00
    •  
  • Montag, 3. September 2012 08:35
    Besitzer
     
     

    das Testsytem läuft mit der Einstellung <gcConcurrent enabled="false"/> seit zwei Wochen ohne CLR Crash.

    Hallo Horst SIEMENS,

    Freut mich dass es jetzt bei Dir läuft.

    Grüße und Erfolg,

    Robert


    Robert Breitenhofer, MICROSOFT   Bitte haben Sie Verständnis dafür, dass im Rahmen dieses Forums, welches auf dem Community-Prinzip Entwickler helfen Entwickler“ beruht, kein technischer Support geleistet werden kann oder sonst welche garantierten Maßnahmen seitens Microsoft zugesichert werden können.