‘strace’如何工作?

‘strace’如何工作?

最近,我把mv大量文件从硬盘移动到闪存驱动器。我忘了添加详细标志,所以我不知道移动“到哪里”以及还剩下多少次传输。

我找到了这个strace实用程序,并决定在我的 mv 进程上使用它。使用后,ps -ef | grep mv我能够找到进程的 pid,然后运行strace -p [PID]。以下是我得到的结果示例:

write(4, "\325\0\0s\1\1\224\0\0\0\0\0109\27\0\0\201\327\0\0\240H:\310xgM\337\274\26\"\273"..., 32768) = 32768
read(3, "\6\3319H\r\207\345\257\301JL)\2601C\t\303\22(\214\353\211\230;{\6\214\355nh@F"..., 32768) = 32768
write(4, "\6\3319H\r\207\345\257\301JL)\2601C\t\303\22(\214\353\211\230;{\6\214\355nh@F"..., 32768) = 32768
read(3, "ZK\301\332\263\214@\177\3352$\374\277];\255\265\364\240d\275\307P\237*\364\23\206\31\306\244\256"..., 32768) = 32768
write(4, "ZK\301\332\263\214@\177\3352$\374\277];\255\265\364\240d\275\307P\237*\364\23\206\31\306\244\256"..., 32768) = 32768
read(3, ".\341\355\32\366\7\365\244\4\4\221{c,$\246]\204\342\261\"\374K\234\264\17\26\346\246\327\347m"..., 32768) = 32768

然后还有一些:

fcntl(3, F_GETFD)                       = 0
fcntl(3, F_SETFD, FD_CLOEXEC)           = 0
fstat(3, {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
fcntl(3, F_GETFL)                       = 0x38800 (flags O_RDONLY|O_NONBLOCK|O_LARGEFILE|O_DIRECTORY|O_NOFOLLOW)
fcntl(3, F_SETFD, FD_CLOEXEC)           = 0
fcntl(3, F_DUPFD, 3)                    = 4
fcntl(4, F_GETFD)                       = 0
fcntl(4, F_SETFD, FD_CLOEXEC)           = 0
getdents64(3, /* 4 entries */, 32768)   = 120
getdents64(3, /* 0 entries */, 32768)   = 0
close(3)                                = 0
newfstatat(4, "The Pick of Destiny", {st_mode=S_IFDIR|0755, st_size=4096, ...}, AT_SYMLINK_NOFOLLOW) = 0
openat(4, "The Pick of Destiny", O_RDONLY|O_NOCTTY|O_NONBLOCK|O_DIRECTORY|O_NOFOLLOW) = 3
fcntl(3, F_GETFD)                       = 0
fcntl(3, F_SETFD, FD_CLOEXEC)           = 0
fstat(3, {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
fcntl(3, F_GETFL)                       = 0x38800 (flags O_RDONLY|O_NONBLOCK|O_LARGEFILE|O_DIRECTORY|O_NOFOLLOW)
fcntl(3, F_SETFD, FD_CLOEXEC)           = 0
fcntl(3, F_DUPFD, 3)                    = 5
fcntl(5, F_GETFD)                       = 0
fcntl(5, F_SETFD, FD_CLOEXEC)           = 0
getdents64(3, /* 22 entries */, 32768)  = 1008
getdents64(3, /* 0 entries */, 32768)   = 0
close(3)                                = 0

那么,strace 到底给了我什么?这些是内核调用吗?如果是,它们是什么意思(我知道 read 和 write 的作用,但那些数字是什么)?

附加问题:有没有办法让我看到比 strace 显示的内容“更低”的内容?也许是 CPU 调用?

答案1

那么,strace 到底给了我什么?

strace您的是系统调用 - 请求内核执行进程本身无法执行的操作(如打开文件)的调用。(在您的跟踪中发现了例如fcntl、等)。close

如果是,那么它们是什么意思(我知道读和写的作用,但是那些数字是什么)?

fcntl(3,F_GETFD) = 0

翻译为:系统调用(fcntl)带有参数(3,F_GETFD),返回值(0)

附加问题:有没有办法让我看到比 strace 显示的内容“更低”的内容?也许是 CPU 调用?

您的意思是 1) CPU 中断或 2) 汇编指令。老实说,我不知道,但是:

  1. 观察中断触发似乎并不是那么有用。
  2. 观察处理器正在执行的指令似乎有点低级,而且仍然没什么用。坦率地说,如果我想要这样做,我只需在真的很慢模拟器允许我观察汇编语言是如何解释的。

strace有一个手册页 - 如果您想了解其工作原理的详细信息,我建议您阅读它。

答案2

您在最初的问题中已经得到了正确的答案。

的默认行为strace是报告该进程正在执行的系统调用,它还将报告调用的信号以及处理该信号的处理程序。

在您的示例中,被调用的系统调用位于行的开头:fcntl()getdents64() close()等等。

传递给这些系统调用的参数会显示出来 - 通常会被截断,因为原始数据的大小可能是千/兆/千兆字节) fstat(3, {st_mode=S_IFDIR|0755, st_size=4096, ...})...捐赠截断)。这些值代表什么因系统调用而异,但 man 会显示它们代表什么(前提是您的系统上安装了与系统调用相关的基本手册页)。man 2 fstat将显示 fstat 的程序员手册页并详细说明参数。

在本例中,这是该系统调用的结果 getdents64(3, /* 22 entries */, 32768) = 1008 1008。此结果代码的值将在所调用的特定系统调用的 man(1) 页中记录,其方式与详细说明参数的方式相同。请注意,在本例中,/* 22 entries */是 strace 的另一个截断操作,可以使用 对其进行扩展-e abbr=none

请注意,这strace不是一个通用命令,一些 unix 版本使用trussktrace并对dump进程执行类似的调试。您还应该查看 strace 的手册页,它附带了一些扩展选项(也许这接近您的奖励问题)例如-i(打印指令指针)-v(详细程度)-a(更改结果部分的位置 - 列 - 以查看传递给命令的更多参数)和表达式过滤-e

编辑添加了一些关于其他形式参数截断的注释。

相关内容