美化打印让程序可通过函数调用以自己的方式呈现表达式值。如果在 print 命令、rprint 命令、 display 命令或 watch 命令中指定 -p 选项,则 dbx 会搜索格式为 const chars *db_pretty_print(const T *, int flags, const char *fmt) 的函数并调用它,从而替换返回值以便打印或显示。
以该函数的 flags 参数传递的值是按位操作值或以下所列之一:
FVERBOSE |
0x1 |
目前尚未实现,始终设置 |
FDYNAMIC |
0x2 |
-d |
FRECURSE |
0x4 |
-r |
FFORMAT |
0x8 |
-f (如果设置,fmt 是格式部分) |
FLITERAL |
0x10 |
-l |
db_pretty_print() 函数可以是静态成员函数,也可以是独立函数。
如果 dbx 环境变量 output_pretty_print 设置为 on,-p 会传递到 print 命令、 rprint 命令或 display 命令中作为缺省选项。可使用 +p 来覆盖此行为。
另外需要考虑以下各项:
在 7.6 版之前,美化打印基于 prettyprint 的 ksh 实现。虽然此 ksh 函数(及其预定义别名 pp)仍然存在, 大部分语义已在 dbx 重新实现,结果如下:
对于 IDE,可以对监视、局部变量和提示框求值应用美化打印。
在 print 命令、display 命令和 watch 命令中,-p 选项表示使用本地路由。
提高了可伸缩性,尤其是现在可频繁调用美化打印,特别是用于监视和局部变量的情况下。
可以更好地从表达式中得到地址。
具有更好的错误恢复功能。
一般来讲,对于 const/volatile 非限定类型,db_pretty_print(int *, ...() 和 db_pretty_print(const int *, ...())() 等函数视为不同函数。dbx 的重载解析方法是识别性但非强制性的:
识别性。如果定义了声明为 int 和 const int 的变量,各变量会传送到适当的函数中。
非强制性。如果只定义了一个 int 或 const int 变量,它们会传送到两种函数中。此行为不是特定于美化打印的,而是适用于任何调用。
以下情况下会调用美化打印函数:
执行 print -p 或当 dbx 环境变量 output_pretty_print 设置为 on 时。
执行 display -p 或当 dbx 环境变量 output_pretty_print 设置为 on 时。
执行 watch -p 或当 dbx 环境变量 output_pretty_print 设置为 on 时。
使用提示框求值,当 dbx 环境变量 output_pretty_print 设置为 on 时。
使用局部变量,当 dbx 环境变量 output_pretty_print 设置为 on 时。
以下情况下不会调用美化打印函数:
使用 $[]。原因是 $[] 专门用于脚本中,且需要是可以预测的。
执行 dump 命令。dump 与 where 命令使用相同的简化格式,可能会在将来转为使用美化打印。IDE 的 "Local Variables" 窗口不存在这一限制。
对于嵌套值,无法进行美化打印,因为 dbx 没有用于计算嵌套字段的地址的基础结构。
必须使用 -g 选项编译 db_pretty_print(),因为 dbx 需要能够访问参数签名。
允许 db_pretty_print() 函数返回 NULL。
传递给 db_pretty_print() 函数的主指针可以确保是非 NULL 的,但它仍可能指向初始化不当的对象。
缺省情况下,dbx 环境变量 output_pretty_print_fallback 设置为 on,这表示如果美化打印失败,dbx 将回退为采用常规格式。如果该环境变量设置为 off,则当美化打印失败时,dbx 将发出错误消息。
如果出现以下可检测并可恢复的情况之一,美化打印可能失败:
未找到美化打印函数。
无法获取要美化打印的表达式的地址,
函数调用未立即返回,这可能表示由于遇到错误对象时美化打印函数不够强健而导致出现段错误。它也可能表示遇到一个用户断点。
美化打印函数返回了 NULL。
美化打印函数返回了 dbx 无法间接使用的指针。
正在调试核心转储文件。
所有情况(函数调用未立即返回除外)下,上述失败都不会有任何提示,dbx 会回退为采用常规格式。但如果环境变量 output_pretty_print_fallback 设置为 off,当美化打印失败时,dbx 将发出错误消息。
但是,如果使用 print -p 命令,而不将 dbx 环境变量 output_pretty_print 设置为 on,dbx 会在中断的函数中停止,让您可以诊断失败的原因。然后可使用 pop-c 命令来清除此调用。
db_pretty_print() 函数需要通过其第一个参数的类型来消除岐义。在 C 中,可通过将函数写为静态文件来重载它们。