Compartir a través de


Uso de la librería DbgHelp

Aunque DbgHelp.dll se incluye con todas las versiones de Windows, los usuarios deben considerar el uso de una de las versiones más recientes de este archivo DLL, tal como se encuentra en el paquete Herramientas de depuración para Windows. Para obtener más información sobre la distribución de DbgHelp, consulte Versiones de DbgHelp.

Al usar DbgHelp, la mejor estrategia es instalar una copia de la biblioteca desde el paquete Herramientas de depuración para Windows en el directorio de la aplicación adyacente lógicamente al software que lo llama. Si también se necesitan el servidor de símbolos y el servidor de origen, tanto SymSrv.dll como SrcSrv.dll deben instalarse en el mismo directorio que DbgHelp.dll, ya que DbgHelp solo llamará a estos archivos DLL si comparten el mismo directorio con él. (Tenga en cuenta que DbgHelp no llamará a estos dos archivos DLL desde la ruta de búsqueda estándar). Esto ayuda a evitar el uso de archivos DLL no coincidedos; del mismo modo, también mejora la seguridad en general.

El código siguiente se extrae del origen DbgHelp. Muestra cómo DbgHelp solo carga versiones de SymSrv.dll y SrcSrv.dll desde el mismo directorio en el que reside DbgHelp.dll.

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;
}

Después de cargar estos dos archivos DLL, DbgHelp llama a GetProcAddress para obtener las funciones que necesita de ellos.

Normalmente, el código que llama a DbgHelp.dll garantiza que la versión correcta se cargue instalando DbgHelp.dll en el mismo directorio que la aplicación que inició el proceso actual. Si el código que realiza la llamada está en un archivo DLL y no tiene acceso o conocimiento de la ubicación del proceso inicial, entonces DbgHelp.dll debe instalarse junto con la DLL de llamada, y se debe usar código similar a LoadDLL de DbgHelp.

Versiones de DbgHelp

LoadLibrary

GetProcAddress

GetModuleFileName