0

I'm trying to monitor read activity on a particular file descriptor in a running process. Here is the C++ test bench I'm testing various solutions on:

#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);
    }
}

Its typical output is:

PID: 14992, fds: 3,4

So, I'm trying to use strace to trace the reads of the file descriptor 3:

strace -p 14992 -e trace=none -e read=3

What I'm getting is just the message strace: Process 14992 attached, and nothing more. If I instead trace all the read system calls, I do get a lot of output:

$ 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
<...>

But strace manual says about -e read=set:

Note that this is independent from the normal tracing of the read system call which is controlled by the option -e trace=read.

So I suppose that my trace=none, which is supposed to avoid tracing anything unrelated to my read=3 option is correct.

Apparently, I'm doing something wrong. So, how should I actually use strace to trace only the read system call, and only when fd==3? Note that filtering output using grep is not an option, since it'd slow down a real-world application I'm going to trace.

0

I’m not sure how to interpret the sentence you quote from the manpage, but disabling all tracing disables all read tracing too: I/O tracing happens after a syscall is traced, and that only happens for enabled syscalls.

strace -e trace=none -e read=3

means “disable all syscall traces, and whenever a syscall is traces which reads from file descriptor 3, dump its I/O”.

strace -e read -e read=3

shows both calls to read and all the information read from file descriptor 3, but it doesn’t filter the general read syscall traces at all, only the I/O dumps.

Put another way, read=3 doesn’t filter all trace options; it requests that reads from file descriptor 3 have their I/O dumped.

Looking through the strace source code, there doesn’t appear to be a way to do what you’re after.

| improve this answer | |
  • Well, if I now set -e read=4 instead of -e read=3, I'll still get the reads of 3, so this latter option is then useless. The goal I'm trying to achieve is filtering at an earlier stage than grep would. – Ruslan Jan 15 at 11:20
  • Yes, I don’t think it’s possible to do what you’re after, within strace. – Stephen Kitt Jan 15 at 12:58

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.