我正在尝试监视正在运行的进程中特定文件描述符的读取活动。这是我正在测试各种解决方案的 C++ 测试平台:
#include <fcntl.h>
#include <unistd.h>
#include <sys/stat.h>
#include <iostream>
int main()
{
const int fd1=open("/tmp/testfile", O_RDWR|O_CREAT);
const int fd2=open("/tmp/testfile", O_RDONLY);
write(fd1, "Hello, world!", 13);
std::cout << "PID: " << getpid() << ", fds: " << fd1 << "," << fd2 << "\n";
for(;;)
{
char b;
if(!read(fd1,&b, 1))
lseek(fd1,0,SEEK_SET);
}
}
其典型输出为:
PID: 14992, fds: 3,4
因此,我尝试使用 strace 来跟踪文件描述符 3 的读取:
strace -p 14992 -e trace=none -e read=3
我收到的只是消息strace: Process 14992 attached
,仅此而已。如果我跟踪所有read
系统调用,我确实会得到很多输出:
$ strace -p 14992 -e trace=read
strace: Process 14992 attached
read(3, "", 1) = 0
read(3, "H", 1) = 1
read(3, "e", 1) = 1
read(3, "l", 1) = 1
read(3, "l", 1) = 1
read(3, "o", 1) = 1
read(3, ",", 1) = 1
read(3, " ", 1) = 1
<...>
但 strace 手册说-e read=set
:
请注意,这独立于
read
由选项 -e trace=read 控制的系统调用的正常跟踪。
所以我认为 mytrace=none
应该避免跟踪与我的read=3
选项无关的任何内容是正确的。
显然,我做错了什么。那么,我实际上应该如何使用 strace 来仅跟踪read
系统调用,并且仅在何时跟踪fd==3
?请注意,使用过滤输出grep
不是一个选项,因为它会减慢我要跟踪的实际应用程序的速度。
答案1
我不确定如何解释您从联机帮助页中引用的句子,但禁用所有跟踪也会禁用所有read
跟踪:I/O 跟踪在跟踪系统调用后发生,并且那仅发生在启用的系统调用上。
strace -e trace=none -e read=3
意思是“禁用所有系统调用跟踪,并且每当跟踪从文件描述符 3 读取的系统调用时,转储其 I/O”。
strace -e read -e read=3
显示对文件描述符 3 的调用read
以及从文件描述符 3 读取的所有信息,但它read
根本不过滤一般系统调用跟踪,仅过滤 I/O 转储。
换句话说,read=3
不过滤所有跟踪选项;它请求从文件描述符 3 读取的 I/O 转储。
查看strace
源代码,似乎没有办法完成您想要的操作。