取得通知
下列程式代碼示範如何從符號處理程式取得和報告詳細信息狀態資訊,以搜尋和載入模組和對應的符號檔。
許多熟悉 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;
}
將 NULL 指定為 SymInitialize 的第二個參數,表示符號處理程式應該使用預設搜尋路徑來尋找符號檔。 如需符號處理程式如何尋找符號檔或應用程式如何指定符號搜尋路徑的詳細資訊,請參閱 符號路徑。
執行此程式會顯示符號路徑的處理方式。 當 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