A
A
Alexander Demchenko2015-01-05 09:18:25
linux
Alexander Demchenko, 2015-01-05 09:18:25

The SystemTap script works strangely. Any experts on this tool?

Given: a small script that monitors read and write syscalls from a particular process and counts how much data was written and read by the process to each 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)
        }
}

If you run it like this: stap test.stp -c 'cat test.stp'- then everything seems to work correctly. Here is the output:
...
здесь вывод самого cat
...
/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

But, if I try to redirect the output of cat to /dev/null - stap test.stp -c 'cat test.stp > /dev/null'- I get some nonsense:
/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

As if the test.stp file does not open at all. At first I thought that this core somehow deceives me: it sees that the output merges into the void and does nothing. But if you run the same thing under strace, the output is the same in both cases:
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 +++

Can't figure out where I've stepped.

Answer the question

In order to leave comments, you need to log in

1 answer(s)
V
Vadim Misbakh-Soloviev, 2015-01-29
@mva

For starters, in the command to call cat under strace, you are redirecting the output of strace's stdout to zero (which, in principle, does not exist), and not cat.
Well, and so - most likely, optimizing the system tap. Now, give me a couple of minutes, I'll dig.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question