strace, ltrace, dtrace

strace -o 可以把log 写入一个文件

root@DTSEACLI1302348:/tmp # strace -o trace.log ls testdir/
file1  file2

wc -l filename 输出文件行数

wc -w filename 输出文件word

wc -c/m filename 输出文件bytes/chars number

-c, --bytes print the byte counts
-m, --chars print the character counts
-l, --lines print the newline counts

root@DTSEACLI1302348:/tmp # wc trace.log
 116  689 8097 trace.log

root@DTSEACLI1302348:/tmp # wc -c trace.log
8097 trace.log

root@DTSEACLI1302348:/tmp # wc -m trace.log
8097 trace.log

root@DTSEACLI1302348:/tmp # wc -w trace.log
689 trace.log

root@DTSEACLI1302348:/tmp # wc -l trace.log
116 trace.log

用grep 查看 trace.log中有多少个testdir

root@DTSEACLI1302348:/tmp # grep testdir trace.log
execve("/usr/bin/ls", ["ls", "testdir/"], 0x7fffcaf0bad8 /* 59 vars */) = 0
stat("testdir/", {st_mode=S_IFDIR|0777, st_size=4096, ...}) = 0
openat(AT_FDCWD, "testdir/", O_RDONLY|O_NONBLOCK|O_CLOEXEC|O_DIRECTORY) = 3

用man 2 来查看系统调用execve

root@DTSEACLI1302348:/tmp # man 2 execve

 execve() executes the program pointed to by filename
你需要在 man 命令和系统调用名称之间添加 2。如果使用 man man 阅读 man 命令的手册页,你会看到第 2 节是为系统调用保留的。同样,如果你需要有关库函数的信息,则需要在 man 和库函数名称之间添加一个 3。

以下是手册的章节编号及其包含的页面类型:

1:可执行的程序或 shell 命令
2:系统调用(由内核提供的函数)
3:库调用(在程序的库内的函数)
4:特殊文件(通常出现在 /dev)

用man 2 来看第二个系统调用stat 是获取文件状态的系统调用

stat 权限是要所有指向这个文件的dir的权限, 通过pathname
fstat,通过fd
lstat,如果pathname是 symbolic link,那么返回的是link itself,并不是symbolic link指向的文件本尊。it returns information about the link itself, not the file that it refers to.


 stat, fstat, lstat, fstatat - get file status 是获取文件状态的系统调用,

       int stat(const char *pathname, struct stat *buf);
       int fstat(int fd, struct stat *buf);
       int lstat(const char *pathname, struct stat *buf);


       int fstatat(int dirfd, const char *pathname, struct stat *buf,
                   int flags);

DESCRIPTION
       These  functions  return  information  about  a file, in the buffer pointed to by buf.  No permissions are required on the file itself, but—in the case of stat(), fstatat(), and lstat()—execute (search) permission is
       required on all of the directories in pathname that lead to the file.

       stat() and fstatat() retrieve information about the file pointed to by pathname; the differences for fstatat() are described below.

       lstat() is identical to stat(), except that if pathname is a symbolic link, then it returns information about the link itself, not the file that it refers to.

       fstat() is identical to stat(), except that the file about which information is to be retrieved is specified by the file descriptor fd.

通过stat 获取文件状态后,通过openat打开文件

root@DTSEACLI1302348:/tmp # grep testdir trace.log
execve("/usr/bin/ls", ["ls", "testdir/"], 0x7fffcaf0bad8 /* 59 vars */) = 0
stat("testdir/", {st_mode=S_IFDIR|0777, st_size=4096, ...}) = 0
openat(AT_FDCWD, "testdir/", O_RDONLY|O_NONBLOCK|O_CLOEXEC|O_DIRECTORY) = 3

getdents 的3 来自于openat的文件描述符 getdents - get directory entries“获取目录项”

root@DTSEACLI1302348:/tmp # grep getdents trace.log
getdents(3, /* 4 entries */, 32768)     = 112
getdents(3, /* 0 entries */, 32768)     = 0

用write 把信息写入终端显示, write 系统调用将在标准显示(就是这个终端,由 1 所标识的)上显示 file1 和 file2

root@DTSEACLI1302348:/tmp # grep write trace.log
write(1, "file1  file2\n", 13)          = 13
你可以看到将要显示的文件名:file1 和 file2。关于第一个参数(1),请记住在 Linux 中,当运行任何进程时,默认情况下会为其打开三个文件描述符。以下是默认的文件描述符:

0:标准输入
1:标准输出
2:标准错误

strace -c ls testdir/ 需要系统调用的名称、运行的次数以及每个系统调用花费的时间百分比

strace -e open ls testdir/ 专注于特定的系统调用,例如专注于 open 系统调用,而忽略其余部分。你可以使用-e 标志跟上系统调用的名称

root@DTSEACLI1302348:/tmp # strace -c ls testdir/
file1  file2
% time     seconds  usecs/call     calls    errors syscall
------ ----------- ----------- --------- --------- ----------------
 29.22    0.000180           6        27           mmap
 17.86    0.000110           6        18           mprotect
 12.66    0.000078           7        10           open
  5.52    0.000034           3        11           fstat
  5.19    0.000032           2        13           close
  4.71    0.000029          14         2           statfs
  4.55    0.000028           3         8           read
  4.06    0.000025           6         4         3 access
  3.41    0.000021          10         2           munmap
  2.44    0.000015           7         2           getdents
  2.11    0.000013           6         2           stat
  1.46    0.000009           4         2           ioctl
  1.30    0.000008           2         3           brk
  1.14    0.000007           7         1           write
  0.97    0.000006           6         1           openat
  0.81    0.000005           2         2           rt_sigaction
  0.65    0.000004           4         1           execve
  0.49    0.000003           3         1           rt_sigprocmask
  0.49    0.000003           3         1           getrlimit
  0.32    0.000002           2         1           arch_prctl
  0.32    0.000002           2         1           set_tid_address
  0.32    0.000002           2         1           set_robust_list
------ ----------- ----------- --------- --------- ----------------
100.00    0.000616                   114         3 total


root@DTSEACLI1302348:/tmp #  strace -e open ls testdir
open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
open("/lib64/libselinux.so.1", O_RDONLY|O_CLOEXEC) = 3
open("/lib64/libcap.so.2", O_RDONLY|O_CLOEXEC) = 3
open("/lib64/libacl.so.1", O_RDONLY|O_CLOEXEC) = 3
open("/lib64/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
open("/lib64/libpcre.so.1", O_RDONLY|O_CLOEXEC) = 3
open("/lib64/libdl.so.2", O_RDONLY|O_CLOEXEC) = 3
open("/lib64/libattr.so.1", O_RDONLY|O_CLOEXEC) = 3
open("/lib64/libpthread.so.0", O_RDONLY|O_CLOEXEC) = 3
open("/usr/lib/locale/locale-archive", O_RDONLY|O_CLOEXEC) = 3
file1  file2
+++ exited with 0 +++

查看2个系统调用 strace -e write,getdents ls testdir

root@DTSEACLI1302348:/tmp #  strace -e write,getdents ls testdir
getdents(3, /* 4 entries */, 32768)     = 112
getdents(3, /* 0 entries */, 32768)     = 0
write(1, "file1  file2\n", 13file1  file2
)          = 13
+++ exited with 0 +++

显示时间 strace -t ls testdir

root@DTSEACLI1302348:/tmp #  strace -e write,getdents -t ls testdir
13:21:13 getdents(3, /* 4 entries */, 32768) = 112
13:21:13 getdents(3, /* 0 entries */, 32768) = 0
13:21:13 write(1, "file1  file2\n", 13file1  file2
) = 13
13:21:13 +++ exited with 0 +++


root@DTSEACLI1302348:/tmp #  strace -e write,getdents -tt ls testdir
13:21:56.895909 getdents(3, /* 4 entries */, 32768) = 112
13:21:56.896157 getdents(3, /* 0 entries */, 32768) = 0
13:21:56.896313 write(1, "file1  file2\n", 13file1  file2
) = 13
13:21:56.896638 +++ exited with 0 +++

显示相对时间strace -e write,getdents -r ls testdir

root@DTSEACLI1302348:/tmp #  strace -e write,getdents -r ls testdir
     0.000000 getdents(3, /* 4 entries */, 32768) = 112
     0.000135 getdents(3, /* 0 entries */, 32768) = 0
     0.000160 write(1, "file1  file2\n", 13file1  file2
) = 13
     0.000303 +++ exited with 0 +++
posted @ 2022-07-24 21:22  vivi~  阅读(79)  评论(0编辑  收藏  举报