알림 수신
다음 코드는 모듈 및 해당 기호 파일의 검색 및 로드에 대한 자세한 상태 정보를 기호 처리기에서 가져와 보고하는 방법을 보여 줍니다.
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