范围和符号组

符号组包含一组符号,用于作为一个组进行高效操作。 可以手动创建和填充符号组,也可以根据词法范围中的符号(例如局部变量和函数参数)自动生成和更新符号组。 接口 IDebugSymbolGroup 用于表示符号组。

有两种方法可以创建符号组。 CreateSymbolGroup 返回空符号组,当前词法范围的符号组由 GetScopeSymbolGroup 返回。

注意从当前范围生成的符号组是局部变量的快照。 如果目标中发生任何执行,符号可能不再准确。 此外,如果当前范围发生更改,符号组将不再表示 当前 作用域 (,因为它将继续表示) 为其创建的范围。

可以使用 AddSymbol 将符号添加到符号组,并使用 RemoveSymbolByIndexRemoveSymbolByName 删除符号。 方法 OutputAsType 告知调试器在处理符号的数据时使用不同的符号类型。

注意 作用域内符号的值可能不准确。 具体而言,计算机体系结构和编译器优化可能会阻止调试器准确确定符号的值。

符号条目信息是符号的说明,包括其位置和类型。 若要在模块中查找符号的此信息,请使用 IDebugSymbols3::GetSymbolEntryInformation。 若要查找符号组中某个符号的此信息,请使用 IDebugSymbolGroup2::GetSymbolEntryInformation。 有关符号输入信息的详细信息,请参阅 DEBUG_SYMBOL_ENTRY

以下方法返回有关符号组中的符号的信息:

如果符号存储在调试器引擎已知的寄存器或内存位置中,则可以使用 WriteSymbol 更改其值。

如果符号包含其他 符号 ,则为父符号。 例如,结构包含其成员。 如果符号包含在另一个符号中,则符号是 符号。 符号可以是父符号和子符号。 每个符号组都有一个平面结构,并包含父符号及其子级。 每个符号都有 一个深度 -- 符号组中没有父级的符号的深度为零,每个子符号的深度比其父符号的深度大 1。 父符号的子级可能存在于符号组中,也可能不存在。 当子级存在于符号组中时,父符号称为 展开符号。 若要添加或删除符号组中符号的子级,请使用 ExpandSymbol

符号组中的符号数由 GetNumberSymbols 返回。 符号组中符号的 索引 是一个标识号;索引范围从零到符号数减 1。 每次向符号组添加或删除符号时(例如,通过展开符号),符号组中所有符号的索引都可能会更改。

可以使用 GetSymbolParameters 找到符号参数,包括有关父子关系的信息。 此方法返回 DEBUG_SYMBOL_PARAMETERS 结构。

可以使用 OutputSymbols 方法将符号组中的符号打印到调试器的输出流中。

范围

当前范围当前本地上下文确定调试器引擎公开的局部变量。 范围包含三个组件:

  1. 堆栈帧。

  2. 当前指令。

  3. 寄存器上下文。

如果堆栈帧位于调用堆栈的顶部,则当前指令是导致最后一个事件的指令。 否则,当前指令是导致下一个更高的堆栈帧的函数调用。

GetScopeSetScope 方法可用于获取和设置当前范围。 发生事件时,当前范围设置为事件的作用域。 可以使用 ResetScope 将当前范围重置为最后一个事件的范围。

线程上下文

线程上下文是 Windows 在切换线程时保留的状态。 这类似于寄存器上下文,只不过存在一些仅限内核的处理器状态,该状态是寄存器上下文的一部分,而不是线程上下文的一部分。 在内核模式调试期间,此额外状态可用作寄存器。

线程上下文由 ntddk.h 中定义的 CONTEXT 结构表示。 此结构依赖于平台,其解释取决于有效的处理器类型。 GetThreadContextSetThreadContext 方法可用于获取和设置线程上下文。