다음을 통해 공유


알림 받기

다음 코드는 모듈 및 해당 기호 파일의 검색 및 로드에 대한 기호 처리기에서 자세한 상태 정보를 가져오고 보고하는 방법을 보여 줍니다.

WinDbg 디버거에 익숙한 많은 사람들이 "!sym noisy"라는 명령을 기억할 수 있습니다. 이 명령은 WinDbg가 기호 파일을 로드할 수 없거나 로드할 수 없는 이유를 확인하기 위해 사용자가 사용합니다. 기호 처리기가 시도하는 모든 항목의 자세한 목록을 표시합니다.

이 동일한 목록은 DbgHelp 기호 처리기에 클라이언트를 개발하는 모든 사용자가 사용할 수 있습니다.

먼저 SYMOPT_DEBUG사용하여 SymSetOptions 호출합니다. 이로 인해 DbgHelp에서 디버그 알림을 켭니다.

SymInitialize호출한 후 SymRegisterCallback64 사용하여 흥미로운 이벤트가 발생할 때마다 DbgHelp에서 호출하는 콜백 함수를 등록합니다. 이 예제에서 콜백 함수는 SymRegisterCallbackProc64호출됩니다. 기호 콜백 함수는 형식에 따라 처리할 수 있는 다양한 작업 코드를 전달합니다. 이 예제에서는 CBA_EVENT 작업 코드만 처리합니다. 이 함수는 기호를 로드하는 과정에서 발생한 이벤트에 대한 자세한 정보가 포함된 문자열을 전달합니다. 이 이벤트는 실행 파일 내의 데이터를 읽으려는 시도부터 기호 파일의 성공적인 위치에 이르기까지 무엇이든 될 수 있습니다. SymRegisterCallbackProc64 해당 문자열을 표시하고 TRUE 반환합니다.

중요하다

처리하지 않는 모든 작업 코드에 FALSE 반환해야 합니다. 그렇지 않으면 정의되지 않은 동작이 발생할 수 있습니다. 모든 작업 코드 및 해당 의미 목록은 SymRegisterCallbackProc64 참조하세요.

 

콜백이 등록되었으므로 SymLoadModuleEx호출하여 명령줄에 지정된 모듈을 로드해야 합니다.

마지막으로 종료하기 전에 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;    
}

SymInitialize 두 번째 매개 변수로 NULL 지정하면 기호 처리기가 기본 검색 경로를 사용하여 기호 파일을 찾아야 합니다. 기호 처리기가 기호 파일을 찾는 방법 또는 애플리케이션에서 기호 검색 경로를 지정하는 방법에 대한 자세한 내용은 기호 경로참조하세요.

이 프로그램을 실행하면 기호 경로가 처리되는 방식이 표시됩니다. DbgHelp는 기호 경로를 통해 기호 파일을 찾을 때 SymRegisterCallbackProc64 반복적으로 호출하며, 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