要使用推理,必须在执行任何数据记录操作之前,将从 speculation() 返回的标识符传递到子句中的 speculate() 函数。包含 speculate() 的子句中所有后续数据记录操作将被推理跟踪。如果在 D 探测子句中对 speculate() 的调用紧跟在数据记录操作之后,D 编译器将会生成编译时错误。因此,子句可以包含推理跟踪请求或非推理跟踪请求,但不能同时包含二者。
不能对聚集操作、破坏性操作和 exit 操作进行推理跟踪。在包含 speculate() 的子句中采用这其中某个操作的任何尝试,都将导致编译时错误。一个 speculate() 不能跟在另一个 speculate() 之后:每条子句中只允许使用一个推理。只包含一个 speculate() 的子句将推理性地跟踪缺省操作,该缺省操作被定义为仅跟踪已经启用的探测器 ID。有关缺省操作的说明,请参见第 10 章。
通常,将 speculation() 的结果赋给线程局部变量,然后使用该变量作为其他探测器的后续谓词以及 speculate() 的参数。例如:
syscall::open:entry { self->spec = speculation(); } syscall::: /self->spec/ { speculate(self->spec); printf("this is speculative"); }