Skip to content

Commit

Permalink
Don't bother recording memory areas when the process has died; the ch…
Browse files Browse the repository at this point in the history
…anged data is unobservable anyway.
  • Loading branch information
rocallahan committed Aug 6, 2023
1 parent 5d24e9b commit ca3554b
Show file tree
Hide file tree
Showing 5 changed files with 46 additions and 1 deletion.
18 changes: 18 additions & 0 deletions src/AddressSpace.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2418,4 +2418,22 @@ void AddressSpace::fd_tables_changed() {
}
}

bool AddressSpace::range_is_private_mapping(const MemoryRange& range) const {
MemoryRange r = range;
while (r.size() > 0) {
if (!has_mapping(r.start())) {
return false;
}
const AddressSpace::Mapping& m = mapping_of(r.start());
if (!(m.map.flags() & MAP_PRIVATE)) {
return false;
}
if (m.map.end() >= r.end()) {
return true;
}
r = MemoryRange(m.map.end(), r.end());
}
return true;
}

} // namespace rr
3 changes: 3 additions & 0 deletions src/AddressSpace.h
Original file line number Diff line number Diff line change
Expand Up @@ -889,6 +889,9 @@ class AddressSpace : public HasTaskSet {
// suitable for hardware watchpoint registers.
enum WatchpointAlignment { UNALIGNED, ALIGNED };

// Returns true if the range is completely covered by private mappings
bool range_is_private_mapping(const MemoryRange& range) const;

private:
struct Breakpoint;
typedef std::map<remote_code_ptr, Breakpoint> BreakpointMap;
Expand Down
9 changes: 9 additions & 0 deletions src/HasTaskSet.cc
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,13 @@ Task* HasTaskSet::first_running_task() const {
return nullptr;
}

Task* HasTaskSet::find_other_thread_group(Task* t) const {
for (Task* tt : task_set()) {
if (tt->thread_group() != t->thread_group()) {
return tt;
}
}
return nullptr;
}

} // namespace rr
1 change: 1 addition & 0 deletions src/HasTaskSet.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ class HasTaskSet {
virtual void insert_task(Task* t);
virtual void erase_task(Task* t);
bool has_task(Task* t) const { return tasks.find(t) != tasks.end(); }
Task* find_other_thread_group(Task* t) const;
Task* first_running_task() const;

protected:
Expand Down
16 changes: 15 additions & 1 deletion src/RecordTask.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1721,7 +1721,21 @@ void RecordTask::record_remote(remote_ptr<void> addr, ssize_t num_bytes) {
return;
}

auto buf = read_mem(addr.cast<uint8_t>(), num_bytes);
bool ok = true;
auto buf = read_mem(addr.cast<uint8_t>(), num_bytes, &ok);
if (!ok) {
// Tracee probably died unexpectely. This should only happen
// due to SIGKILL racing with our PTRACE_CONT.
if (!vm()->find_other_thread_group(this) &&
vm()->range_is_private_mapping(MemoryRange(addr, num_bytes))) {
// The recording range is mapped private and no other threadgroup shares the
// address space, so the new memory contents should be unobservable, and we can
// just not record the data.
return;
}
ASSERT(this, false) << "Should have recorded " << num_bytes << " bytes from "
<< addr << ", but failed";
}
trace_writer().write_raw(rec_tid, buf.data(), num_bytes, addr);
}

Expand Down

0 comments on commit ca3554b

Please sign in to comment.