Fix infinite loop in StepToSafePoint after stepping to an address once

This commit is contained in:
Dr. Chat 2015-12-12 13:36:00 -06:00 committed by Ben Vanik
parent 4cbe219476
commit 6f4626118e
2 changed files with 18 additions and 8 deletions

View File

@ -882,7 +882,7 @@ uint32_t XThread::StepIntoBranch(uint32_t pc) {
return pc; return pc;
} }
uint32_t XThread::StepToSafePoint() { uint32_t XThread::StepToSafePoint(bool ignore_host) {
// This cannot be done if we're the calling thread! // This cannot be done if we're the calling thread!
if (IsInThread() && GetCurrentThread() == this) { if (IsInThread() && GetCurrentThread() == this) {
assert_always( assert_always(
@ -906,12 +906,22 @@ uint32_t XThread::StepToSafePoint() {
return 0; return 0;
} }
auto& first_frame = cpu_frames[0];
if (ignore_host) {
for (size_t i = 0; i < count; i++) {
if (cpu_frames[i].type == cpu::StackFrame::Type::kGuest &&
cpu_frames[i].guest_pc) {
first_frame = cpu_frames[i];
}
}
}
// Check if we're in guest code or host code. // Check if we're in guest code or host code.
uint32_t pc = 0; uint32_t pc = 0;
if (cpu_frames[0].type == cpu::StackFrame::Type::kGuest) { if (first_frame.type == cpu::StackFrame::Type::kGuest) {
auto& frame = cpu_frames[0]; auto& frame = first_frame;
if (!frame.guest_pc) { if (!frame.guest_pc) {
// Lame. // Lame. The guest->host thunk is a "guest" function.
frame = cpu_frames[1]; frame = cpu_frames[1];
} }
@ -990,10 +1000,8 @@ uint32_t XThread::StepToSafePoint() {
pc = first_pc; pc = first_pc;
} else { } else {
// Step forward and run this logic again. // Step forward and run this logic again.
// FIXME: This is broken. Runs this code in an infinite loop because
// breakpoints call out of the guest.
StepToAddress(first_pc + 4); StepToAddress(first_pc + 4);
return StepToSafePoint(); return StepToSafePoint(true);
} }
} else { } else {
// We've managed to catch a thread before it called into the guest. // We've managed to catch a thread before it called into the guest.

View File

@ -190,7 +190,9 @@ class XThread : public XObject {
// Steps the thread to a point where it's safe to terminate or read its // Steps the thread to a point where it's safe to terminate or read its
// context. Returns the PC after we've finished stepping. // context. Returns the PC after we've finished stepping.
uint32_t StepToSafePoint(); // Pass true for ignore_host if you've stopped the thread yourself
// in host code you want to ignore.
uint32_t StepToSafePoint(bool ignore_host = false);
protected: protected:
bool AllocateStack(uint32_t size); bool AllocateStack(uint32_t size);