Udostępnij przez


Otrzymywanie powiadomień

Poniższy kod pokazuje, jak uzyskać i zgłosić pełne informacje o stanie z programu obsługi symboli na temat wyszukiwania i ładowania modułów oraz odpowiednich plików symboli.

Wiele osób zaznajomionych z debugerem WinDbg może pamiętać polecenie o nazwie "!sym noisy". To polecenie jest używane przez użytkownika do określenia, dlaczego WinDbg może lub nie może załadować plików symboli. Przedstawia on szczegółową listę wszystkich prób obsługi symboli.

Ta sama lista jest również dostępna dla każdego, kto opracowuje klienta programu obsługi symboli DbgHelp.

Najpierw wywołaj SymSetOptions z parametrem SYMOPT_DEBUG. Powoduje to włączenie powiadomień debugowania przez DbgHelp.

Po wywołaniu SymInitializeużyj funkcji SymRegisterCallback64, aby zarejestrować funkcję wywołania zwrotnego, którą DbgHelp wywoła za każdym razem, gdy wystąpi interesujące zdarzenie. W tym przykładzie funkcja wywołania zwrotnego nosi nazwę SymRegisterCallbackProc64. Funkcje wywołań zwrotnych symboli otrzymują różne kody akcji, które mogą obsługiwać zgodnie z typem. W tym przykładzie obsługujemy tylko kod akcji CBA_EVENT. Ta funkcja przekazuje ciąg zawierający pełne informacje o zdarzeniu, które wystąpiło podczas ładowania symbolu. To zdarzenie może obejmować wszystko, od próby odczytania danych z pliku wykonywalnego, aż po pomyślne zlokalizowanie pliku symboli. SymRegisterCallbackProc64 wyświetla ten ciąg i zwraca true.

Ważny

Upewnij się, że zwracasz false do każdego kodu akcji, który nie jest obsługiwany, w przeciwnym razie może wystąpić niezdefiniowane zachowanie. Zapoznaj się z SymRegisterCallbackProc64, aby uzyskać listę wszystkich kodów akcji i ich implikacje.

 

Po zarejestrowaniu wywołania zwrotnego należy załadować moduł określony w wierszu polecenia, wywołując SymLoadModuleEx.

Na koniec przed wyjściem wywołaj SymCleanup.

#include <windows.h>
#include <stdio.h>
#include <tchar.h>

#ifdef UNICODE
 #define DBGHELP_TRANSLATE_TCHAR
#endif
#include <dbghelp.h>

// Here is an implementation of a Symbol Callback function.

BOOL 
CALLBACK 
SymRegisterCallbackProc64(
    __in HANDLE hProcess,
    __in ULONG ActionCode,
    __in_opt ULONG64 CallbackData,
    __in_opt ULONG64 UserContext
    )
{
    UNREFERENCED_PARAMETER(hProcess);
    UNREFERENCED_PARAMETER(UserContext);
    
    PIMAGEHLP_CBA_EVENT evt;

    // If SYMOPT_DEBUG is set, then the symbol handler will pass
    // verbose information on its attempt to load symbols.
    // This information be delivered as text strings.
    
    switch (ActionCode)
    {
    case CBA_EVENT:
        evt = (PIMAGEHLP_CBA_EVENT)CallbackData;
        _tprintf(_T("%s"), (PTSTR)evt->desc);
        break;

    // CBA_DEBUG_INFO is the old ActionCode for symbol spew.
    // It still works, but we use CBA_EVENT in this example.
#if 0
    case CBA_DEBUG_INFO:
        _tprintf(_T("%s"), (PTSTR)CallbackData);
        break;
#endif

    default:
        // Return false to any ActionCode we don't handle
        // or we could generate some undesirable behavior.
        return FALSE;
    }

    return TRUE;
}

// Main code.

int __cdecl
#ifdef UNICODE
_tmain(
#else
main(
#endif
    __in int argc,
    __in_ecount(argc) PCTSTR argv[]
    )
{
    BOOL status;
    int rc = -1;
    HANDLE hProcess;
    DWORD64 module;
    
    if (argc < 2)
    {
        _tprintf(_T("You must specify an executable image to load.\n"));
        return rc;
    }

    // If we want to se debug spew, we need to set this option.
        
    SymSetOptions(SYMOPT_DEBUG);
    
    // We are not debugging an actual process, so lets use a placeholder
    // value of 1 for hProcess just to ID these calls from any other
    // series we may want to load.  For this simple case, anything will do.
    
    hProcess = (HANDLE)1;
    
    // Initialize the symbol handler.  No symbol path.  
    // Just let dbghelp use _NT_SYMBOL_PATH
    
    status = SymInitialize(hProcess, NULL, false);
    if (!status)
    {
        _tprintf(_T("Error 0x%x calling SymInitialize.\n"), GetLastError());
        return rc;
    }
     
    // Now register our callback.
    
    status = SymRegisterCallback64(hProcess, SymRegisterCallbackProc64, NULL);
    if (!status)
    {
        _tprintf(_T("Error 0x%x calling SymRegisterCallback64.\n"), GetLastError());
        goto cleanup;
    }
    
    // Go ahead and load a module for testing.
    
    module = SymLoadModuleEx(hProcess,  // our unique id
                             NULL,      // no open file handle to image
                             argv[1],   // name of image to load
                             NULL,      // no module name - dbghelp will get it
                             0,         // no base address - dbghelp will get it
                             0,         // no module size - dbghelp will get it
                             NULL,      // no special MODLOAD_DATA structure
                             0);        // flags
    if (!module)
    {
        _tprintf(_T("Error 0x%x calling SymLoadModuleEx.\n"), GetLastError());
        goto cleanup;
    }
    rc = 0;
    
cleanup:
    SymCleanup(hProcess);
    
    return rc;    
}

Określenie null jako drugiego parametru SymInitialize wskazuje, że program obsługi symboli powinien używać domyślnej ścieżki wyszukiwania do lokalizowania plików symboli. Aby uzyskać szczegółowe informacje o tym, jak program obsługi symboli lokalizuje pliki symboli lub jak aplikacja może określić ścieżkę wyszukiwania symboli, zobacz Ścieżki symboli.

Uruchomienie tego programu pokazuje sposób przetwarzania ścieżki symboli. Ponieważ DbgHelp przegląda ścieżkę symboli, aby znaleźć plik symboli, wielokrotnie wywołuje SymRegisterCallbackProc64, który z kolei wyświetla następujące ciągi przekazywane przez DbgHelp.

d:\load.exe c:\home\dbghelp.dll
DBGHELP: No header for c:\home\dbghelp.dll.  Searching for image on disk
DBGHELP: c:\home\dbghelp.dll - OK
DBGHELP: .\dbghelp.pdb - file not found
DBGHELP: .\dll\dbghelp.pdb - file not found
DBGHELP: .\symbols\dll\dbghelp.pdb - file not found
DBGHELP: .\symbols\dll\dbghelp.pdb - file not found
DBGHELP: cache*c:\symbols\dbghelp.pdb - file not found
DBGHELP: cache*c:\symbols\dll\dbghelp.pdb - file not found
DBGHELP: cache*c:\symbols\symbols\dll\dbghelp.pdb - file not found
DBGHELP: d:\nt.binaries.amd64chk\symbols.pri\dbg\dbghelp.pdb - file not found
DBGHELP: dbghelp - private symbols & lines
         dbghelp.pdb