speculation
Creates a speculative trace buffer and returns its ID.
int speculation(void)
The speculation
function reserves a speculative trace buffer for use with
speculate
and
returns an identifier for this buffer.
Example 7-45 How to use speculation
The following example illustrates how to use speculation. All speculation functions must be used together for speculation to work correctly.
The speculation is created for the syscall::open:entry
probe and the ID
for the speculation is attached to a thread-local variable. The first argument of the
open()
system call is traced to the speculation buffer by using the
printf
function.
Three more clauses are included for the syscall::open:return
probe. In the
first of these clauses, the errno
is traced to the speculative buffer. The
predicate for the second of the clauses filters for a non-zero errno
value
and commits the speculation buffer. The predicate of the third of the clauses filters for a
zero errno
value and discards the speculation buffer.
The output of the program is returned for the primary data buffer, so the program
effectively returns the file name and error number when an open()
system
call fails. If the call doesn't fail, the information that was traced into the speculation
buffer is discarded.
syscall::open:entry
{
/*
* The call to speculation() creates a new speculation. If this fails,
* dtrace will generate an error message indicating the reason for
* the failed speculation(), but subsequent speculative tracing will be
* silently discarded.
*/
self->spec = speculation();
speculate(self->spec);
/*
* Because this printf() follows the speculate(), it is being
* speculatively traced; it will only appear in the primary data buffer if the
* speculation is subsequently committed.
*/
printf("%s", copyinstr(arg0));
}
syscall::open:return
/self->spec/
{
/*
* Trace the errno value into the speculation buffer.
*/
speculate(self->spec);
trace(errno);
}
syscall::open:return
/self->spec && errno != 0/
{
/*
* If errno is non-zero, commit the speculation.
*/
commit(self->spec);
self->spec = 0;
}
syscall::open:return
/self->spec && errno == 0/
{
/*
* If errno is not set, discard the speculation.
*/
discard(self->spec);
self->spec = 0;
}