Speculation Example
One potential use for speculations is to highlight a particular code path. The following example shows the entire code path under the open
() system call only when open
() fails:
Example 7-1 Showing Code Flow for Failed open
() Calls
#!/usr/sbin/dtrace -Fs syscall::openat:entry, syscall::openat64:entry { /* * The call to speculation() creates a new speculation. If this fails, * dtrace(8) 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 data buffer if the * speculation is subsequently committed. */ printf("%s", stringof(copyinstr(arg1))); } fbt::: /self->spec/ { /* * A speculate() with no other actions speculates the default action: * tracing the EPID. */ speculate(self->spec); } syscall::openat:return, syscall::openat64:return /self->spec/ { /* * To balance the output with the -F option, make sure that * every entry has a matching return. Because the open entry was * speculated, you must also speculate the open return. * This is also a convenient time to trace the errno value. */ speculate(self->spec); trace(errno); } syscall::openat:return, syscall::openat64:return /self->spec && errno != 0/ { /* * If errno is non-zero, commit the speculation. */ commit(self->spec); self->spec = 0; } syscall::openat:return, syscall::openat64:return /self->spec && errno == 0/ { /* * If errno is not set, discard the speculation. */ discard(self->spec); self->spec = 0; }
Running the preceding script produces output similar to the following example:
# ./specopen.d
dtrace: script './specopen.d' matched 24282 probes
CPU FUNCTION
1 => open /var/ld/ld.config
1 -> open
1 -> copen
1 -> falloc
1 -> ufalloc
1 -> fd_find
1 -> mutex_owned
1 <- mutex_owned
1 <- fd_find
1 -> fd_reserve
1 -> mutex_owned
1 <- mutex_owned
1 -> mutex_owned
1 <- mutex_owned
1 <- fd_reserve
1 <- ufalloc
1 -> kmem_cache_alloc
1 -> kmem_cache_alloc_debug
1 -> verify_and_copy_pattern
1 <- verify_and_copy_pattern
1 -> file_cache_constructor
1 -> mutex_init
1 <- mutex_init
1 <- file_cache_constructor
1 -> tsc_gethrtime
1 <- tsc_gethrtime
1 -> getpcstack
1 <- getpcstack
1 -> kmem_log_enter
1 <- kmem_log_enter
1 <- kmem_cache_alloc_debug
1 <- kmem_cache_alloc
1 -> crhold
1 <- crhold
1 <- falloc
1 -> vn_openat
1 -> lookupnameat
1 -> copyinstr
1 <- copyinstr
1 -> lookuppnat
1 -> lookuppnvp
1 -> pn_fixslash
1 <- pn_fixslash
1 -> pn_getcomponent
1 <- pn_getcomponent
1 -> ufs_lookup
1 -> dnlc_lookup
1 -> bcmp
1 <- bcmp
1 <- dnlc_lookup
1 -> ufs_iaccess
1 -> crgetuid
1 <- crgetuid
1 -> groupmember
1 -> supgroupmember
1 <- supgroupmember
1 <- groupmember
1 <- ufs_iaccess
1 <- ufs_lookup
1 -> vn_rele
1 <- vn_rele
1 -> pn_getcomponent
1 <- pn_getcomponent
1 -> ufs_lookup
1 -> dnlc_lookup
1 -> bcmp
1 <- bcmp
1 <- dnlc_lookup
1 -> ufs_iaccess
1 -> crgetuid
1 <- crgetuid
1 <- ufs_iaccess
1 <- ufs_lookup
1 -> vn_rele
1 <- vn_rele
1 -> pn_getcomponent
1 <- pn_getcomponent
1 -> ufs_lookup
1 -> dnlc_lookup
1 -> bcmp
1 <- bcmp
1 <- dnlc_lookup
1 -> ufs_iaccess
1 -> crgetuid
1 <- crgetuid
1 <- ufs_iaccess
1 -> vn_rele
1 <- vn_rele
1 <- ufs_lookup
1 -> vn_rele
1 <- vn_rele
1 <- lookuppnvp
1 <- lookuppnat
1 <- lookupnameat
1 <- vn_openat
1 -> setf
1 -> fd_reserve
1 -> mutex_owned
1 <- mutex_owned
1 -> mutex_owned
1 <- mutex_owned
1 <- fd_reserve
1 -> cv_broadcast
1 <- cv_broadcast
1 <- setf
1 -> unfalloc
1 -> mutex_owned
1 <- mutex_owned
1 -> crfree
1 <- crfree
1 -> kmem_cache_free
1 -> kmem_cache_free_debug
1 -> kmem_log_enter
1 <- kmem_log_enter
1 -> tsc_gethrtime
1 <- tsc_gethrtime
1 -> getpcstack
1 <- getpcstack
1 -> kmem_log_enter
1 <- kmem_log_enter
1 -> file_cache_destructor
1 -> mutex_destroy
1 <- mutex_destroy
1 <- file_cache_destructor
1 -> copy_pattern
1 <- copy_pattern
1 <- kmem_cache_free_debug
1 <- kmem_cache_free
1 <- unfalloc
1 -> set_errno
1 <- set_errno
1 <- copen
1 <- open
1 <= open 2
For more information, see the open
(2) man page.