VS-Tipps & Tricks: Debugger Pseudo Variablen

Die folgenden Variablen helfen mir immer wieder beim Debuggen und zeigen einem während des Debuggens in Watch-Window manch nützliche Information:

  • $TID
    Die Thread ID des aktuellen Threads. Nützlich wenn man mehrere Threads debuggt und bestimmte Threads bei einem Breakpoint identifizieren muss.
  • $HANDLES
    Die Anzahl der aktuell benutzen System-Handles des Prozesses. Handle Leaks lassen sich damit im Debugger leicht überwachen.
  • $ERR
    GetLastError
    leicht gemacht. Schlägt ein WinApi Befehl fehl, dann ist es schön das man sofort beim Debuggen im Watch-Window sehen kann was die Ursache war. Oft genug ist ja im Code selbst kein Aufruf von GetLastError vorhanden oder nötig.

Siehe auch MSDN:
http://msdn.microsoft.com/en-us/library/ms164891.aspx

BTW: WinDbg hat noch einige mehr nette Pseudovariablen:
http://blogs.msdn.com/b/debuggingtoolbox/archive/2008/06/16/special-command-using-variables-and-retrieving-information-through-pseudo-registers.aspx
Schmerzhaft vermisse ich immer wieder $PEB, $TEB, $TPID, $RA im Visual Studio, komisch, dass es die nur im WinDbg gibt.

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,..).

LNK2001: unresolved external symbol _mainCRTStartup

Ich habe einige Zeit gebraucht um herauszufinden warum ein Benutzer von VC-Express die folgende Meldung bekam:

1>------ Build started: Project: Hallo Welt, Configuration: Debug Win32 ------
1>LINK : error LNK2001: unresolved external symbol _mainCRTStartup
1>Hallo Welt.exe : fatal error LNK1120: 1 unresolved externals
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

Der User war ein Anfänger und hat ein leeres Win32 Projekt erzeugt. Anschließend eine Sourcedatei und hat das typische „Hello World“ Programm schreiben wollen.
Das Problem war aber, dass er zwar die Sourcedatei angelegt hat, diese aber nicht in das erzeugte Projekt eingefügt hat.
Sobald man über die erzeugte Sourcedatei über den Menüpunkt File -> Move file Hello World.cpp into -> Hello World  in das Projekt einfügt, klappt alles wie erwartet.
Man kann die Datei natürlich auch über das Kontexmenü im Projekt hinzufügen, oder per Drag & Drop auf den Solution Explorer ziehen.

Und eigentlich ist die Meldung auch klar, für den der sie versteht. Der Linker läuft an, findet keine Objektdateien. Entsprechend werden auch keine CRT Libraries einbezogen und geladen. Aber der Linker will gemäß den Einstellungen einen entsprechenden Einsprungpunkt für die CRT finden und wirft die obige Fehlermeldung aus.

Ich muss ehrlich sagen, dass mir die Fehlermeldung erst etwas gesagt hat, als ich per Email, das Beispielprojekt zugesendet bekam.

Zur Abwechslung mal ein kleines Quiz: Was ist das Problem mit diesem Template?

Folgender Code wurde in einem Programmteil von uns eingebaut:

template <class T>
void SecureClearString(T &strText)
{
  ::SecureZeroMemory(strText.GetBuffer(0),strText.GetAllocLength());
  strText.Empty();
}

Der Sinn und Zweck sollte sein, dass der Inhalt einer CString Variable durch diesen Code überschrieben und anschließend freigegeben wird, damit zum Beispiel ein Kennwort oder ein Benutzername nicht mehr im Speicher lesbar bleibt.
Die Anwendung sieht in etwa so aus (war allerdings noch in einer Klasse gekapselt):

CString strPassword;
...
// Fill password and use it
...
SecureClearString(strPassword);

Doch leider ist was faul mit dem Code… zwei Probleme gibt es mit diesem Stück Code.
Meine Frage an meine Leser lautet nun was ❓

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

Patchday vom 14.06.2011 behebt die Probleme der VisualStudio 2005/2008 Servicepacks vom 13.04.2011

Die nachfolgenden 4 Sicherheitsupdates wurden am 14.06.2011 von Microsoft herausgegeben:

Sicherheitsupdate für Microsoft Visual C++ 2005 Service Pack 1 Redistributable Package (KB2538242)
Sicherheitsupdate für Microsoft Visual Studio 2005 Service Pack 1 (KB2538218)
Sicherheitsupdate für Microsoft Visual C++ 2008 Service Pack 1 Redistributable Package (KB2538243)
Sicherheitsupdate für Microsoft Visual Studio 2008 Service Pack 1 (KB2538241)

Eigentlich beheben Sie nur das, was am Patchday vom 13.04.2011 hätte behoben werden sollen. Ich habe dazu ja mehrere Artikel geschrieben (1, 2, 3, 4, 5). Nach Vergleich der entsprechenden Sourcen machen Sie Änderungen jetzt das, was sie sollen.

Auch das Problem, dass mit dem letzten Sicherheitsupdate, die Größe der Executables immens angewachsen ist wurde behoben.
Schade, dass dieses Problem in VS-2010 weiter bestehen bleibt.
Insbesondere funktioniert diese neue Runtime für VS-2005 auch auf Windows 2000. Eines der Hauptprobleme vom Patchday im April.

Anzumerken wäre hier eigentlich nur noch die neuen Versionen der Runtime die mit diesem Sicherheitsupdate veröffentlicht werden, d.h. auch, dass man nun die neuen Runtimes auch in sein Setup einbauen sollte, bzw. dass man die neueste passende VCRedist_x86 nun auch mit ausliefern muss. D.h. auch, dass sich die entsprechenden Manifeste wieder ändern, sofern man diese manuell angepasst hat:

  • Die neuen Runtimedateien von VS-2005 haben die Versionsnummer 8.0.50727.6195
    Die neue Runtime für VS-2005 gibt es hier zum Download.
  • Die neuen Runtimedateien von VS-2008 haben die Versionsnummer 9.0.30729.6161
    Die neue Runtime für VS-2008 gibt es hier zum Download.

Weitere und vollständige Infos zu diesem Sicherheitsupdate finden sich im VC-Blog:
http://blogs.msdn.com/b/vcblog/archive/2011/06/17/10175518.aspx

Ich jetzt kann nur allen Entwicklern raten diese neuen Sicherheitsupdates auch zu installieren und zu nutzen!

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: Black Patchday for all OS from XP and later 3. – MFC 8.0 (VC-2005) or MFC 9.0 (VC-2008) linked dynamically to the MFC may not find the MFC language DLLs after installation of the security packs dated April 12th 2011

This is the English translation of the already published German article:
BUG: Schwarzer Patchday für alle OS XP und später 3. – MFC 8.0 (VC-2005) oder MFC 9.0 (VC-2008) die dynamisch gelinkt wurden finden die MFC Sprach-DLLs evtl. nicht mehr nach Installation der Sicherheitspatches vom 12.04.2011

Affected are:

  • All programs created with MFC 8.0 and MFC 9.0 that link dynamically to the MFC DLLs .
  • All operating systems from Windows XP and later. 32bit as 64bit
  • Al programs that do not use an application local installation (program directory, see note at the bottom of the article). So all programs that use and depend on WinSxS and VCRedist_x86.exe ( VCRedist_x64.exe).
  • All programs that are localized and use the MFC90xxx.DLL or. MFC80xxx.DLL language-DLLs and the OS system language is not set to English.

It is affected due to the security fixes offered April 12th, 2011:

For VS-2005 SP1 http://support.microsoft.com/kb/2465367 and http://support.microsoft.com/kb/2467175
For VS-2008 SP1 http://support.microsoft.com/kb/2465361 and http://support.microsoft.com/kb/2467174

Failure description:

The MFC language DLLs (satellite DLLs) are not loaded any longer. Parts of the application appear in English and not the selected language from the OS.

Background:

To prevent loading of wrong satellite DLLs (Binary Planting), an internal function in appcore.cpp named _AfxLoadLangDLL was changed. It checks if an activation context is active or not and if the DLLs should be loaded using this context. If there is an activation context active it is safe to load the satellite DLLs(MFCDEUxxx.DLL etc.) without defining a full path. If no activation context is active the path of the current application is used to load and find the satellite DLLs. The DLLs are loaded with a call to LoadLibrary.

The code used looks like this (empty lines removed):

...
TCHAR *pszFilename = ::PathFindFileName(szLangDLL);
ACTCTX_SECTION_KEYED_DATA data;
if (FindActCtxSectionString(
    FIND_ACTCTX_SECTION_KEY_RETURN_HACTCTX,
    NULL,
    ACTIVATION_CONTEXT_SECTION_DLL_REDIRECTION,
    pszFilename,
    &data) )
{
    // Load using the dll name only...
    hInstance = ::LoadLibraryEx(pszFilename, NULL, 0);
}
else
{
    // Load using the full path...
    hInstance = ::LoadLibraryEx(szLangDLL, NULL, 0);
}
...

The code looks OK.  And it is conform to the documentation of FindActCtxSectionString where the last parameter is defined as __out.

BOOL FindActCtxSectionString(
  __in   DWORD dwFlags,
  __in   const GUID *lpExtensionGuid,
  __in   ULONG ulSectionId,
  __in   LPCTSTR lpStringToFind,
  __out  PACTCTX_SECTION_KEYED_DATA ReturnedData
);

But the documentation of ACTCTX_SECTION_KEYED_DATA tells a different story:

Callers should initialize the ACTCTX_SECTION_KEYED_DATA structure as such:
„ACTCTX_SECTION_KEYED_DATA askd = { sizeof(askd) };“
which initializes all members to zero/null except the size field which is set correctly.

(BTW: In my eyes a documentation failure)

So what we see is that the code misses this: data.cbSize isn’t initialized
Now we have 3 possible scenarios what can happen with a  randomly initialized data.cbSize field:

  1. data.cbSize is larger than sizeof(ACTCTX_SECTION_KEYED_DATA):
    In this case the activation context is correctly detected. The program executes normal.  With an activation context no full path is needed. The MFC90xxx.DLL will be loaded from the WinSxS (Side by Side) or found over the common search path.
  2. data.cbSize is less than  sizeof(ACTCTX_SECTION_KEYED_DATA):
    In this case FindActCtxSectionString returns with an error. The DLL is now loaded with a full path name constructed from the application directory to prevent Binary Planting. Butthe problemis that with a normal installation the searched files are all in WinSxS, and the application directory has no such data. The DLL is not loaded.
    If the application local assemblies are used and placed in sub directories they aren’t found either.
  3. A future problem.
    If an OS will use a larger ACTCTX_SECTION_KEYED_DATA and data.cbSize has a greater value than the corresponding sizeof(…):
    We have a buffer-overrun!

I always recommend to use private and application local assemblies for the CRT and MFC DLLs. And to install all this files local to the application.
Years ago I wrote an article for this scenario that was published on CodeProject and a hotfix for VS-2008 is also available
Create projects easily with private MFC, ATL and CRT assemblies
Hotfix für UseMSPrivateAssemblies.h und VC-2008

What to do?

Uninstall all of the mentioned security fixes with the specified article IDs.
Runtime-2005: KB2467175, Runtime-2008: KB2467174
VS-2007 SP1: KB2465367, VS-2008 SP1: KB2465361).

Further notes:

The affected C/C++ Runtimes of Visual Studio have the following version numbers:
– VC-2005 8.0.50727.5592 (KB2467175)
– VC-2008 9.0.30729.5570 (KB2467174)

My comment to tis issue:
It was easier to live with the DLL-hell. 🙁

Many thanks to my Co-MVP Mike Ryan who helped me to discover this problems with the latest security patches:!:

What Do I mean with „application local“?
Some people ship the MFC files in the application directory. In such a case this DLLs are not loaded if a newer version can be found in the WinSxS directory. This is not application local for me!
So if the manifest file in the program directory still have a publicKey entry, the local files will be used  in case of the here described bug. Even if the activation context was not detected, so the local files are a kind of fallback and help prevent get around the problem.
My articles describe how to make your application really application local in removingthe publicKey tokens from the manifest files. Such programs will never fail on such broken security patches. (Just read my article at Codeproject). (Thanks for Co-MVP David Ching who asked me for a clarification)

BUG: Schwarzer Patchday für alle OS XP und später 3. – MFC 8.0 (VC-2005) oder MFC 9.0 (VC-2008) die dynamisch gelinkt wurden finden die MFC Sprach-DLLs evtl. nicht mehr nach Installation der Sicherheitspatches vom 12.04.2011

Betroffen sind:

  • Alle Programme die mit MFC 8.0 oder MFC 9.0 erzeugt wurden und dynamisch an die MFC DLLs gelinkt sind.
  • Alle Betriebssysteme ab Windows XP aufwärts. 32bit wie 64bit
  • Alle Programme, die nicht die MFC und CRT DLLs applikationsnah (d.h. im Programmverzeichnis, siehe dazu auch die Fußnote in meinem Artikel) installiert haben. Also alle Programme die WinSxS benutzen und die VCRedist_x86.exe ( VCRedist_x64.exe)  mit ausliefern.
  • Alle Programme, die lokalisiert sind und die MFC90xxx.DLL bzw. MFC80xxx.DLL Sprach-DLLs verwenden und das OS nicht auf Englisch eingestellt ist

Betrifft die folgenden Fixes vom 12.04.2011:

Für VS-2005 SP1 http://support.microsoft.com/kb/2465367 und http://support.microsoft.com/kb/2467175
Für VS-2008 SP1 http://support.microsoft.com/kb/2465361 und http://support.microsoft.com/kb/2467174

Effekt:

Die MFC Statelite DLLs werden nicht geladen. Teile der Anwendung erscheinen in englischer Sprache.

Hintergrund:

Um das Laden von falschen Satelite DLLs zu verhindern (Binary Planting), wurde intern in appcore.cpp in der Funktion _AfxLoadLangDLL geprüft, ob die DLLs in aus einem Activation Context geladen werden oder nicht. Sollte ein Activation Context vorhanden sein, dann kann man gefahrlos die Sprach DLLs (MFCDEUxxx.DLL etc.) ohne Pfadnamen laden. Ist kein Activation Context vorhanden wird der Pfad der Anwendung verwendet und LoadLibrary mit vollem Pfadnamen durchgeführt.

Der Code der dazu verwendet wird sieht so aus (Leerzeilen entfernt):

...
TCHAR *pszFilename = ::PathFindFileName(szLangDLL);
ACTCTX_SECTION_KEYED_DATA data;
if (FindActCtxSectionString(
    FIND_ACTCTX_SECTION_KEY_RETURN_HACTCTX,
    NULL,
    ACTIVATION_CONTEXT_SECTION_DLL_REDIRECTION,
    pszFilename,
    &data) )
{
    // Load using the dll name only...
    hInstance = ::LoadLibraryEx(pszFilename, NULL, 0);
}
else
{
    // Load using the full path...
    hInstance = ::LoadLibraryEx(szLangDLL, NULL, 0);
}
...

Eigentlich sieht der Code prima aus. Und er verträgt sich auch mit der Doku von FindActCtxSectionString dort wird der letzte Parameter als __out definiert.

BOOL FindActCtxSectionString(
  __in   DWORD dwFlags,
  __in   const GUID *lpExtensionGuid,
  __in   ULONG ulSectionId,
  __in   LPCTSTR lpStringToFind,
  __out  PACTCTX_SECTION_KEYED_DATA ReturnedData
);

Aber die Doku zu ACTCTX_SECTION_KEYED_DATA sagt was anderes:

Callers should initialize the ACTCTX_SECTION_KEYED_DATA structure as such:
„ACTCTX_SECTION_KEYED_DATA askd = { sizeof(askd) };“
which initializes all members to zero/null except the size field which is set correctly.

(BTW: Auch ein krasser Doku-Bug in meinen Augen)

Und jetzt sieht man was dem Code fehlt: data.cbSize wird nicht gesetzt
Daraus ergeben sich nun drei Varianten, da data.cbSize nun zufälligen (nicht initialisierten) Inhalt hat:

  1. data.cbSize ist größer als  sizeof(ACTCTX_SECTION_KEYED_DATA):
    In diesem Fall wird korrekt ermittelt ob ein Activation Context vorhanden ist. Das Programm läuft normal. Mit Activation Context ist kein voller Pfadname nötig. Die MFC90xxx.DLL wird evtl. aus dem WinSxS (Side by Side) geladen, oder in einem der Suchpfade gefunden.
  2. data.cbSize ist kleiner als  sizeof(ACTCTX_SECTION_KEYED_DATA):
    In diesem Fall liefert FindActCtxSectionString einen Fehler und nun wird es spannend. Die DLL wird nun versucht mit dem vollen Pfadnamen zu laden um Binary Planting zu verhindern. Das Problem ist aber dass bei korrekter Installation im WinSxS, dass im Applikationsverzeichnis keine dieser Daten liegen. Die DLL wird nicht gefunden.
    Sollten die private applikationsnahe Assemblies in einem Unterverzeichnis installiert sein, werden diese auch nicht gefunden.
  3. Für die Zukunft.
    Ein zukünftiges OS vergrößert ACTCTX_SECTION_KEYED_DATA und data.cbSize hat zufälligen Inhalt und ist größer als sizeof(…):
    Ein Buffer-Overrun!

Ich empfehle nicht ohne Grund seit VS-2005 private Assemblies zu verwenden, und die MFC Dateien in das Anwendungsverzeichnis zu kopieren. Dazu habe ich auf Code-Projekt einen entsprechenden Artikel geschrieben und ein Hotfix für VS-2008 existiert auch ❗
Create projects easily with private MFC, ATL and CRT assemblies
Hotfix für UseMSPrivateAssemblies.h und VC-2008

Was ist zu tun?

Deinstallation aller hier erwähnten Sicherheitspatches mit den entsprechenden Arikelnummern:
Runtime-2005: KB2467175, Runtime-2008: KB2467174
VS-2007 SP1: KB2465367, VS-2008 SP1: KB2465361).

Weitere Anmerkungen:

Die betroffenen C/C++ Runtimes des Visual Studio haben die folgenden Versionsnummern
– VC-2005 8.0.50727.5592 (KB2467175)
– VC-2008 9.0.30729.5570 (KB2467174)

Mein Kommentar dazu:
Das Leben in der DLL-Hölle war fast angenehmer als das hier. Ohne Worte 🙁

Herzlichen Dank auch an meinem Mit-MVP Mike Ryan, der mit mir zusammen auf diese gesamte Problematik gestoßen ist ❗

Was meine ich mit „application local“?
Einige Entwickler installieren die MFC runtme Dateien im Applikationsverzeichnis. In diesem Fall werden diese DLLs nicht verwendet wenn eine neuere Version der DLLs im WinSxS Verzeichnis liegen. Das ist für mich keine applikationsnahe Instalation! Diese Manifeste im Programmverzeichnis haben immer noch einen publicKey Eintrag. Aber durch die Existenz der lokalen Dateien wird dieses hier beschriebene Problem umgangen, weil die lokalen Dateien eine Art Fallback bilden.
Meine Artikel beschriben wie man eine Anwendung wirklich applikationslokal macht und damit unabhängig von solchen „kaputten“ Security Patches. Dazu muss der publicKey Token aus den Manifesten entfernt werden. (Lesen Sie meinen Artikel aufCodeproject).
(Danke an Co-MVP David Ching der mich um Kläurung gebeten hat)

BUG: Schwarzer Patchday für Windows 2000 2.- MFC 8.0 (VC-2005) und MFC 9.0 (VC-2008) Static Libraries erzeugen auch inkompatiblen Code für Windows 2000 durch KB2465367 bzw. KB2465361

Wer VS-2005 SP1 oder VS-2008 SP1 installiert hatte und bei dem auch die entsprechenden Patches von gestrigen Tag (12.04.2011) durchlaufen wurden, der hat nun auch veränderte statische Libraries.

Sollte man nun also EXEs oder DLLs mit den neuen Libararies statisch linken, dann sind diese genausowenig lauffähig unter Windows 2000. wie auch die EXEs und DLLs die gegen die MFC 8.0 bzw. MFC 9.0 DLLs gelinkt werden

Das Ganze ist hier aufgelistet:
für VS-2005 SP1 http://support.microsoft.com/kb/2465367
für VS-2008 SP1 http://support.microsoft.com/kb/2465361

Die LIBs sind aufgeführt und auch diese verwenden auch die Funktion FindActCtxSectionStringA, die natürlich nicht unter Windows 2000 vorhanden ist.

Siehe auch:
http://blog.m-ri.de/index.php/2011/04/13/bug-schwarzer-patchday-fur-windows-2000-mfc-8-0-vc-2005-und-mfc-9-0-vc-2008-dlls-sind-nicht-mehr-lauffahig-nach-installation-von-kb2467175-bzw-kb2467175/

PS: Ich kann nur raten die entsprechenden Patches zu deinstallieren sofern man noch für Windows 2000 entwickelt und warten bis neue Securitypatches vorhanden sind.

Nachtrag:
Die betroffenen C/C++ Runtimes des Visual Studio haben die folgenden Versionsnummern
– VC-2005 8.0.50727.5592 (KB2467175)
– VC-2008 9.0.30729.5570 (KB2467174)