按地址检索符号信息

以下代码演示如何调用 SymFromAddr 函数。 此函数会填充 SYMBOL_INFO 结构。 由于名称长度可变,因此必须提供足够大的缓冲区来保存存储在 SYMBOL_INFO 结构末尾的名称。 此外,必须将 MaxNameLen 成员设置为为名称保留的字节数。 在此示例中,dwAddress 是要映射到符号的地址。 SymFromAddr 函数将符号开头的偏移量存储在 dwDisplacement 内的地址中。 请注意,此示例假定你已使用初始化符号处理程序中的代码初始化了符号处理程序。

DWORD64  dwDisplacement = 0;
DWORD64  dwAddress = SOME_ADDRESS;

char buffer[sizeof(SYMBOL_INFO) + MAX_SYM_NAME * sizeof(TCHAR)];
PSYMBOL_INFO pSymbol = (PSYMBOL_INFO)buffer;

pSymbol->SizeOfStruct = sizeof(SYMBOL_INFO);
pSymbol->MaxNameLen = MAX_SYM_NAME;

if (SymFromAddr(hProcess, dwAddress, &dwDisplacement, pSymbol))
{
    // SymFromAddr returned success
}
else
{
    // SymFromAddr failed
    DWORD error = GetLastError();
    printf("SymFromAddr returned error : %d\n", error);
}

为了检索指定地址的源代码行号,应用程序可以使用 SymGetLineFromAddr64。 此函数需要一个指向 IMAGEHLP_LINE64 结构的指针,才能接收对应于指定代码地址的源文件名和行号。 请注意,只有在使用 SymSetOptions 函数设置 SYMOPT_LOAD_LINES 时,才能使用符号处理程序检索行号信息。 在加载模块之前,必须设置此选项。 dwAddress 参数包含将对其定位源文件名和行号的代码地址。

DWORD64  dwAddress;
DWORD  dwDisplacement;
IMAGEHLP_LINE64 line;

SymSetOptions(SYMOPT_LOAD_LINES);

line.SizeOfStruct = sizeof(IMAGEHLP_LINE64);
dwAddress = 0x1000000; // Address you want to check on.

if (SymGetLineFromAddr64(hProcess, dwAddress, &dwDisplacement, &line))
{
    // SymGetLineFromAddr64 returned success
}
else
{
    // SymGetLineFromAddr64 failed
    DWORD error = GetLastError();
    _tprintf(TEXT("SymGetLineFromAddr64 returned error : %d\n"), error);
}