Das Update für Microsoft Visual Studio 2010 Service Pack 1 (KB2635973) macht Visual-Studio instabil

Ich habe eindeutig und nachvollziehbar die Erfahrung gemacht, dass dieser Fix Update für Microsoft Visual Studio 2010 Service Pack 1 (KB2635973) Visual-Studio 2010 instabil macht. (siehe auch http://support.microsoft.com/?kbid=2635973)

Ich habe seit längerer Zeit immer wieder Abstürze in Visual-Studio. Nachvollziehbar ist in den Dumps zu sehen, dass dies immer dann passiert wenn der Garbage-Collector anläuft. Es ist auch immer die selbe Stelle in den selben Modulen.

Oft verschwindet eine offene Visual-Studio Instanz, die im Hintergrund offen war, während ich z.B. in Outlook eine Email schreibe einfach vom Bildschirm und startet erneut. Ich sehe dann ein „blinken“ in der Startleiste. Die Solution ist natürlich geschlossen. Dateien wurde nicht gesichert (können aber meistens recovert werden).
Oder ich arbeite in einem großen Projekt und Tippe meistens eine Klammer, einen Punkt oder einen Strich-Größerzeichen und Intellisense springt an und crashed meine Anwendung.

Ich habe mir sogar die Mühe gemacht 4 Arbeitstage ohne Addins zu arbeiten um zu prüfen ob ein Addin der Verursacher war. Ich kam mir ohne VA-X und Powertools wie Fingeramputiert vor. Dennoch kam es immer wieder zu Crashes, der genau gleichen Art. Meistens immer in großen Projekten.

Ich habe natürlich einen Case dazu, auf dem sich aber eigentlich nichts tut, obwohl Microsoft haufenweise Dumps von mir bekommen hat:
http://connect.microsoft.com/VisualStudio/feedback/details/635653/crash-while-navigating-in-vs-2010-and-crashes-when-vs-is-inactive-in-the-background

Allerdings bekam ich jetzt einen Tipp von einem Microsoft Mitarbeiter in diesem Case, den oben genannten  Fix zu deinstallieren.
Die Crashes sind nicht weg, aber sind eindeutig weniger geworden ❗
Wenn man sich die Daten ansieht merkt man auch schnell, dass ich diesen Case auch veröffentlicht, bevor der besagte Fix KB2635973 herauskam.

Tipp: Wer also mit einer Englischen VS-Version arbeitet sollte diesen Hotfix meiner Meinung nach deinstallieren ❗

Manchmal der letzte Retter in der Not: VA-X und die interne Historie

So geht es manchmal:

  • Da arbeitet man 4, 8, 12 oder 16 Stunden an einem Modul.
  • Alles sieht gut aus, nicht mehr lange und wir können einchecken.
  • Du änderst noch dies und das, steckst noch mal 2 Stunden Arbeit rein weil noch was optimiert werden soll und auf einmal merkst Du dass Du Dich verrannt hast. Die letzten 2 Stunden Arbeit hattest Du irgendwie das Gehirn nicht eingeschaltet, x-Änderungen gemacht, die nun alle Sch…sind.
  • Undo ist nicht mehr, weil Du schon andere Projekte offen hattest bzw. einmal VS abgeraucht ist.
  • Du hast Bockmist gebaut und jetzt willst Du auf den Stand von vor 4 Stunden zurück, oder den von gestern Abend.
  • Ein Shelveset hast Du im TFS nicht angelegt. Das machst Du nur wenn Du ins Wochenende gehst, oder Deinen Kollegen was weiterreichen musst.

Was nun? 😮

Als VA-X Benutzer (VisualAssist X http://www.wholetomato.com) hat man tatsächlich noch ein Backup!
Und zwar nicht nur eines, sondern ein paar.
In meinem History Ordner von VA-X
C:\Users\USER\AppData\Local\Microsoft\VisualStudio\10.0\Extensions\Whole Tomato Software\Visual Assist X\VERSION\Data\vs10\history\
werde ich fündig…

Ufff… :mrgreen:

Ich habe dieses Backup mittlerweile schon so oft verwendet, dass ich dazu übergangen bin diesen Ordner umzulegen an eine Stelle an die ich schneller dran komme. Das geht über den Registry Schlüssel HKCU\Software\Whole Tomato\UserDataDir.

Wer mehr dazu wissen will findet hier weitere Infos:
http://www.wholetomato.com/forum/topic.asp?TOPIC_ID=6865

Nachtrag (30.01.2012):
Damit diese Funktion auch verfügbar ist muss im VA-X die Auto Recovery Option eingeschaltet sein.
VA-X -> Options -> Performance -> Enable Auto Recovery

Visual Studio 2010 komplett entfernen bzw. die Unmöglichkeit es richtig zu tun

Immer wieder mal lese ich von Problemen bei der Installation oder mit Installationen von VS-2010. Ich hatte den Fall noch nie, aber es gibt scheinbar immer wieder Installationen in denen der Wurm drin ist.

VS-2010 installiert eine Unmenge an Komponenten und Programmteilen. Die meisten können einfach deinstalliert/gelöscht werden. Aber es bleiben immer noch ein Haufen DLLs/ActiveX Controls und Registry Einträge und Verweise auf Verzeichnisse. Und leider gibt es für die Visual Studio 2010 keinen richtigen Uninstaller, der auch alle Artefakte löscht und deshalb kann ich gleich zu Anfang sagen, dass man außer der Deinstallation wirklich wenig tun kann.
Eine Reparaturinstallation sollte man aber bei einer bestehenden Installation in jedem Fall einmal, bevor man zu härteren Maßnahmen greift. Die wirkt oft schon Wunder.

Im Netz gibt es das folgende Utility: Visual Studio 2010 Uninstall Utility:
http://archive.msdn.microsoft.com/vs2010uninstall
Das Tool hat drei Operationsweisen die man in dem obigen Link erklärt findet.
Das Tool funktioniert eigentlich ohne Probleme aber benutzt auch nur auf dem MSI Uninstall Prozess auf, und dabei berücksichtigt es nicht einmal Servicepacks. Sollte man also das SP1 von Visual Studio 2010 installiert haben, dann muss man dieses vorher selber entfernen.

Das dieses Tool macht aber auch nur die Arbeit halb. Das erkennt man mit einem schnellen Blick in Registry. Der Ast HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\10.0 wird durch die Deinstallation nicht entfernt und man muß in diesem Fall manuell Hand anlegen.

Wenn man also persistente Probleme mit der VS-2010 Installation hat, die man nicht über die Setup-Logs oder mit Tipps aus den Foren lösen kann, dann bleibt nach meiner Meinung nur der harte Weg den Rechner neu aufzusetzen. Bisher bin ich davon verschont geblieben und meine Installation haben immer von Rechnerwechsel zu Rechnerwechsel gehalten.

4 Termine für Microsoft C++ Infoday 2012

Wer letztes Jahr im Oktober keine Zeit hatte zum C++ Info Day nach München zu kommen, kann dies nun nachholen.

In etwa ähnliche Themen werden an vier verschiedenen Terminen und Standorten von Microsoft kostenlos angeboten:

Die Themen:

  • C++ 11: Modernes C++ im 21. Jahrhundert
  • Parallel-Power in Visual Studio 11: Konzepte und Tools
  • Application Lifecycle Management für C++: Die nächste Generation

Die Termine:

Ich werde 07.02. in Bad Homburg vor Ort sein um ein wenig Networking zu betreiben.
Da es aktuell eigentlich keine C/C++ Community im Netz gibt sehe ich hier die einzige wirklich gute Möglichkeit mit anderen C/C++ Entwicklern ins Gespräch zu kommen.

Für was ist der Makro %(PreprocessorDefinitions) gut ?

In den C++ Compilereinstellungen finden sich ein vorgegebener Makro %(PreprocessorDefinitions) in den C++ Präprozessor Definitionen. Die Verwendung dieses Makros ist nicht ganz offensichtlich.

Dieser Makro sollten in jedem Fall nicht entfernt werden, denn Sie dienen der Übernahme einiger Einstellungen aus der General-Seite für die C++ Projekte. Zum Beispiel werden die Einstellungen für Unicode und MBCS über den Makro %(PreprocessorDefinitions) in die allgemeinen Compiler-Einstellungen übernommen (die entsprechenden Defines sind _UNICODE; UNICODE; _MBCS ).
Erzeugt man eine DLL wird zusätzlich _WINDLL gesetzt.
Setzt man ATL Optionen in der General Seite wird auch über die %(PreprocessorDefinitions) _ATLDLL bzw. _ATL_STATIC_REGISTRY gesetzt oder zurückgesetzt.
Gleiches gilt, wenn die MFC als shared DLL verwendet wird. In diesem Fall wird der Define _AFXDLL zusätzlich gesetzt.

Löscht man also %(PreprocessorDefinitions) dann werden alle diese Einstellungen nicht mehr  korrekt übernommen.

Anmerkung:
Bei dem Linker Makro %(AdditionalDependencies) habe ich eine ähnliche Verwendung vermutet, konnte aber keine direkte Beziehung zur Seite General herstellen.

Obwohl es auch hier Einflüsse auf die Linkereinstellungen gibt bei Änderungen in den General-Einstellungen. Werden allerdings die MFC als zusätzliche Bibliothek ausgewählt werden die Standard-LIBs aus dem SDK komplett entfernt. Hier gibt die MFC Bibliothek selbst vor in welchen zusätzlichen Libs, des SDK gesucht werden soll über #pragma comment(lib,..).

Änderungen in den VC-Libraries des Sicherheitsupdates vom 09.08.2011

Eigentlich kann man es kein Sicherheitsupdate nennen. Ich sehe  eigentlich nur eine sicherheitsrelevante Änderung in:

  • atltransactionmanager.h (ATL)
    Hier wird das Laden der ktmw32.dll jetzt mit einer neuen Funktion AtlLoadSystemLibraryUsingFullPath durchgeführt, die in atlcore.h hinzugefügt wird. Diese Funktion lädt eine DLL nur aus dem Windows-System Verzeichnis. Damit wird Binary-Planting verhindert, aber dies betrifft eigentlich nur Windows Vista / 7 / 2008 Windows 2003 und Windows XP (Nachtrag am 18.08. siehe dazu Kommentar von Stefan Kuhr) und diejenigen die den Kernel Transaction Manager mit der ATL nutzen.

Bugfixes habe ich folgende gefunden:

  • afxtoolbarimages.cpp (MFC)
    In CPngImage::LoadFromBuffer wurde bei der Verwendung dieser Funktion in Speicherblock eines Streams nicht freigegeben (falsche Nutzung von CreateStreamOnHGlobal).
  • dbcore (MFC / ODBC)
    In CRecordset::BuildUpdateSQL in der ODBC Implementierung, wird bei Abfrage eines Cursornamens ein Puffer von 18 Zeichen Länge verwendet (MAX_CURSOR_NAME). Ist der Cursorname länger so wurde eine Exception geworfen. Jetzt wird erkannt, dass der Buffer zu klein ist und es wird ein dynamischer Buffer mit ausreichender Größe alloziert und der Name dann abgefragt.
  •  xutility (STL und auch CRT)
    In der Basisklasse der Iteratoren wurde eine Änderung gemacht. Scheinbar hat die Zuweisung eines „leeren/nicht initialisierten“ Iterators bisher einen Iterator gar nicht verändert. Der alte Iterator wurde nicht aufgelöst durch _Orphan_me. Dies bringt dann Probleme mit sich wenn der _ITERATOR_DEBUG_LEVEL mit 2 genutzt wird.
    Da dieser STL Code auch komplett in der CRT verwendet wird, hat dies auch Einfluß auf die CRT.
    Auf die Release Version aber hat diese Code-Änderung jedoch keinen Einfluss, soweit ich das erkennen kann.

Es gibt noch einige andere Dateien, die geändert wurde, aber hier haben sich nur unwichtige Kommentare geändert.

Fazit: Alles in allem ein Sicherheitspatch, der eher Bugfixes enthält, aber selbst die sind nicht sonderlich weitreichend. Und der Nutzerbereich, der mit der ATL den Kernel Transaction Manager nutzt, wird wohl eher klein sein…

PS: Die Dateien dieses Sicherheitspatches haben die Version 10.0.40219.325.
Die Dateien aus dem VS-2010 SP1 haben die Versionsnummer 10.0.30319.1.

Nachtrag 01.12.2011, MSDN Links:
Sicherheits Bullentin:   MS11-025
Knowledge Base-Artikel (KB-Artikel):  KB2565057

VS-Tipps & Tricks: Wie man gezielt einen Breakpoint für einen Thread setzen kann

Wenn man eine Anwendung oder einen Dienst hat, der mit vielen Threads arbeitet, dann kann das Debuggen abenteuerlich werden. Besonders wenn viele Threads ein und die selbe Threadfunktion verwenden.
Was macht man nun wenn man einen Thread isoliert hat und dessen Verhalten weiter prüfen möchte? Single-Stepping ist nicht drin, denn der Breakpoint würde auch jeden anderen Thread anhalten, der diese Code-Position erreicht.

Die nachfolgende Methode ist relativ einfach um gezielt einen Breakpoint für einen Thread zu setzen.
Gehen wir mal davon aus, dass wir im Debugger einen Breakpoint haben und uns im Kontext des Threads befinden, den wir nun weiter verfolgen wollen.

  1. Zuallererst ermitteln wir die Thread-Id.
    Das geht elementar einfach über die Pseudo-Debugger-Variable $TID, die wir uns im Watch-Fenster, oder im Quick-View anzeigen lassen:
  2. Als nächstes modifizieren wir den Breakpoint so, dass er nur noch dann stoppt, wenn auch unser Thread diesen Breakpoint erreicht.
    Das erreichen wir über die Breakpoint-Eigenschaft Condition (rechter Mausklick, über das Kontextmenü):

    Hier geben wir einfach als Bedingung an, das $TID (also die Thread-ID) identisch sein muss, zu der ID des Threads, den wir beobachten wollen.
  3. Den Rest macht der Debugger für uns, wenn wir wieder den Go-Befehl (F5) geben:

Auf diese Weise kann man auch mehrere Threads einfach beobachten.

Hinweis:
Dieses Verfahren ändert das Laufzeitverhalten des Programmes, denn der Breakpoint wird immer intern ausgeführt, egal welcher Thread diese Codestelle passiert. Nur ermittelt der Debugger dann die Bedingung returniert und lässt das Programm, dann weiterlaufen, wenn die Id nicht passt. Wird diese Codestelle sehr oft passiert, dann kann ist der Einfluss eines solchen Breakpoints nicht  unerheblich.

Alternativ, kann man in solch einem Fall auch ein Stück Code einsetzen, der die aktuelle Thread-ID gegen eine statische Variable testet und einen DebugBreak ausführt. Die statische Variable setzt man dann während der Debugsession auf die gwünschte Thread-ID über das Watch-Window oder den Quick-View

Weiterführende Infos zu Debugger-Pseudo-Variablen von Visual-Studio findet man hier:
http://msdn.microsoft.com/en-us/library/ms164891.aspx

Feature Request: Always ask the developer before applying a service pack or a security fix to Visual Studio that need changed C++ runtime DLLs ATL/MFC/CRT

I know this is a German blog, but for reaching a wider range of developer this article is written in English 🙂

In the past security patches to Visual Studio were automatically installed on the machines of developers. This might have a great impact of to the shipment of the software that is created with this new pachted Visual-Studio version and it might cause incompatibilities with previous created modules.

And we all suffered under the problems that came with this patches and I don’t want to know how much time and money was wasted here.

Also I am aware of the risk that is caused when security fixes are not applied. But the last decision must be allowed to a developer if a fix is applied or not.

To avoid this I have a feature request that such security fixes to Visual Studio (any Version: VS-2005, VS-2008, VS-2010) is only applied to the developers machine if he is asked to do this!

Please use your vote and your words to comment this feature request ❗
Here is the link:

Always ask the developer before applying a security fix or service pack to Visual Studio that need changed the C++ runtime DLLs ATL/MFC/CRT

BUG: VS-2010 erkennt nicht die Änderung an einer Manifest Datei in einem C++ Projekt

Ich habe einige Manifest Dateien in meinen Projekten. Viele steuern COM Module und machen diese registration-free. Das ist einfach und effektiv. Dazu habe ich einfach eine entsprechende Manifestdatei angelegt mit den entsprechenden Einträgen und diese in das Projekt eingefügt. Soweit alles gut.

Jetzt stellte sich aber heraus, dass VS-2010 (auch SP1), eine Änderung der Manifest Datei nicht bemerkt und die EXE/DLL weder neu linkt, noch das Manifest-Tool anwirft, um das geänderte Manifest in das Executable einzutragen.

Dabei spielt es keinerlei Rolle, ob die Datei nur einfach in das Projekt eingefügt wurde, oder ob die Datei zusätzlich in den Projekteinstellungen für das Manifest Tool bei Additional Manifest Files eingetragen wird.

Das ist ein lästiger Fehler, der in VS-2005 und VS-2008 nicht vorhanden war.
Er hat mich mindestens 4 Stunden Arbeit gekostet, weil ich bestimmte Abhängigkeiten testen und Fehler beheben wollte aber die neuen Dateien in dem Projekt immer wieder SxS Fehler lieferten. Es dauerte eine ganze Weile bis ich merkte, dass meine Änderungen an den Manifest Dateien überhaupt nicht in meine Executables übernommen wurden und ich immer wieder nur alte Manifeste in den EXEs und DLLs hatte.
Und dann das Ganze an einem Montagmorgen und nach der Zeitumstellung… 😉

Auf Connect habe ich einen entsprechenden Bug veröffentlich und mir wurde ein Fix empfohlen, der bei mir das Problem behebt.
Changes to a Manifest file in a C++ project does not trigger a rebuild of the EXE or DLL

In der Datei %Programfiles%\msbuild\microsoft.cpp\v4.0\Microsoft.cppcommon.targets wird die folgenden Kommentarzeile gesucht:

<!-- If RC did produce an output, then force link to embed that manifest.
     This enforcement is required for projects residing on FAT32 drives. -->

Darunter wird der folgende Textblock eingefügt:

<PropertyGroup>
    <LinkSkippedExecution Condition="@(RCSourcesCompiled)!=''">
        false
    </LinkSkippedExecution>
</PropertyGroup>

Danch wird eine Änderung im Manifest korrekt erkannt und der Linker für die geänderte Ressouce angeworfen.

Umstellung eines Projektes auf VS-2010 schaltet DEP (/NXCOMPAT) ein und ASLR (/DYNAMICBASE) ein

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 ❗