DTrace 谓词用于过滤实验中不需要的数据,具体方法是仅跟踪指定的条件为 true 时的数据。启用许多探测器时,通常可使用标识特定线程或所关注线程(如 /self->traceme/ 或 /pid == 12345/)形式的谓词。尽管对于多数探测器中的多数线程而言,许多谓词的计算结果为 false 值,但对成千上万个探测器进行这样的计算时,计算本身的开销也可能变得很大。为了降低此开销,如果谓词仅包含线程局部变量(例如,/self->traceme/)或不变变量(例如,/pid == 12345/),DTrace 将对谓词计算进行高速缓存。计算已高速缓存的谓词的开销要远远小于计算未高速缓存的谓词的开销,在谓词包含线程局部变量、字符串比较或其他开销相对较大的操作时,尤其如此。虽然谓词高速缓存对于用户是透明的,但它隐含了一些构造最优谓词的原则,如下表所示:
可高速缓存 |
不可高速缓存 |
---|---|
self->mumble |
mumble[curthread], mumble[pid, tid] |
execname |
curpsinfo->pr_fname, curthread->t_procp->p_user.u_comm |
pid |
curpsinfo->pr_pid, curthread->t_procp->p_pipd->pid_id |
tid |
curlwpsinfo->pr_lwpid, curthread->t_tid |
curthread |
curthread->any member, curlwpsinfo->any member, curpsinfo->any member |
建议您不要使用以下示例:
syscall::read:entry { follow[pid, tid] = 1; } fbt::: /follow[pid, tid]/ {} syscall::read:return /follow[pid, tid]/ { follow[pid, tid] = 0; }
首选使用线程局部变量的以下示例:
syscall::read:entry { self->follow = 1; } fbt::: /self->follow/ {} syscall::read:return /self->follow/ { self->follow = 0; }
为进行高速缓存,谓词必须完全由可高速缓存的表达式组成。以下谓词均可进行高速缓存:
/execname == "myprogram"/ /execname == $$1/ /pid == 12345/ /pid == $1/ /self->traceme == 1/
以下示例使用了全局变量,因而无法高速缓存:
/execname == one_to_watch/ /traceme[execname]/ /pid == pid_i_care_about/ /self->traceme == my_global/