mozilla/rr — pull request #179 by cgjones (2013-07-03 23:47:38+00:00)
Title: Initial support for buffered may-block syscalls.

This commit includes quite a few changes, many of which are noise or
lesser bugs fixed along the way. But the crux of the approach of this
patch, building on the desched event already being fired, is

0. When the desched event fires, check if the tracee has already
finished the system call it was in. If so, continue normally; the
call will be recorded in the buffer and replay will Just Work.
1. If the syscall really did block, then record the syscall entry
normally (outside the syscallbuf), flush the syscallbuf, and mark the
context as preemptible. Additionally, set things up so that the
syscallbuf code *will not* commit the current syscall into the buffer
when it finishes. Advance execution normally until the syscall
finishes, then record the syscall exit normally.

A somewhat tricky part of the implementation is that desched'd
syscalls will still use the syscallbuf as "scratch storage" after the
buffer has been flushed, when the event fires --- even though they're
not going to commit to the buffer. This is OK because

* rr records the outparams as if they were help in normal scratch buffers
* the tracee hold a lock on the storage throughout
* we do careful dance to replay the flushing / clearing of recorded
size / marking for commit-abort in the right order

One large part but relatively minor part of the patch was refactoring
the code that initializes the shared buffer, because we need to share
the mapping during replay now. Another large but minor part was
simplifying and correcting how the scratch-buffer setup is done in
prep_event().

This patch doesn't enable any may-block syscalls for buffering, but
there are two included in commented-out code in syscall_buffer.c which
can be used for testing.

Resolves #7.