【发布时间】:2014-09-03 04:19:06
【问题描述】:
我正在编写一个脚本来分析使用strace 跟踪的文件访问。
跟踪包含一些已被另一个进程中断的调用。 strace 用<unfinished ...> 和<... close resumed>(如果close 呼叫中断)标记显示它们。
[pid 26817] 12:48:22.972737 close(449 <unfinished ...>
[pid 28708] 12:48:22.972797 fcntl(451, F_SETFD, FD_CLOEXEC <unfinished ...>
[pid 26817] 12:48:22.972808 <... close resumed> ) = 0
进程及其所有线程已被跟踪
strace -f -tt -p <pid>
手册页不确定调用何时结束。
如果正在执行一个系统调用,同时另一个线程/进程正在调用另一个系统调用,则 strace 将尝试保留这些事件的顺序并将正在进行的调用标记为未完成。当呼叫返回时,它将被标记为已恢复。
虽然我假设,resumed 标记自然会指示呼叫现已完成。我想问问是不是这样。
上面的痕迹摘录可以重构为
一个
[pid 28708] 12:48:22.972797 fcntl(451, F_SETFD, FD_CLOEXEC <unfinished ...>
[pid 26817] 12:48:22.972808 close(449) = 0
还是应该重构为
B
[pid 26817] 12:48:22.972737 close(449) = 0
[pid 28708] 12:48:22.972797 fcntl(451, F_SETFD, FD_CLOEXEC <unfinished ...>
这里的顺序很重要,因为unfinished 和resumed 之间可能有多次调用,其中一个可能会对目前即将关闭的文件执行某些操作。
【问题讨论】:
-
跟踪是正确的,你的“重建”不是。如果调用不重叠,则跟踪首先看起来像 A 或 B。
-
我并没有声称
strace是错误的。 ;) 我想知道带有449句柄的文件何时不再打开。我的理解是close()呼叫已被另一个呼叫中断。如果它实际上正在进行中并且另一个进程在这 71 毫秒内进行另一个系统调用,这可能与纯技术角度完全不同,但在我的情况下是相同的:当strace"看到时文件将被关闭“unfinished。不是吗? -
如果程序在调用
close()后还在使用文件描述符,那就是bug。如果进程试图在close()返回之前再次打开文件,这也可能表明存在错误。所以调用和返回都显示在跟踪中。