Created
July 16, 2021 14:08
-
-
Save rocallahan/eee63245a75b6f27b5dce4548e446191 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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