Strings

Strings in dynamic tracing languages are wrappers around C-style null-terminated char* string, but they behave differently. In SystemTap it is simple alias, while DTrace add extra limitations, for example, you can't access single character to a string. String operations are listed in following table:

Operation DTrace SystemTap
Get kernel string stringof ( expr ) or (string) expr kernel_string*()
Convert a scalar type to a string sprint() and sprintf()
Get userspace string copyinstr() user_string*()
Compare strings ==, !=, >, >=, <, <= –- semantically equivalent to strcmp
Concatenate two strings strjoin(str1, str2) str1 . str2
Get string length strlen(str)
Check if substring is in string strstr(haystack, needle) isinstr(haystack, needle)

Note that this operations may be used in DTrace predicates, for example:

syscall::write:entry
/strstr(execname, "sh") != 0/ 
{}

References

Structures

Many subsystems in Linux and Solaris have to represent their data as C structures. For example, path to file corresponds from file-related structure dentry and filesystem-related structure vfsmnt:

struct path {
    struct vfsmount *mnt;
    struct dentry *dentry;
};

Structure fields are accessed same way it is done in C: in DTrace depending on what you are getting you need to use -> for pointers and . for structures. In SystemTap you should always use -> which will be contextually converted to . where needed. Information about structures is read from CTF sections in Solaris and DWARF sections in Linux, including field names. To get C structure you may need to cast a generic pointer (void* in most cases) to a needed structures. In DTrace it is done using C-style syntax:

(struct vnode *)((vfs_t *)this->vfsp)->vfs_vnodecovered

Conversion in SystemTap is used more often, because in many places, typed pointers are coerced to generic long type. It is performed with @cast expression which accepts address, name of structure as string (struct keyword is optional), and an optional third parameter which contains name of include file, for example:

function get_netdev_name:string (addr:long) {
    return kernel_string(@cast(addr, "net_device")->name)
}

References