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;
}
uint32_t XThread::StepToSafePoint() {
uint32_t XThread::StepToSafePoint(bool ignore_host) {
// This cannot be done if we're the calling thread!
if (IsInThread() && GetCurrentThread() == this) {
assert_always(
@ -906,12 +906,22 @@ uint32_t XThread::StepToSafePoint() {
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.
uint32_t pc = 0;
if (cpu_frames[0].type == cpu::StackFrame::Type::kGuest) {
auto& frame = cpu_frames[0];
if (first_frame.type == cpu::StackFrame::Type::kGuest) {
auto& frame = first_frame;
if (!frame.guest_pc) {
// Lame.
// Lame. The guest->host thunk is a "guest" function.
frame = cpu_frames[1];
}
@ -990,10 +1000,8 @@ uint32_t XThread::StepToSafePoint() {
pc = first_pc;
} else {
// 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);
return StepToSafePoint();
return StepToSafePoint(true);
}
} else {
// 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
// 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:
bool AllocateStack(uint32_t size);