当我在构建目录中运行以下make
命令时,它几乎是空的(有问题的文件绝对不存在)
strace -f -e trace=execve,vfork,open,creat -s 1024 make <target>
完成后,文件就完全存在了。因此它一定是由其make
子进程之一(或其子进程的子进程等)创建的。
但是,当我 grep 日志strace
查找文件名或 时,creat
我找不到负责创建该文件的系统调用。
我缺少什么?我还应该监视其他系统调用吗?
编辑:
事实证明,错误出在我的 strace 命令和 grep 中。所有的答案都很有帮助,谢谢大家的宝贵时间。
实际上,我未能传达该文件位于子目录中的信息,并且我正在使用文件名和子目录名称进行 grep。但由于 strace 不提供有关当前工作目录的信息,因此这种方法效果不佳(我最终进行了 stracingchdir
和rename
调用以获得所需的效果)。
所以 PaulHaldane 的第一个建议是正确且切题的。以及拉尔斯克斯的回答,他实际上已经猜到了文件是如何创建的。
答案1
在没有该选项的情况下运行 strace-e
并查看是否会改善您的结果。
创建文件的方法有多种。open
生成该文件的任何工具很可能首先打开一个临时文件,写入数据,然后在完成后重命名该文件,而不是-ing 它。
在您当前的限制 ( execve,vfork,open,creat
) 下,您不会看到这种行为。
例如,给出这个简单的 python 脚本:
import os
import tempfile
fd = tempfile.NamedTemporaryFile(dir='.', delete=False)
fd.write('this is a test\n')
fd.close()
os.rename(fd.name, 'output')
使用您的参数运行strace
然后output
在结果中查找不会产生任何结果:
$ strace -e trace=execve,vfork,open,creat -o trace -f -s 80 python tmptest.py
$ grep output trace
$
但如果我删除-e
过滤器:
$ strace -o trace -f -s 80 python tmptest.py
$ grep output trace
4523 rename("/home/lars/tmp/tmpZDwvPK", "output") = 0
在对您的问题的评论中,Sato Katsura 提供了一个示例,您将在输出中看不到目标文件名,但我认为只要您从干净的构建环境开始,strace
运行时就不太可能遇到这种情况。make
答案2
另一种选择是sysdig
,例如命令如下:
sysdig -p '%proc.pname[%proc.ppid]: %proc.name -> %evt.type(%evt.args)' \
evt.args contains /tmp/yourbuilddir
在一个终端中运行,然后使用临时文件重命名代码的:
#!/usr/bin/perl
use File::AtomicWrite;
File::AtomicWrite->write_file(
{ file => "/tmp/yourbuilddir/foofile",
input => \"blah",
MKPATH => 1
}
);
执行,然后sysdig
在另一个终端中运行回来应该显示类似以下内容:
bash[13645]: perl -> stat(res=-2(ENOENT) path=/tmp/yourbuilddir )
bash[13645]: perl -> stat(res=-2(ENOENT) path=/tmp/yourbuilddir )
bash[13645]: perl -> mkdir(path=/tmp/yourbuilddir mode=0 )
bash[13645]: perl -> stat(res=0 path=/tmp/yourbuilddir )
bash[13645]: perl -> stat(res=0 path=/tmp/yourbuilddir/ )
bash[13645]: perl -> stat(res=0 path=/tmp/yourbuilddir/ )
bash[13645]: perl -> open(fd=3(<f>/tmp/yourbuilddir/.tmp.8XUnHhOrIn) name=/tmp/yourbuilddir/.tmp.8XUnHhOrIn flags=39(O_EXCL|O_CREAT|O_RDWR) mode=0 )
bash[13645]: perl -> ioctl(fd=3(<f>/tmp/yourbuilddir/.tmp.8XUnHhOrIn) request=5401 argument=7FFEF6BE5020 )
bash[13645]: perl -> lseek(fd=3(<f>/tmp/yourbuilddir/.tmp.8XUnHhOrIn) offset=0 whence=1(SEEK_CUR) )
bash[13645]: perl -> fstat(fd=3(<f>/tmp/yourbuilddir/.tmp.8XUnHhOrIn) )
bash[13645]: perl -> fcntl(fd=3(<f>/tmp/yourbuilddir/.tmp.8XUnHhOrIn) cmd=3(F_SETFD) )
bash[13645]: perl -> write(fd=3(<f>/tmp/yourbuilddir/.tmp.8XUnHhOrIn) size=4 )
sshd[678]: sshd -> read(res=970 data=bash[13645]: perl -> stat(res=-2(ENOENT) path=/tmp/yourbuilddir )..bash[13645]: )
bash[13645]: perl -> close(fd=3(<f>/tmp/yourbuilddir/.tmp.8XUnHhOrIn) )
bash[13645]: perl -> rename(res=0 oldpath=/tmp/yourbuilddir/.tmp.8XUnHhOrIn newpath=/tmp/yourbuilddir/foofile )
sshd[678]: sshd -> read(res=186 data=bash[13645]: perl -> close(fd=3(<f>/tmp/yourbuilddir/.tmp.8XUnHhOrIn) )..bash[13 )