公共、全局和本地符号

DbgHelp API 的符号处理功能多年来经过了不断发展。 若要确保代码在各种方案中工作,并提供有关符号的完整详细信息,请尽可能使用最新函数。 例如,SymEnumSymbols 会替换 SymEnumerateSymbols64SymFromName 会替换 SymGetSymFromName64SymFromAddr 会替换 SymGetSymFromAddr64

公共符号

初始版本的 DbgHelp.dll 支持仅检查公共符号。 这些符号是针对代码中必须在不同源文件之间公开的任何项生成的。 它们还包括从模块中导出的所有项。

符号嵌入在图像中,或者单独存储在 .dbg 或 .pdb 文件中。 存储的唯一信息是符号名称和地址。 这些名称可用作修饰名。 若要查看未修饰名,请使用 SYMOPT_UNDNAME 调用 SymSetOptions 函数,或者使用 UnDecorateSymbolName 函数。

请注意,DbgHelp API 最初并不是为了支持模块中同一符号的多个实例而设计的。 这是因为公共符号仅限于模块中的唯一名称。 因此,SymGetSymFromName64 仅返回匹配的第一个符号。 若要检索匹配的所有符号,请调用 SymEnumSymbols

全局符号和本地符号

使用 .pdb 文件时,较新版本的 DbgHelp.dll 支持全局符号和本地符号。 这些新版本包括静态函数、源文件范围内的函数、函数参数和局部变量。 当 DbgHelp 搜索符号时,它会在检查公共符号表之前检查全局符号表和本地符号表。 这是因为这些类型的符号的可用信息比公共符号的可用信息多。

全局符号和本地符号以未修饰名存储。 因此,SYMOPT_UNDNAME 标志不起作用。 若要获取修饰的符号名称,必须使用 SYMOPT_PUBLICS_ONLY 标志。 这会导致 DbgHelp 仅搜索公共符号。

若要查看局部符号或函数参数,请调用 SymSetContext 函数,并将 IMAGEHLP_STACK_FRAME 结构的 InstructionOffset 成员设置为任何函数符号的地址。 对 SymFromNameSymEnumSymbols 的后续调用可以在此地址的上下文中运行。 为此,请将 BaseOfDll 参数设置为 NULL,并从名称掩码参数中省略模块说明符。 这会强制 DbgHelp 在 SymSetContext 指示的范围内搜索匹配符号。

若要确定符号是否为参数,请检查 SYMBOL_INFO 结构的标志成员。 如果符号是参数,则成员包含 SYMFLAG_PARAMETER。 如果它是本地符号,则成员包含 SYMFLAG_LOCAL。