本主题介绍在 JavaScript 扩展中使用本机调试器对象的设计和测试注意事项。
本机调试器对象表示调试器环境的各种构造和行为。 可以将对象传递到 JavaScript 扩展中或在其中获取,以操控调试器的状态。
有关调试器对象 JavaScript 扩展的信息,请参阅 JavaScript 扩展中的本机调试器对象。
有关使用 JavaScript 的一般信息,请参阅 JavaScript 调试器脚本。
调试器数据模型设计注意事项
设计原理
请考虑以下原则,使调试器扩展提供可发现、可查询和可编写脚本的信息。
- 信息接近其所需的地方。 例如,应将有关注册表项的信息显示为包含注册表项句柄的局部变量的一部分。
- 信息是结构化的。 例如,有关注册表项的信息显示在单独的字段中,例如密钥类型、密钥 ACL、密钥名称和值。 这意味着无需分析文本即可访问各个字段。
- 信息是一致的。 信息关于注册表项句柄的呈现方式尽可能与文件句柄信息的呈现方式相似。
避免这些不支持这些原则的方法。
- 不要将你的物品结构成一个扁平化的“集杂箱”。 组织层次结构允许用户浏览他们查找的信息,而无需事先了解要查找的内容并支持可发现性。
- 不要通过将经典 dbgeng 扩展移动到模型,同时仍输出原始文本的屏幕来转换经典 dbgeng 扩展。 这不能与其他扩展组合,并且不能使用 LINQ 表达式进行查询。 而是将数据拆分为单独的可查询字段。
命名准则
- 字段的大写应为 PascalCase。 对于在不同大小写形式中广为人知的名称,例如 jQuery,可以考虑例外。
- 避免使用通常不会在C++标识符中使用的特殊字符。 例如,避免使用名称(如“Total Length”(包含空格)或“[size]”(包含方括号)。 该约定使得在脚本语言中更容易使用,因为这些语言不允许这些字符作为标识符的一部分,同时也让命令窗口的使用变得更加轻松。
组织和层次结构准则
- 不要扩展调试器命名空间的顶层。 相反,应扩展调试器中的现有节点,以便显示信息最相关的位置。
- 不要重复概念。 如果要创建一个数据模型扩展,其中列出了调试器中已存在的概念的其他信息,请扩展现有信息,而不是尝试将其替换为新信息。 换句话说,显示有关模块的详细信息的扩展应扩展现有 Module 对象,而不是创建新的模块列表。
- 免费浮动实用工具命令必须是 Debugger.Utility 命名空间的一部分。 它们还应正确设置子命名空间(例如 Debugger.Utility.Collections.FromListEntry)
向后兼容性和破坏性变更
发布的脚本不应破坏与其他依赖于它的脚本的兼容性。 例如,如果函数发布到模型,则它应始终位于同一位置,并尽可能使用相同的参数。
不使用外部资源
- 扩展不得生成外部进程。 外部进程可能会干扰调试器的行为,并且会在各种远程调试器方案中(例如 dbgsrv remotes、ntsd remotes 和“ntsd -d remotes”)中出现错误行为。
- 扩展不得显示任何用户界面。 显示用户界面元素在远程调试方案中的行为不正确,并可能会中断控制台调试方案。
- 扩展不能通过未公开的方法操控调试器引擎或调试器 UI。 这会导致兼容性问题,并且在具有不同用户界面的调试器客户端上表现不正确。
- 扩展只能通过记录的调试器 API 访问目标信息。 对于许多远程方案,尝试通过 win32 API 访问有关目标的信息将失败,甚至某些跨安全边界的本地调试方案也会失败。
不使用 Dbgeng 特定功能
用于作为扩展的脚本应尽可能避免依赖 dbgeng 特定功能(例如执行“经典”调试器扩展)。 脚本应在承载数据模型的任何调试器之上可用。
测试调试器扩展
扩展应适用于各种场景。 虽然某些扩展可能特定于某个方案(例如内核调试方案),但大多数扩展应适用于所有方案,或者具有指示受支持方案的元数据。
内核模式
- 实时内核调试
- 内核转储调试
用户模式
- 实时用户模式调试
- 用户模式转储调试
此外,请考虑这些调试器使用方案
- 多进程调试
- 多会话调试(例如转储 + 单个会话中的实时用户)
远程调试器使用情况
测试远程调试器的使用场景以确保正确操作。
- dbgsrv远程调试组件
- ntsd 远程工具
- ntsd -d 远程控制
有关详细信息,请参阅 使用 CDB 和 NTSD调试并激活进程服务器。
回归测试
研究如何使用测试自动化来验证扩展的功能,以便在调试器的新版本发布时确保其有效性。