printa() 函数用于格式化 D 程序中聚合的结果。可通过下列两种形式之一来调用该函数:
printa(@aggregation-name); printa(format-string, @aggregation-name);
如果使用函数的第一种形式,则 dtrace(1M) 命令将提取聚合数据的一致快照并生成输出,该输出与用于聚合的缺省输出格式等效,如第 9 章中所述。
如果使用函数的第二种形式,则 dtrace(1M) 命令将提取聚合数据的一致快照,并根据 format string 中指定的转换以及下列规则来生成输出:
格式转换必须与用于创建聚合的元组签名相匹配。每个元组元素仅能显示一次。例如,如果使用下列 D 语句来聚合计数:
@a["hello", 123] = count(); @a["goodbye", 456] = count();
然后将 D 语句 printa(format-string, @a) 添加到探测器子句,则 dtrace 将提取聚合数据的快照并生成输出,就像输入了下列语句:
printf(format-string, "hello", 123); printf(format-string, "goodbye", 456);
及类似语句一样(对于聚合中定义的每个元组)。
与 printf() 不同,用于 printa() 的格式字符串无需包括元组的所有元素。即,元组的长度可以为 3,并且仅进行一次格式转换。因此,可以通过更改聚合声明将要在 printa() 输出中省略的任何元组键移到元组的结尾来将其省略,然后在 printa() 格式字符串中省略其对应的转换说明符。
可通过使用附加的 @ 格式标志字符(仅在用于 printa() 时有效)将聚合结果包括在输出中。@ 标志可与任何相应的格式转换说明符组合,并且可在一个格式字符串中多次显示,以便元组结果可在输出中的任何位置多次显示。可用于聚合函数的一组转换说明符隐含在聚合函数的结果类型中。聚合结果类型包括:
avg() |
uint64_t |
count() |
uint64_t |
lquantize() |
int64_t |
max() |
uint64_t |
min() |
uint64_t |
quantize() |
int64_t |
sum() |
uint64_t |
例如,要格式化 avg() 的结果,可应用 %d、%i、%o、%u 或 %x 格式转换。quantize() 和 lquantize() 函数会将其结果格式化为 ASCII 表而不是单个值。
以下 D 程序显示 printa() 的完整示例,通过使用 profile 提供器来对 caller 的值进行采样,然后将结果格式化为简单的表:
profile:::profile-997 { @a[caller] = count(); } END { printa("%@8u %a\n", @a); }
如果使用 dtrace 来执行此程序,请等待几秒钟,然后按 Ctrl-C 组合键,将会看到与以下示例类似的输出:
# dtrace -s printa.d ^C CPU ID FUNCTION:NAME 1 2 :END 1 0x1 1 ohci`ohci_handle_root_hub_status_change+0x148 1 specfs`spec_write+0xe0 1 0xff14f950 1 genunix`cyclic_softint+0x588 1 0xfef2280c 1 genunix`getf+0xdc 1 ufs`ufs_icheck+0x50 1 genunix`infpollinfo+0x80 1 genunix`kmem_log_enter+0x1e8 ... |