Bei der Umstellung eines Projektes von VS-2005 auf VS-2010 lief unsere Software im Testfeld ohne Probleme, bis auf einem Rechner, auf dem gezielt immer wieder der selbe Fehler auftrat.
Der Stackdump zeigte aber immer wieder eine unterschiedliche Absturzadresse. Glücklicherweise konnten wir durch Crash-Dumps einigermaßen lokalisieren was passierte. Eigentümlicherweise zeigte sich der Crash immer beimAufruf einer bestimmten Windows-Prozedur:
Eigentümlicherweise lief das selbe Programm mit VS-2005 kompiliert auf allen Maschinen. Also vermutete ich einen Compilerfehler! Aber wie kann ein Compilerfehler nur auf einer Maschine zu einem Problem werden?
Aber ich lag komplett daneben.
Nach der Analyse des Codes stellte sich heraus das DEP die Ursache war, und das der Crash nur auf der einizgen Maschine auftrat, auf der DEP unterstützt wurde und eingeschaltet war.
Die anderen Rechner im Testfeld unterstützen DEP nicht:
Und auf diesen trat der Fehler nicht auf.
Weitere Analyse zeigte, dass ein spezieller Code aus einer Fensterklasse, die ich von einer Libary übernommen hatte ein spezielles Windows Subclassing mit einem Thunking ähnlich wie ATL machte, jedoch wurde der Speicher nicht korrekt als ausführbar markierte.
Folgerichtig krachte es. D.h. die paar Codezeilen, die gerade mal einen JMP und das laden eines Registers durchführten wurden von DEP als illegal betrachtet und es kam zum Crash.
Und das eigentümliche, dass der Code mit VS-2005 kompiliert lief, war auch schnell erklärt.
Als das Projekt von VS-2005 in VS-2010 übernommen wurde, wurden auch die Optionen für DEP (/NXCOMPAT) und auch ASLR (/DYNAMICBASE) eingeschaltet ❗
Das ist eigentlich nicht nett, denn es hat schon einige weitreichende Konsequenzen für die Software.
Also aufgepast bei der Konvertierung von Programmen und genau darüber nachgedacht ob man DEP und ASLR wirklich für seine Software will ❗
Aufpassen mit DEP muss man auch, wenn innerhalb der eigenen Anwendung Explorer-Erweiterungen (Kontextmenü, Eigenschaftendialog, …) verwendet werden. Ältere Erweiterungen basieren teilweise noch auf ATL 7.1 oder früher und bringen durch die Thunking-Funktion dann die Anwendung zu Absturz.
Problematisch sind hier aber nur 32-bit Anwendungen, für 64-bit Anwendungen gab es glücklicherweise keine ATL 7.1. 😉
Danke Sven für Deinen (wie immer) hilfreichen Kommentar.
Ich weiß nicht woher mein alter Thunking Code kam, aber ich vermute entweder aus dem alten ATL Code, oder einem Code von PJ-Naughter, der den evtl. auch wieder bei ATL abgeschaut hat.
Wenn man Thunks benötigt dann sollte man gleich zur ATL greifen (ab 8.0 und höher).
Mit SetProcessDEPPolicy kann man auch DEP aktivieren und das Verhalten bei ATL-Thunks anpassen. So richtig schlau bin aus der Beschreibung der Flags aber noch nicht geworden.