Skip to content

Support preadv2 and pwritev2 syscalls.#4066

Merged
rocallahan merged 1 commit intorr-debugger:masterfrom
azat-archive:preadv2-pwritev2
Apr 20, 2026
Merged

Support preadv2 and pwritev2 syscalls.#4066
rocallahan merged 1 commit intorr-debugger:masterfrom
azat-archive:preadv2-pwritev2

Conversation

@azat
Copy link
Copy Markdown
Contributor

@azat azat commented Apr 14, 2026

These were marked as UnsupportedSyscall, causing rr to expect ENOSYS. On modern kernels that support them (Linux 4.6+), the syscall succeeds and rr hits a FATAL assertion. Handle them the same way as their v1 counterparts (preadv/pwritev).

Handle them like their v1 counterparts, but with an additional flag whitelist: reject unknown RWF_* flags with EINVAL so that a future kernel addition whose semantics break rr can't silently go wrong. RWF_APPEND is additionally rejected for pwritev2 because the kernel would ignore the user's offset while FileMonitor would still compute it from the arguments and misrecord the write.

Fixes #3193

Comment thread src/record_syscall.cc
case Arch::preadv:
/* ssize_t preadv2(int fd, const struct iovec *iov, int iovcnt,
off_t offset, int flags); */
case Arch::preadv2: {
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's possible that some future RWF_ flag will introduce behaviour that breaks rr. So it would be a good idea to define a set of flags that we know are ok with rr with preadv2 (all the flags currently defined, I think), and fail here with EINVAL if some flag outside that set is passed in. See below for why this is especially important for pwritev2.

Comment thread src/Task.cc
}

case Arch::pwritev:
case Arch::pwritev2:
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the RWF_APPEND flag is set then the kernel ignores the user's offset, but we'll compute an incorrect offset below and things will go wrong. (I think we already have an existing bug if the user passes O_APPEND to open(); in that case pwritev will ignore the offset and we compute the wrong offset.)

So let's do what I said above and specify a mask of flags we know we can handle correctly --- I think that's everything currently defined except for RWF_APPEND --- and return EINVAL if any other flags are set. That will require adding code in record_syscall.cc for pwritev2.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for taking a look! Fixed

Previously these were marked UnsupportedSyscall, so rr expected the
kernel to return ENOSYS; on modern kernels (Linux 4.6+) the syscall
succeeds and rr hits a FATAL assertion. Fixes rr-debugger#3193.

Handle them like their v1 counterparts, but with an additional flag
whitelist: reject unknown RWF_* flags with EINVAL so that a future
kernel addition whose semantics break rr can't silently go wrong.
RWF_APPEND is additionally rejected for pwritev2 because the kernel
would ignore the user's offset while FileMonitor would still compute
it from the arguments and misrecord the write.
@azat azat force-pushed the preadv2-pwritev2 branch from 5374b0d to cbd6930 Compare April 20, 2026 08:59
@rocallahan rocallahan merged commit 95b6860 into rr-debugger:master Apr 20, 2026
3 of 4 checks passed
@rocallahan
Copy link
Copy Markdown
Collaborator

Thanks!!!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Support preadv2/pwritev2

2 participants