1

I have simple ST script which counts process io size per file:

global fds, counts

probe syscall.open.return {
        if ( ( pid() == target() ) & ( $return != -1 ) ) {
                printf("%s opened as %d\n", user_string($filename), $return)
                fds[$return] = user_string($filename)
        }
}

probe syscall.read.return, syscall.write.return {
        if ( (pid() == target()) & ($return > 0) ) {
                counts[fds[$fd]] += $return
        }
}

probe end {
        foreach (fname in counts+) {
                count = counts[fname]
                if ( count > 1024) {
                        count = count / 1024
                        bs = "Kb"
                } else {
                        bs = "B"
                }
                printf("%s: %d %s\n", fname, count, bs)
        }
}

When i run stap test.stp -c 'cat test.stp' i get:

global fds, counts

probe syscall.open.return {
    if ( ( pid() == target() ) & ( $return != -1 ) ) {
        printf("%s opened as %d\n", user_string($filename), $return)
        fds[$return] = user_string($filename)
    }
}

probe syscall.read.return, syscall.write.return {
    if ( (pid() == target()) & ($return > 0) ) {
        counts[fds[$fd]] += $return
    }
}

probe end {
    foreach (fname in counts+) {
        count = counts[fname]
        if ( count > 1024) {
            count = count / 1024
            bs = "Kb"
        } else {
            bs = "B"
        }
        printf("%s: %d %s\n", fname, count, bs)
    }
}
/etc/ld.so.cache opened as 3
/lib64/libc.so.6 opened as 3
/usr/lib/locale/locale-archive opened as 3
test.stp opened as 3
test.stp: 541 B
: 541 B
/lib64/libc.so.6: 832 B

This is almost correct. But when i execute stap test.stp -c 'cat test.stp > /dev/null' i get something strange:

/etc/ld.so.cache opened as 3
/lib64/libtinfo.so.5 opened as 3
/lib64/libdl.so.2 opened as 3
/lib64/libc.so.6 opened as 3
/dev/tty opened as 3
/usr/lib/locale/locale-archive opened as 3
/proc/meminfo opened as 3
/usr/lib64/gconv/gconv-modules.cache opened as 3
/lib64/libtinfo.so.5: 832 B
/lib64/libdl.so.2: 832 B
/lib64/libc.so.6: 832 B
/proc/meminfo: 1024 B

Why do i not see test.stp opened as 3 in second case?

I do some test with strace:

1) strace -e open -o trace cat test.stp:

open("/home/al/lib/tls/x86_64/libc.so.6", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
open("/home/al/lib/tls/libc.so.6", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
open("/home/al/lib/x86_64/libc.so.6", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
open("/home/al/lib/libc.so.6", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
open("/lib64/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
open("/usr/lib/locale/locale-archive", O_RDONLY|O_CLOEXEC) = 3
open("test.stp", O_RDONLY)              = 3
+++ exited with 0 +++

2) strace -e open -o trace cat test.stp > /dev/null:

open("/home/al/lib/tls/x86_64/libc.so.6", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
open("/home/al/lib/tls/libc.so.6", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
open("/home/al/lib/x86_64/libc.so.6", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
open("/home/al/lib/libc.so.6", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
open("/lib64/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
open("/usr/lib/locale/locale-archive", O_RDONLY|O_CLOEXEC) = 3
open("test.stp", O_RDONLY)              = 3
+++ exited with 0 +++

No distincts.

1 Answers1

1

That is because cat test.stp > /dev/null requires shell (bash) to be run (note output redirection with >), so PID of bash process (not cat) will be recognized as target().

You may check if pid() is child to target(). There is action in DTrace called progenyof() that determines if current task is child of task with predefined pid(). There is no analogue in SystemTap, but you may easily reproduce it like this:

function progenyof(pid:long) {
    parent = task_parent(task_current());
    task = pid2task(pid);

    while(parent && task_pid(parent) > 0) {
        if(task == parent)
            return 1;

        parent = task_parent(parent);
    }
}
myaut
  • 11,174
  • 2
  • 30
  • 62