Gründe für den R6034 bei der VC 8.0 DLL CRT

Warum lässt sich die neue VC 8.0 CRT eigentlich nicht ohne Manifest verwenden?
Schauen wir uns also mal an was passiert wenn eine Applikation oder eine DLL geladen wird, die die VC 8.0 CRT als DLL verwendet:

Die DllMain der CRT wird aufgerufen. Bei der C-Runtime DLL ist dies die Funktion _CRTDLL_INIT die sofort die Funktion __CRTDLL_INIT aufruft.

Diese Funktion sorgt nun der Reihe nach dafür, dass:

  • die aktuelle Windows Version bestimmt wird
  • der Heap initialisiert wird
  • die TLS Bereiche für multithreading angelegt werden
  • das Environment und die Befehlszeile bestimmt werden
  • die MBCS Umwandlungstabellen angelegt werden
  • alles was mit atexit, floating-point math etc. initialisiert wird
  • und… jetzt wird es spannend… die Funktion _check_manifest aufgerufen wird.

In der Funktion _check_manifest wird der Code ausgeführt der zum Runtime Fehler R6034 „The application has attempted to load the runtime library incorrectly. Contact support for more information“ führen kann, nämlich genau dann, wenn diese Funktion FALSE zurück gibt.

Was macht diese Funktion nun?
Im Source-Code der CRT ist dies wunderbar dokumentiert:

  1. if (pre-fusion OS)
      return TRUE; [no need to check]

    Das bedeutet nichts anderes, als das die nachfolgenden Tests nur auf XP/Vista/2003 und folgenden OS durchgeführt werden. Also im Klartext unter Windows 2000 kann dieser Runtime Error nicht auftreten.
  2. if dll is being loaded by instrumented-mscoree.dll.
      return TRUE;
    OK. Ein Speziallfall. Im Kontext der .NET CLR und des Profilers ist auch ales erlaubt. Also wenn sich MSCoree.dll (Microsoft .NET Runtime Execution Engine) und PGORT80.dll (Profile Guided Optimization Instrumentation Runtime) im Speicher befinden ist auch alles paletti.
  3. if (dll is loaded from system32)
      return FALSE;
    Dies ist interessant. In keinem Fall darf diese DLL im Windows\System32 stehen! Oder wenn Sie von dort geladen wird fielgt einem der R6045 um die Ohren.
  4. if (!(loaded through a manifest))
      return FALSE;

    Hier wird über die Funktion FindActCtxSectionStringW geprüft ob diese DLL über ein Manifest geladen wird. ActCtx ist die Abkürzung für Activation Context.
    Wurde kein solcher Activation Context gefunden (also kein Manifest), dass für diese DLL verantwortlich ist, dann heißt das auch R6045.
  5. if (loaded from %SystemRoot%\WinSxS)
      return TRUE; [loaded from the WinSxS cache]

    Wird die DLL aus den Side by Side Verzeichnissen geladen ist schon alles gut.
    Aber auch das geht nur mit gültigem Manifest.
  6. if (manifest is in the same folder as the dll)
      return TRUE;
    Auch das ist interessant. Das Manifest muss zwingend im selben Verzeichnis wie diese DLL liegen, denn sonst sind wir fertig
  7. return FALSE; [loaded with another manifest]
    und nun schlägt das Laden fehl, da das Manifest offensichtlich nicht im DLL Verzeichnis liegt. Auch hier ein R6045.

Zurück noch mal zum Fall 2. Was macht dieser Test „if dll is being loaded by instrumented-mscoree.dll“? Er macht nichts anderes als zu prüfen ob die beiden DLLs im Speicher sind.

BTW: Man könnte nun ganz frech zwei leere DLLs mit diesen Namen erzeugen und diese in ein Projekt implizit laden lassen… und siehe da, die Applikation benötigt auf einmal kein Manifest mehr…
Aber warum sich das ganze verbietet ist auch klar. DLLs mit den oben genannten Namen zu erzeugen, kann ganz schön verwirrend und problematisch werden.
Und warum zwei leere DLLs in einen Prozess laden, wenn es reicht ein Manifest zu ergänzen? 😉

4 Gedanken zu „Gründe für den R6034 bei der VC 8.0 DLL CRT“

  1. Hallo Martin,
    du scheinst bis jetzt am meisten zu wissen über diese sehr lästige Fehlermeldung.
    Ich programmiere 3D-Applikationen mit VC9 mit OpenGL und Qt4 als GUI.
    Ich habe die R6034 Fehlermeldung immer wieder und dann mal wieder nicht.
    In allen meinen Projekten ist das Manifest eingebunden.
    In meinem bin Directory liegen alle DLL die es braucht inkl. msvcp90.dll und msvcr90.dll in Debug und Release Version inkl. deren Manifeste.
    Manchmal geht der Fehler weg, wenn ich ein Rebuild mache.

    Hat der Fehler R6034 etwas mit Precompiled Headern zu tun?
    Wo fände ich noch mehr Infos zu diesem Fehler?

    Gruss & Dank
    Marcus Hudritsch

  2. Hi Marcus!

    Immer wieder? Dann machst Du grundsätzlich was falsch. Alleine, dass Du die DLLs in Deinem Verzeichnis hast wundert mich, denn normalerweise liegen diese in WinSxS.

    Wende dich am Besten mit Deinen Problemen an ein publikes Forum:
    nntp://microsoft.public.de.vc
    http://www.c-plusplus.de/forum
    oder
    http://social.msdn.microsoft.com/Forums/de-DE/visualcplusde

    Es macht wenig Sinn solche Sachen in den Kommentaren zu diskutieren.
    Zudem gibt es zu R6034 nicht mehr zu sagen, als was ich hier schreibe.
    Alle Ursachen sind hier aufgeführt. Das kannst Du selbst im CRT Sourcecode nachsehen. Also verstößt Du gegen eine dieser Regeln…

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.

This site uses Akismet to reduce spam. Learn how your comment data is processed.