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