Fehler in ATLTHUNK.DLL führt auf Windows 10 (64bit) unter bestimmten Umständen zu zufälligen Crashes von Anwendungen

Wer es schnell mag, kann gleich den Beitrag und technische Details auf Stack Overflow lesen:
http://stackoverflow.com/questions/41741448/random-crashes-on-windows-10-64bit-with-atl-subclassing

Hier möchte ich etwas ausführlicher, die Story dazu erzählen, eine Story aus dem ganz „normalen“ Leben eines Programmierers 😉

Letztes Jahr stellen wir in der Firma produktiv von VC-2013 auf VC-2015 um. Wir haben eine relativ große Anwendung, die im Kern, MFC und ATL verwendet. Unsere Anwendung zeigt Informationen in vielen Tabs und Dialogen an. Mehr als 256 Fenster sind da keine Ausnahme und eher die Regel als eine Seltenheit.

Unsere Anwendung erzeugt bei Crashes automatisch volle Dumps auch bei Kunden. Für unsere Qualitätssicherung ein Muss und ein Segen.
Bereits in der Alpha und Beta Phase hatten wir auf manchen Rechnern ein eigentümliches Phänomen. Unser Programm startete und erzeugte Fenster und auf einmal kam es zu einem Absturz bei oft ganz einfachen Windows API Funktionen, die ein Fenster verwendeten und die alle ausnahmslos letzten Endes dazu führten, dass eine Nachricht an ein Fenster gesendet wird. Der Stack war nichtssagend und schien zerstört. Die Dumps für die einzelnen User waren aber fast immer glich.
Das Problem trat in Release und Debug Builds auf.

Der Horror für jeden Programmierer. Nicht nachzuvollziehende Crashes auf manchen Rechnern. Heapfehler? Wilder Zeiger? Buffer-Overrun? Nichts was man gebrauchen kann… aber kein Analysetool was wir verwendeten schlug Alarm…

Nach Sammlung von mehreren Dumps waren die Crashes immer wieder an ähnlichen Stellen und fast immer alle sofort nach Programmstart. Betroffen in der Regel alles Windows 10 64bit Maschinen auf dem aktuellen Softwarestand, meistens hatten diese Maschinen 8GB und zum Teil weitaus mehr Speichern und es waren ausnahmslos schnelle Intel i7 verschiedener Generationen. Und in virtuellen Maschinen konnte ich das bisher nicht nachvollziehen.

Interessant, war, dass ich diese Crashes auch auf meiner Entwicklungsmaschine hatte. Manchmal…
Nach einigen Tests konnte ich sagen. Entweder tritt der Fehler auf und solange der Rechner gestartet ist kann man es manchmal nachvollziehen, oder der Fehler tritt eben nicht auf und man hat Ruhe vor ihm. Dann hatte ich mir 3 Tage hintereinander – ohne Rechnerneustart – mit Debug-Session auf Debug-Session eine Spur erarbeitet. Es war immer das 257 Fenster, dass gesubclassed wurde (mit ATL Thunking) oder erzeugt wurde (ATL Fenster), dass zum Crash führte.
Insofern war es bei jedem User auch immer ein ähnlicher Dump, weil der Fensteraufbau ja bei jedem User individuell war.

Am Ende des dritten Tages hatte ich einen Testcode, der den Fehler in der aktuellen Windows Session meines Rechners und meinen Programm zu 100% nachvollziehbar machte. Ich verschob den Testcode immer weiter in einem Programm nach vorne, bis ich bei InitInstance ankam.
Ups. Es liegt nicht an meiner Software.
Dann isolierte ich den Testcode in eine eigenes Programm und konnte den Bug in einem minimalen Sample nachstellen.

Zeit für einen Support-Case bei Microsoft und eine Anfrage auf stackoverflow.com (das war am 19.01.2017).

Mit dem Case hatte ich natürlich auch einen Workaround. Ich musste nur einfach die atlthunk.dll nicht benutzen und auch das ging mit einer einfachen Änderung in der atlstdthunk.h. (Auskommentieren des defines USE_ATL_THUNK2).

Die Kommunikation mit Microsoft gestaltete sich nicht einfach. Aber ich hatte zumindest einen konstruktiven MS Mitarbeiter aus Indien erwischt. Dumps konnte ich Microsoft liefern, auch den Crash direkt in einer Session zeigen. Code hatten sie auch, aber der Bug war bisher nicht bei Ihnen nachvollziehbar. Das trieb mich fast in die Verzweiflung. Natürlich musste alles andere ausgeschlossen werden.. Virenscanner, andere Software… etc…
Dennoch kein Repro auf eine Microsoft Maschine. Allerdings weiß ich nicht wie „intensiv“ da gesucht wurde.

Dann endlich ein Lichtblick auf stackoverflow.com. Eugene konnte den Bug nachvollziehen. Endlich.
Und nachdem ich wusste, dass es mit der bevorzugten Ladeadresse zu tun hatte, konnte ich auch meinen Code erweitern und mit 100% Wahrscheinlichkeit den Crash erzeugen.
Wenn also an der bisher bevorzugten Ladeadresse der atlthunk.dll kein Speicher zur Verfügung liegt und sofort wieder eine Relocation notwendig wird, dann kracht es. Lustig, da wir ja durch ASLR sowieso keine festen Ladeadressen haben, aber es gibt innerhalb einer Windows Session dennoch eine „bevorzugte Ladeadresse“.

Jetzt bin ich gespannt auf Microsoft…
Denn defakto kann jede Software die mit dem VC-2015 und VC-2017 Compiler und der ATL kompiliert wurde von diesem Problem betroffen sein.

PS: Man entschuldige mir Ungenauigkeiten oder auch falsche Begrifflichkeiten…
Bis heute habe ich den Fehler immer noch nicht ganz verstanden und ganz sooo tief lebe ich im Kernel von Windows doch nicht. 😀

PPS: Ich werden den Artikel auf stackoverflow.com aktuell halten.

Nachtrag 01.03.2017:

  • Microsoft hat bestätigt, dass es sich um um einen Bug handelt.
  • Der Bug soll in der nächsten Windows 10 Version (RS2) gefixed sein.
  • Nachteil: Ich werde wohl mit der Änderung der ATL leben müssen, denn auch andere Windows Versionen sind von diesem Fehler betroffen.

Schwerwiegender Fehler Ihr Menü „Start“ funktioniert nicht. Wir beheben das Problem, sobald sie sich erneut anmelden.

Ich hatte relativ schnell nach Veröffentlichung von Windows 10 auch meinen Produktivrechner umgestellt. Hier war sowieso ein Hardwaretausch nötig und da ich Windows 10 schon auf meinem Laptop hatte und es mir gut gefiel, habe ich auch gleich neu installiert. Und ich habe es eigentlich auch nicht bereut.

Die Freude am neuen System währte exakt 2 Wochen und ich bekam nach Neustart des Rechners wegen eines Updates den folgenden Fehler. 🙁

Schwerwiegender Fehler Ihr Menü „Start“ funktioniert nicht. Wir beheben das Problem, sobald sie sich erneut anmelden.

                                                                                                                      Jetzt Abmelden 

Schwerwiegender-Fehler

Ich habe natürlich das Update deinstalliert aber das nützte mir nichts. Das Problem lag auch nicht am Rechner, sondern einzig an meinem Benutzerprofil, denn alle anderen Profile auf dem Rechner zeigten keine Probleme. Also war vermutlich auch das Update nicht die Ursache. 😕
Nachdem ich einiges ausprobiert hatte was auch so im Internet dazu stand, habe ich einfach den Microsoft Support angerufen (wir hatten sowieso noch 5 unbenutzte Cases).  Leider hat der Support auch zu keiner Lösung gefunden. Damals habe ich also einige Daten aus dem Profil gesichert und mein Benutzerprofil auf dem Rechner entfernt und neu angelegt.

Das ganze ging jetzt Monate gut (auch nach dem Update 1510) und ich dachte: OK Problem scheint behoben.
Pustekuchen: Diese Woche war es wieder so weit. Der gleiche Fehler. Wieder Suche im Internet was im letzten Monat zu diesem Fehler heraus kam. Und siehe da… ein neuer Tipp: Dropbox ist die Ursache?

Kein Hexenwerk. Also Dropbox deinstalliert Rechner neu gestartet und siehe da. Der Fehler ist weg. Allerdings auch der Root Eintrag im Explorer für OneDrive.
Da ich die Dropbox aber täglich benötige habe ich die Software gleiche wieder installiert. Überraschung: Kein Fehler. 🙂
Auch der Root Eintrag im Explorer für DropBox war nun weg. Aber die Ordner funktionieren und sind erreichbar. Damit kann ich leben. (Evtl. finde ich wenn ich Zeit habe auch hierfür noch eine Lösung).
Fazit in meinem Fall: In diesem Szenario von Dropbox in Verbindung mit Windows 10 scheint was nicht zu passen, was bei mir (vermutlich bereits zweimal) einen Fehler auslöste.

Vielleicht hilft es anderen. Denn ein Profil neu aufzubauen mit allen Einstellungen macht nicht unbedingt viel Spaß, selbst wenn man einen Registry Auszug und eine Kopie alle Daten hat.

Nachtrag 11.01.2016:
Gestern hatten wir auf einem Rechner unserer Kirchengemeinde ein ähnliches Problem mit der folgenden Meldung:

Schwerwiegender Fehler. Das Menü Start und Cortana funktioniert nicht. Wir bemühen uns, das Problem bis zur nächsten Anmeldung zu beheben.

Jetzt Abmelden

In diesem Falle half ein anderer Tipp, der mittlerweile auch im Netz schon mehrfach geteilt wurde.

  1. STRG + ALT + Entf Tasten drücken.
  2. Jetzt die Umschalt-Taste drücken und mit der Maus auf das Power-Symbol klicken und Herunterfahren auswählen.
  3. Die Umschalt-Taste gedrückt halten bis Windows 10 komplett heruntergefahren wurde.
  4. Den PC erneut und hoffen, dass der Fehler diesmal behoben ist.

Bei diesem Problem kann ich nicht sagen, ob es am Profil liegt. Der Rechner hatte nur eines und dieses war mit einem Microsoft-Konto verbunden.

„Elevated“ Programme unter Vista / Windows 7 / Windows 8 / Windows 10 haben auf einmal keine gemappten Laufwerke mehr

Ist man Administrator unter Vista, Windows 7, Windows 8 oder Windows 10 und UAC ist aktiviert, dann existieren technisch zwei Sicherheits -Tokens. Ein Token mit den vollen Administrativen Rechten und ein reduziertes gefiltertes Token, ohne Admin-Rechte.

Wenn man sich anmeldet und Netzwerklaufwerke (Freigaben/Shares) zugeordnet werden, dann erfolgen diese Laufwerksmappings in dem Token mit den reduzierten Rechten.

Startet man nun eine Session mit angehobenen, vollen administrativen Rechten, dann sind die vorher zugeordneten Netzwerklaufwerke in dieser Session nicht sichtbar.
Ein etwas ungewöhnliches aber durchaus logisches Verhalten.
Das Logon Skript läuft eben nicht in dem selben Sicherheitskontext, wie Prozesse, die man mit vollen angehobenen Rechten startet. Defakto sind es wirklich zwei verschiedene Logon’s mit zwei verschiedenen Logon-ID’s.

Mit einem einfachen setzen eines Registry Keys kann man jedoch erreichen, dass auch die angehobenen Admin-Sessions die gleichen Laufwerkmappings erhalten:

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System
EnableLinkedConnections = 1 (DWord)

Aber leider ist dieser Schalter nicht als Standard gesetzt.
Ärgerlich wird dies, wenn man ein kleines Setup-Programm schreiben will, dass einige Daten aus dem Nezwerk kopieren soll und dem man ein entsprechendes requireAdministrator-Manifest gibt. Startet man dieses Programm findet es auf einmal nicht mehr die Laufwerke, die eben noch verfügbar waren. Umgehen kann man das ganze nur in dem man UNC-Dateinamen verwendet.

Beschrieben wird dies auch hier auch in diesem KB Artikel und besonders dieser TechNet Artikel.