Skip to content

Instantly share code, notes, and snippets.

@rocallahan
Created July 16, 2021 14:08
Show Gist options
  • Save rocallahan/eee63245a75b6f27b5dce4548e446191 to your computer and use it in GitHub Desktop.
Save rocallahan/eee63245a75b6f27b5dce4548e446191 to your computer and use it in GitHub Desktop.
diff --git a/src/AddressSpace.cc b/src/AddressSpace.cc
index 0362a46ff..88690b77b 100644
--- a/src/AddressSpace.cc
+++ b/src/AddressSpace.cc
@@ -63,7 +63,7 @@ static bool thread_group_in_exec(Task* t) {
return false;
}
for (Task* tt : t->thread_group()->task_set()) {
- if (tt == t) {
+ if (tt == t || t->already_exited()) {
continue;
}
RecordTask* rt = static_cast<RecordTask*>(tt);
@@ -1033,10 +1033,11 @@ bool AddressSpace::add_breakpoint(remote_code_ptr addr, BreakpointType type) {
ssize_t bkpt_size = bkpt_instruction_length(arch());
// Grab a random task from the VM so we can use its
// read/write_mem() helpers.
- Task* t = *task_set().begin();
- if (bkpt_size !=
- t->read_bytes_fallible(addr.to_data_ptr<uint8_t>(),
- bkpt_size, overwritten_data)) {
+ Task* t = first_running_task();
+ if (!t ||
+ bkpt_size !=
+ t->read_bytes_fallible(addr.to_data_ptr<uint8_t>(),
+ bkpt_size, overwritten_data)) {
return false;
}
t->write_bytes_helper(addr.to_data_ptr<uint8_t>(), bkpt_size,
@@ -1062,19 +1063,23 @@ void AddressSpace::remove_all_breakpoints() {
void AddressSpace::suspend_breakpoint_at(remote_code_ptr addr) {
auto it = breakpoints.find(addr);
if (it != breakpoints.end()) {
- Task* t = *task_set().begin();
- t->write_bytes_helper(addr.to_data_ptr<uint8_t>(),
- bkpt_instruction_length(arch()), it->second.overwritten_data);
+ Task* t = first_running_task();
+ if (t) {
+ t->write_bytes_helper(addr.to_data_ptr<uint8_t>(),
+ bkpt_instruction_length(arch()), it->second.overwritten_data);
+ }
}
}
void AddressSpace::restore_breakpoint_at(remote_code_ptr addr) {
auto it = breakpoints.find(addr);
if (it != breakpoints.end()) {
- Task* t = *task_set().begin();
- t->write_bytes_helper(addr.to_data_ptr<uint8_t>(),
- bkpt_instruction_length(arch()),
- breakpoint_insn(arch()));
+ Task* t = first_running_task();
+ if (t) {
+ t->write_bytes_helper(addr.to_data_ptr<uint8_t>(),
+ bkpt_instruction_length(arch()),
+ breakpoint_insn(arch()));
+ }
}
}
@@ -1146,7 +1151,10 @@ bool AddressSpace::restore_watchpoints() {
bool AddressSpace::update_watchpoint_value(const MemoryRange& range,
Watchpoint& watchpoint) {
- Task* t = *task_set().begin();
+ Task* t = first_running_task();
+ if (!t) {
+ return false;
+ }
bool valid = true;
vector<uint8_t> value_bytes = watchpoint.value_bytes;
for (size_t i = 0; i < value_bytes.size(); ++i) {
@@ -1956,7 +1964,10 @@ void AddressSpace::destroy_breakpoint(BreakpointMap::const_iterator it) {
if (task_set().empty()) {
return;
}
- Task* t = *task_set().begin();
+ Task* t = first_running_task();
+ if (!t) {
+ return;
+ }
auto ptr = it->first.to_data_ptr<uint8_t>();
auto data = it->second.overwritten_data;
if (bkpt_instruction_length(arch()) == 1) {
@@ -2323,13 +2334,7 @@ void AddressSpace::fd_tables_changed() {
}
DEBUG_ASSERT(task_set().size() != 0);
uint8_t fdt_uniform = true;
- RecordTask* rt = nullptr;
- // Find a suitable task
- for (auto* t : task_set()) {
- if (!t->is_dying()) {
- rt = static_cast<RecordTask*>(t);
- }
- }
+ RecordTask* rt = static_cast<RecordTask*>(first_running_task());
if (!rt) {
return;
}
diff --git a/src/FdTable.cc b/src/FdTable.cc
index 6904b0e88..2697a599c 100644
--- a/src/FdTable.cc
+++ b/src/FdTable.cc
@@ -151,6 +151,9 @@ void FdTable::update_syscallbuf_fds_disabled(int fd) {
return;
}
RecordTask* rt = static_cast<RecordTask*>(t);
+ if (rt->already_exited()) {
+ continue;
+ }
AddressSpace* vm = rt->vm().get();
if (vms_updated.find(vm) != vms_updated.end()) {
diff --git a/src/HasTaskSet.cc b/src/HasTaskSet.cc
index de3f7d381..130ab4ae4 100644
--- a/src/HasTaskSet.cc
+++ b/src/HasTaskSet.cc
@@ -17,4 +17,13 @@ void HasTaskSet::erase_task(Task* t) {
tasks.erase(t);
}
+Task* HasTaskSet::first_running_task() const {
+ for (auto t : task_set()) {
+ if (!t->already_exited() && !t->is_dying()) {
+ return t;
+ }
+ }
+ return nullptr;
+}
+
} // namespace rr
diff --git a/src/HasTaskSet.h b/src/HasTaskSet.h
index 83e282d03..f740f20e0 100644
--- a/src/HasTaskSet.h
+++ b/src/HasTaskSet.h
@@ -21,6 +21,7 @@ public:
void insert_task(Task* t);
void erase_task(Task* t);
bool has_task(Task* t) const { return tasks.find(t) != tasks.end(); }
+ Task* first_running_task() const;
protected:
TaskSet tasks;
diff --git a/src/MmappedFileMonitor.cc b/src/MmappedFileMonitor.cc
index 5f3ed5c70..5a28a4739 100644
--- a/src/MmappedFileMonitor.cc
+++ b/src/MmappedFileMonitor.cc
@@ -96,7 +96,7 @@ void MmappedFileMonitor::did_write(Task* t, const std::vector<Range>& ranges,
// If the task here has execed, we may not be able to record its
// memory any longer, so loop through all tasks in this address
// space in turn in case any *didn't* exec.
- if (static_cast<RecordTask*>(tt)->record_remote_fallible(km.intersect(mr)) > 0) {
+ if (!tt->already_exited() && static_cast<RecordTask*>(tt)->record_remote_fallible(km.intersect(mr)) > 0) {
break;
}
}
diff --git a/src/ProcMemMonitor.cc b/src/ProcMemMonitor.cc
index b5393ee59..4f59c65aa 100644
--- a/src/ProcMemMonitor.cc
+++ b/src/ProcMemMonitor.cc
@@ -54,7 +54,10 @@ void ProcMemMonitor::did_write(Task* t, const std::vector<Range>& ranges,
return;
}
- auto* task = static_cast<ReplayTask*>(*target->task_set().begin());
+ ReplayTask* task = static_cast<ReplayTask*>(target->first_running_task());
+ if (!task) {
+ return;
+ }
for (auto& r : ranges) {
auto bytes = t->read_mem(r.data.cast<uint8_t>(), r.length);
diff --git a/src/ThreadDb.cc b/src/ThreadDb.cc
index 00f2fa80c..e4e7540da 100644
--- a/src/ThreadDb.cc
+++ b/src/ThreadDb.cc
@@ -46,7 +46,10 @@ ps_err_e ps_pdread(struct ps_prochandle* h, psaddr_t addr, void* buffer,
// We need any task associated with the thread group. Here we assume
// that all the tasks in the thread group share VM, which is enforced
// by clone(2).
- rr::Task* task = *h->thread_group->task_set().begin();
+ rr::Task* task = h->thread_group->first_running_task();
+ if (!task) {
+ return PS_ERR;
+ }
task->read_bytes_helper(uaddr, len, buffer, &ok);
LOG(debug) << "ps_pdread " << ok;
return ok ? PS_OK : PS_ERR;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment