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