Share via


Appel de la bibliothèque DbgHelp

Bien que DbgHelp.dll soit fourni avec toutes les versions de Windows, les appelants doivent envisager d’utiliser l’une des versions les plus récentes de cette DLL, comme indiqué dans le package Outils de débogage pour Windows . Pour plus d’informations sur la distribution de DbgHelp, consultez Versions de DbgHelp.

Lorsque vous utilisez DbgHelp, la meilleure stratégie consiste à installer une copie de la bibliothèque à partir du package Outils de débogage pour Windows dans le répertoire de l’application qui est logiquement adjacent au logiciel qui l’appelle. Si le serveur de symboles et le serveur source sont également nécessaires, SymSrv.dll et SrcSrv.dll doivent être installés dans le même répertoire que DbgHelp.dll, car DbgHelp appelle ces DLL uniquement s’ils partagent le même répertoire avec celui-ci. (Notez que DbgHelp n’appelle pas ces deux DLL à partir du chemin de recherche standard.) Cela permet d’éviter l’utilisation de DLL incompatibles ; de même, il améliore également la sécurité globale.

Le code suivant est extrait de la source DbgHelp. Il montre comment DbgHelp charge uniquement les versions de SymSrv.dll et de SrcSrv.dll à partir du répertoire dans lequel DbgHelp.dll réside.

HINSTANCE ghinst;

// For calculating the size of arrays for safe string functions.

#ifndef cch
 #define ccht(Array, EltType) (sizeof(Array) / sizeof(EltType))
 #define cch(Array) ccht(Array, (Array)[0])
#endif

//
// LoadLibrary() a DLL, using the same directory as dbghelp.dll.
//

HMODULE 
LoadDLL(
    __in PCWSTR filename
    )
{
    WCHAR drive[10] = L"";
    WCHAR dir[MAX_PATH + 1] = L"";
    WCHAR file[MAX_PATH + 1] = L"";
    WCHAR ext[MAX_PATH + 1] = L"";
    WCHAR path[MAX_PATH + 1] = L"";
    HMODULE hm;
    
    // Chop up 'filename' into its elements.
    
    _wsplitpath_s(filename, drive, cch(drive), dir, cch(dir), file, cch(file), ext, cch(ext));

    // If 'filename' contains no path information, then get the path to our module and 
    // use it to create a fully qualified path to the module we are loading.  Then load it.
    
    if (!*drive && !*dir) 
    {
        // ghinst is the HINSTANCE of this module, initialized in DllMain or WinMain
         
        if (GetModuleFileNameW(ghinst, path, MAX_PATH)) 
        {
            _wsplitpath_s(path, drive, cch(drive), dir, cch(dir), NULL, 0, NULL, 0);
            if (*drive || *dir) 
            {
                swprintf_s(path, cch(path), L"%s%s%s%s", drive, dir, file, ext);
                hm = LoadLibrary(path);
                if (hm)
                    return hm;
            }
        }
    }
    else
    {
        // If we wanted to, we could have LoadDLL also support directories being specified
        // in 'filename'.  We could pass the path here.  The result is if no path is specified,
        // the module path is used as above, otherwise the path in 'filename' is specified.
        // But the standard search logic of LoadLibrary is still avoided.
        
        /*
        hm = LoadLibrary(path);
        if (hm)
            return hm;
        */
    }
    
    return 0;
}

Après avoir chargé ces deux DLL, DbgHelp appelle GetProcAddress pour obtenir les fonctions dont il a besoin.

Normalement, le code qui appelle DbgHelp.dll garantit que la version correcte est chargée en installant DbgHelp.dll dans le même répertoire que l’application qui a lancé le processus actuel. Si le code appelant se trouve dans une DLL et n’a pas accès à l’emplacement du processus initial ou n’a pas connaissance de l’emplacement du processus initial, DbgHelp.dll doit être installé en même temps que la DLL appelante et le code similaire à LoadDLL de DbgHelp doit être utilisé.

DbgHelp Versions

LoadLibrary

GetProcAddress

GetModuleFileName