Skip to content

Commit

Permalink
Fix the unexpected-exit path in Task::exit_syscall_and_prepare_restart
Browse files Browse the repository at this point in the history
  • Loading branch information
rocallahan committed Sep 5, 2023
1 parent 5f37db9 commit 8d51a1e
Show file tree
Hide file tree
Showing 3 changed files with 19 additions and 3 deletions.
4 changes: 3 additions & 1 deletion src/Monkeypatcher.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1218,7 +1218,9 @@ bool Monkeypatcher::try_patch_syscall_aarch64(RecordTask* t, bool entering_sysca
auto success = patch_syscall_with_hook(*this, t, syscall_hooks[0], ip, 4, 0);
if (!success && entering_syscall) {
// Need to reenter the syscall to undo exit_syscall_and_prepare_restart
t->enter_syscall();
if (!t->enter_syscall()) {
return false;
}
}

if (!success) {
Expand Down
11 changes: 9 additions & 2 deletions src/Task.cc
Original file line number Diff line number Diff line change
Expand Up @@ -972,12 +972,12 @@ bool Task::exit_syscall_and_prepare_restart() {
// This exits the hijacked SYS_gettid. Now the tracee is
// ready to do our bidding.
if (!exit_syscall()) {
// The tracee suddenly exited. To get this to replay correctly, we need to
// The tracee unexpectedly exited. To get this to replay correctly, we need to
// make it look like we really entered the syscall. Then
// handle_ptrace_exit_event will record something appropriate.
r.set_original_syscallno(syscallno);
r.set_syscall_result(-ENOSYS);
set_regs(r);
override_regs_during_exit(r);
return false;
}
LOG(debug) << "exit_syscall_and_prepare_restart done";
Expand Down Expand Up @@ -1578,6 +1578,13 @@ void Task::set_regs(const Registers& regs) {
}
}

void Task::override_regs_during_exit(const Registers& regs) {
ASSERT(this, !is_stopped_);
orig_syscallno_dirty = true;
registers_dirty = true;
registers = regs;
}

void Task::flush_regs() {
if (registers_dirty) {
LOG(debug) << "Flushing registers for tid " << tid << " " << registers;
Expand Down
7 changes: 7 additions & 0 deletions src/Task.h
Original file line number Diff line number Diff line change
Expand Up @@ -598,6 +598,13 @@ class Task {
/** Set the tracee's registers to |regs|. Lazy. */
void set_regs(const Registers& regs);

/** Set the tracee's registers to |regs|. The task
* is known to be exiting (running towards, or actually in, a
* not-yet-reported PTRACE_EVENT_EXIT or reap) so its real registers
* won't change underneath us, but we need to override those
* registers with our values for recording purposes. */
void override_regs_during_exit(const Registers& regs);

/** Ensure registers are flushed back to the underlying task. */
void flush_regs();

Expand Down

0 comments on commit 8d51a1e

Please sign in to comment.