范围和符号组
符号组包含一组符号,用于作为一个组进行高效操作。 可以手动创建和填充符号组,也可以根据词法范围中的符号(例如局部变量和函数参数)自动生成和更新符号组。 接口 IDebugSymbolGroup 用于表示符号组。
有两种方法可以创建符号组。 CreateSymbolGroup 返回空符号组,当前词法范围的符号组由 GetScopeSymbolGroup 返回。
注意从当前范围生成的符号组是局部变量的快照。 如果目标中发生任何执行,符号可能不再准确。 此外,如果当前范围发生更改,符号组将不再表示 当前 作用域 (,因为它将继续表示) 为其创建的范围。
可以使用 AddSymbol 将符号添加到符号组,并使用 RemoveSymbolByIndex 或 RemoveSymbolByName 删除符号。 方法 OutputAsType 告知调试器在处理符号的数据时使用不同的符号类型。
注意 作用域内符号的值可能不准确。 具体而言,计算机体系结构和编译器优化可能会阻止调试器准确确定符号的值。
符号条目信息是符号的说明,包括其位置和类型。 若要在模块中查找符号的此信息,请使用 IDebugSymbols3::GetSymbolEntryInformation。 若要查找符号组中某个符号的此信息,请使用 IDebugSymbolGroup2::GetSymbolEntryInformation。 有关符号输入信息的详细信息,请参阅 DEBUG_SYMBOL_ENTRY 。
以下方法返回有关符号组中的符号的信息:
GetSymbolName 返回符号的名称。
如果符号具有绝对地址,GetSymbolOffset 将返回符号的目标虚拟地址空间中的绝对地址。
如果符号包含在寄存器中,则 GetSymbolRegister 返回包含符号的寄存器。
GetSymbolSize 返回符号的数据大小。
GetSymbolTypeName 返回符号的类型的名称。
GetSymbolValueText 将符号的值作为字符串返回。
如果符号存储在调试器引擎已知的寄存器或内存位置中,则可以使用 WriteSymbol 更改其值。
如果符号包含其他 符号 ,则为父符号。 例如,结构包含其成员。 如果符号包含在另一个符号中,则符号是 子 符号。 符号可以是父符号和子符号。 每个符号组都有一个平面结构,并包含父符号及其子级。 每个符号都有 一个深度 -- 符号组中没有父级的符号的深度为零,每个子符号的深度比其父符号的深度大 1。 父符号的子级可能存在于符号组中,也可能不存在。 当子级存在于符号组中时,父符号称为 展开符号。 若要添加或删除符号组中符号的子级,请使用 ExpandSymbol。
符号组中的符号数由 GetNumberSymbols 返回。 符号组中符号的 索引 是一个标识号;索引范围从零到符号数减 1。 每次向符号组添加或删除符号时(例如,通过展开符号),符号组中所有符号的索引都可能会更改。
可以使用 GetSymbolParameters 找到符号参数,包括有关父子关系的信息。 此方法返回 DEBUG_SYMBOL_PARAMETERS 结构。
可以使用 OutputSymbols 方法将符号组中的符号打印到调试器的输出流中。
范围
当前范围或当前本地上下文确定调试器引擎公开的局部变量。 范围包含三个组件:
堆栈帧。
当前指令。
寄存器上下文。
如果堆栈帧位于调用堆栈的顶部,则当前指令是导致最后一个事件的指令。 否则,当前指令是导致下一个更高的堆栈帧的函数调用。
GetScope 和 SetScope 方法可用于获取和设置当前范围。 发生事件时,当前范围设置为事件的作用域。 可以使用 ResetScope 将当前范围重置为最后一个事件的范围。
线程上下文
线程上下文是 Windows 在切换线程时保留的状态。 这类似于寄存器上下文,只不过存在一些仅限内核的处理器状态,该状态是寄存器上下文的一部分,而不是线程上下文的一部分。 在内核模式调试期间,此额外状态可用作寄存器。
线程上下文由 ntddk.h 中定义的 CONTEXT 结构表示。 此结构依赖于平台,其解释取决于有效的处理器类型。 GetThreadContext 和 SetThreadContext 方法可用于获取和设置线程上下文。