利用美化输出功能,程序可通过函数调用以自己的方式呈现表达式的值。dbx 支持两种美化输出机制:基于调用的美化输出和基于过滤器的美化输出。早期基于调用的机制的工作原理是调用调试对象中定义的符合特定模式的函数。当前版本的 dbx 现在支持基于 Python 的过滤器,从而允许用户创建可将值从一种形式转换为另一种形式的过滤器。
dbx 将确定哪个机制结合使用 dbxenv 变量 output_pretty_print_mode。如果设置为 call,则将寻找基于调用的美化输出器。如果设置为 filter,则将寻找基于 Python 的美化输出器。如果设置为 filter_unless_call,则优先采用基于调用的美化输出器,而不是过滤器。
如果将 –p 选项指定为 print 命令、rprint 命令、display 命令或 watch 命令,则调用美化输出器(无论它属于何种类型)。有关调用美化输出器的更多信息,请参见调用美化输出。
如果将 dbxenv 变量 output_pretty_print 设置为 on,则 –p 将作为缺省值传递给 print 命令、rprint 命令或 display 命令。可使用 +p 来覆盖此行为。此外,output_pretty_print 控制 IDE 局部变量、气球表达式求值和监视的美化输出。
以下情况下会调用美化输出函数:
执行 print –p 或当 dbxenv 变量 output_pretty_print 设置为 on 时。
执行 display –p 或当 dbxenv 变量 output_pretty_print 设置为 on 时。
执行 watch –p 或当 dbxenv 变量 output_pretty_print 设置为 on 时。
使用气球表达式求值,当 dbxenv 变量 output_pretty_print 设置为 on 时。
使用局部变量,当 dbxenv 变量 output_pretty_print 设置为 on 时。
以下情况下不会调用美化输出函数:
$[]. $[] 专门用于脚本中,因此脚本应当是可以预测的。
执行 dump 命令。dump 与 where 命令使用相同的简化格式,可能会在未来的版本中转为使用美化输出。IDE 的 "Local Variables"(局部变量)窗口不存在这一限制。
利用基于调用的美化输出功能,应用程序可通过函数调用以自己的方式呈现表达式值。如果在 print 命令、rprint 命令、 display 命令或 watch 命令中指定 –p 选项,则 dbx 会搜索格式为 const chars *db_pretty_print(const T *, int flags, const char *fmt) 的函数并调用它,从而替换 print 或 display 的返回值。
以该函数的 flags 参数传递的值是按位操作值或以下所列之一:
|
db_pretty_print() 函数可以是静态成员函数,也可以是独立函数。
美化输出时,还要考虑以下信息:
在 dbx 8.0 版本之前,美化输出基于 prettyprint 的 ksh 实现。虽然此 ksh 函数(及其预定义别名 pp)仍然存在, 但大部分语义已在 dbx 重新实现,结果如下:
对于 IDE,可以对监视、局部变量和气球表达式求值使用美化输出。
在 print 命令、display 命令和 watch 命令中,–p 选项表示使用本地路由。
提高了可伸缩性,尤其是现在可频繁调用美化输出,特别是用于监视和局部变量的情况下。
可以更好地从表达式中得到地址。
具有更好的错误恢复功能。
对于嵌套值,无法进行美化输出,因为 dbx 没有用于计算嵌套字段的地址的基础结构。
缺省情况下,dbxenv 变量 output_pretty_print_fallback 设置为 on,这表示如果美化输出失败,dbx 将回退为采用常规格式。如果在该环境变量设置为 off 的情况下美化输出失败,dbx 将仍发出错误消息。
使用美化输出函数时,您需考虑以下内容:
一般来讲,对于 const/volatile 非限定类型,db_pretty_print(int *, ...()) 和 db_pretty_print(const int *, ...)() 等函数视为不同函数。dbx 的重载解析方法是识别性但非强制性的:
识别性-如果定义了声明为 int 和 const int 的变量,各变量会传送到适当的函数中。
非强制性-如果只定义了一个 int 或 const int 变量,它们会传送到两种函数中。此行为不是特定于美化输出的,而是适用于任何调用。
必须使用 –g 选项编译 db_pretty_print() 函数,因为 dbx 需要能够访问参数签名。
允许 db_pretty_print() 函数返回 NULL。
传递给 db_pretty_print() 函数的主指针可以确保是非 NULL 的,但它仍可能指向初始化不当的对象。
db_pretty_print() 函数需要通过其第一个参数的类型来消除岐义。在 C 中,可通过将函数写为静态文件来重载它们。
如果出现以下可检测并可恢复的情况之一,美化输出可能失败:
未找到美化输出函数。
无法获取要美化输出的表达式的地址。
函数调用未立即返回,这可能表示由于遇到错误对象时美化输出函数不够强健而导致出现段错误。它也可能表示遇到一个用户断点。
美化输出函数返回了 NULL。
美化输出函数返回了 dbx 无法间接使用的指针。
正在调试信息转储文件。
所有情况(函数调用未立即返回除外)下,这些失败都不会有任何提示,dbx 会回退为采用常规格式。但是,如果该 output_pretty_print_fallback dbxenv 变量设置为 off,则当美化输出失败时,dbx 将发出错误消息。
如果您使用 print –p 命令,而没有将 dbxenv 变量 output_pretty_print 设置为 on,则 dbx 会在中断的函数中停止,允许您诊断故障的原因。然后可使用 pop–c 命令来清除此调用。
利用美化输出过滤器功能,您可以通过 Python 编写过滤器,这些过滤器可将值从一种形式转换为另一种形式。基于 Python 的美化输出器仅在 Oracle Solaris 中可用。
系统已内置过滤器,用于在 C++ 标准模板库的 4 种实现中选择类。下表指定了库名和该库的编译器选项:
|
下表说明了美化输出过滤器在 C++ 标准模板库中可用于哪些类以及是否可以输出索引和分片:
|
以下是一个在 dbx 中使用 print 命令时输出列表的输出示例:
(dbx) dbxenv output_pretty_print off (dbx) print list10 list10 = { __buffer-size = 32U __buffer-list = { __data_ = 0x654a8 } __free-list = (nil) __next-avail = 0x67334 __last = 0x67448 __node = 0x48830 __length = 10U }
以下是与 dbx 中输出的列表相同的列表,但该列表使用的是美化输出过滤器:
(dbx) print -p list10 list10 = (200, 201, 202, 203, 204, 205, 206, 207, 208, 209) (dbx) print -p list10[5] list10[5] = 205 (dbx) print -p list10[1..100:2] list10[1..100:2] = [1] = 202 [3] = 204 [5] = 206 [7] = 208
Python 美化输出过滤器和 python 命令仅在 Oracle Solaris 中可用。要启动内置的 Python 解释程序,请键入 python。要对 Python 代码求值,请键入 python python-code。新生的 Python 插件 API 可用。但是,其主要用途是编写可以作为回调调用的美化输出器过滤器。因此 python 命令主要用于测试和诊断用途。
要生成 Python 美化输出 API 文档,请使用 python-docs 命令。该命令仅在 Oracle Solaris 上可用。