2015-01-03 69 views
1

我有简单的ST脚本,每个文件计算过程IO大小:SystemTap的脚本奇怪的行为

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) 
     } 
} 

当我运行stap test.stp -c 'cat test.stp'我得到:

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 

这几乎是正确的。但是,当我执行stap test.stp -c 'cat test.stp > /dev/null'我得到一些奇怪的事情:在第二种情况下

/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 

为什么我没有看到test.stp opened as 3

我做一些测试与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 +++ 

没有distincts。

回答

1

这是因为cat test.stp > /dev/null需要运行shell(bash)(注意输出重定向>),所以bash进程的PID(非cat)将被识别为target()

您可能会检查pid()是否为target()。 DTrace中有一个名为progenyof()的动作,用于确定当前任务是否为具有预定义的pid()任务的子任务。在SystemTap中没有类似的东西,但你可以很容易地重现它,像这样:

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); 
    } 
}