Sola
1第1 章
13
查找特定线程分配的所有内存
列显内核STREAM 的直观图
确定特定地址所引用的结构类型
在内核中查找已泄漏的内存块
分析内存以查找栈跟踪
使用高级编程API 实现自己的调试器命令和分析工具,而不必重新编译或修改调试器本
身:在MDB中,调试支持的实现形式为一组可装入模块(调试器可以dlopen(3C) 的共
享库),其中每个可装入模块都提供一组扩展调试器本身功能的命令。相应地,调试器
提供核心服务的API,例如读写内存和访问符号表信息的功能。MDB为开发者提供一个
用于针对其自身的驱动程序和模块实现调试支持的框架;然后使这些模块可供所有人使
用。
了解如何使用MDB(如果您已熟悉传统的调试工具adb 和crash):MDB为这些现有
调试解决方案提供向后兼容性。MDB语言本身是adb 语言的超集;所有现有adb 宏和命
令都在MDB内工作,因此使用adb 的开发者可以立即使用MDB,而无需了解任何MDB
特定的命令。MDB还提供了功能比crash 实用程序更强大的命令。
增强的可用性功能可带来许多益处。MDB提供了许多可用性功能,其中包括:
命令行编辑
命令历史记录
内置输出页面调度程序
语法错误检查和处理
联机帮助
交互式会话日志记录
使用MDB
在Solaris 系统中,以共享通用功能的两个命令提供MDB:mdb 和kmdb。可以使用mdb 命令
以交互方式或在脚本中调试实时用户进程、用户进程核心转储文件、内核崩溃转储、实时
操作系统、目标文件和其他文件。在还需要控制和停止内核执行时,可以使用kmdb 命令调
试实时操作系统内核和设备驱动程序。要启动mdb,请执行mdb(1) 命令。要启动kmdb,请引
导系统(如kmdb(1) 手册页中所述)或执行带-K 选项的mdb 命令。
未来的增强功能
MDB为开发高级事后分析工具打下了稳定的基础。每个Solaris 操作系统发行版都包括提供
更复杂功能的附加MDB模块,用于调试内核和其他软件程序。可以使用MDB调试现有的
软件程序,以及开发自定义的模块以提高调试自己的Solaris 驱动程序和应用程序的能力。
使用MDB
14 Solaris 模块调试器指南• 2006 年11 月
调试器概念
本节讨论MDB设计的重要方面,以及此体系结构带来的益处。
生成块
目标是指调试器正在检查的程序。目前MDB提供了对以下目标类型的支持:
用户进程
用户进程核心转储文件
没有内核执行控制的实时操作系统(通过/dev/kmem 和/dev/ksyms)
具有内核执行控制的实时操作系统(通过kmdb(1))
操作系统崩溃转储
在操作系统崩溃转储内记录的用户进程映像
ELF 目标文件
原始数据文件
每个目标都导出标准属性集,包括一个或多个地址空间、一个或多个符号表、一组装入对
象和一组线程。图2–1 概述了MDB体系结构,包括两个内置目标和一对样例模块。
在MDB术语中,调试器命令又名dcmd(读作dee-command),是调试器中能够访问当前
目标的任何属性的例程。MDB解析标准输入中的命令,然后执行对应的dcmd。每个dcmd
还可以接受字符串或数值参数的列表,如第19 页中的“语法”所示。MDB包含一组始终
可用的内置dcmd(在第5 章中介绍)。通过使用MDB附带的编程API 编写dcmd,程序员
还可以扩展MDB本身的功能。
walker 是说明如何遍历或迭代特定程序数据结构的元素的一组例程。walker 从dcmd 和从
MDB本身封装数据结构的实现。可以交互使用walker,或者将它们用作元语以生成其他
dcmd 或walker。与使用dcmd 一样,程序员可以通过将其他walker 作为调试器模块的一部
分进行实现来扩展MDB。
调试器模块又名dmod(读作dee-mod),是包含一组dcmd 和walker 的动态装入的库。在
初始化过程中,MDB尝试装入与目标中存在的装入对象对应的dmod。随后可以在运行
MDB时随时装入或卸载dmod。MDB提供了一组标准dmod,用于调试Solaris 内核。
2第2 章
15
宏文件是包含一组要执行的命令的文本文件。宏文件通常用于自动执行显示简单数据结构
的过程。MDB提供了完全的向后兼容性以执行为adb 编写的宏文件。因此,Solaris 安装附
带的一组宏文件可以与任一工具一起使用。
图2–1MDB体系结构
模块化
MDB的模块化体系结构的优点不仅仅是能够装入包含其他调试器命令的模块。MDB体系
结构各层之间定义了清晰的接口边界(如图2–1 所示)。宏文件执行以MDB或adb 语言编
写的命令。调试器模块中的Dcmd 和walker 是使用MDB模块API 编写的,这为允许调试器
及其模块独立发展的应用程序二进制接口奠定了基础。
walker 和dcmd 的MDB名称空间还在调试代码(随着目标程序本身的发展,最大限度地实
现代码共享并限制必须修改的代码量)之间定义第二组层。例如,Solaris 内核中的主要数
据结构之一是表示系统中活动进程的proc_t 结构的列表。::ps dcmd 必须迭代此列表才能
生成其输出。但是,用于迭代该列表的代码不在::ps dcmd 中,而是封装在genunix 模块的
proc walker 中。
MDB同时提供了::ps 和::ptree dcmd,但是这两者都不知道如何在内核中访问proc_t 结
构。相反,它们以程序方式调用proc walker,并相应地格式化返回的结构集。如果用于
proc_t 结构的数据结构发生更改,则MDB可以提供新的proc walker,而且相关的dcmd 都
不需要更改。还可以使用::walk dcmd 以交互方式访问proc walker,以便在调试会话中工
作时创建新的命令。
模块化
16 Solaris 模块调试器指南• 2006 年11 月
除了便于分层和代码共享外,MDB模块API 还提供了具有单一稳定接口的dcmd 和
walker,以访问基础目标的各种属性。使用同一API 函数访问用户进程或内核目标中的信
息,简化了开发新调试工具的任务。
此外,可以使用自定义MDB模块在各种上下文中执行调试任务。例如,您也许希望为正在
开发的用户程序开发一个MDB模块。开发模块后,当MDB检查执行该程序的实时进程、
该程序的核心转储、甚至是在执行该程序的系统上所取得的内核崩溃转储时,就可以使用
此模块。
模块API 提供了用于访问以下目标属性的工具:
地址空间模块API 提供了用于从目标的虚拟地址空间读取和写入数据
的工具。还为内核调试模块提供了使用物理地址读取和写
入的功能。
符号表模块API 提供了对目标主要可执行文件的静态和动态符号
表、其运行时链接编辑器和一组装入对象(用户进程中的共
享库或Solaris 内核中的可装入模块)的访问。
外部数据模块API 提供了用于检索与目标关联的指定外部数据缓冲区
集合的工具。例如,MDB提供了对与用户进程或用户核心
转储文件目标关联的proc(4) 结构的程序访问。
此外,可以使用内置MDBdcmd 访问有关目标内存映射、装入对象、寄存器值的信息以及
控制用户进程目标的执行。
模块化