specify CONTEXT::ContextFlags before calling GetThreadContext

Previously, we assumed that the "context" parameter to
GetThreadContext was only an output parameter, but it actually uses at
the value of CONTEXT::ContextFlags on entry to decide what parts of
the structure to fill in.  We were getting lucking most of the time,
because whatever garbage was on the stack at that location had the
necessary bits set.  When we weren't so lucky, we got all zeros for
the register values which sometimes lead to a crash depending on the
state of the thread being examined.
This commit is contained in:
Joel Dice 2009-11-24 19:16:22 -07:00
parent 9f14d63592
commit f6a52e260b

View File

@ -616,26 +616,32 @@ class MySystem: public System {
ACQUIRE(this, mutex);
bool success = false;
int rv = SuspendThread(target->thread);
expect(this, rv != -1);
if (rv != -1) {
CONTEXT context;
memset(&context, 0, sizeof(CONTEXT));
context.ContextFlags = CONTEXT_CONTROL;
rv = GetThreadContext(target->thread, &context);
CONTEXT context;
rv = GetThreadContext(target->thread, &context);
expect(this, rv);
if (rv) {
#ifdef ARCH_x86_32
visitor->visit(reinterpret_cast<void*>(context.Eip),
reinterpret_cast<void*>(context.Ebp),
reinterpret_cast<void*>(context.Esp));
visitor->visit(reinterpret_cast<void*>(context.Eip),
reinterpret_cast<void*>(context.Ebp),
reinterpret_cast<void*>(context.Esp));
#elif defined ARCH_x86_64
visitor->visit(reinterpret_cast<void*>(context.Rip),
reinterpret_cast<void*>(context.Rbp),
reinterpret_cast<void*>(context.Rsp));
visitor->visit(reinterpret_cast<void*>(context.Rip),
reinterpret_cast<void*>(context.Rbp),
reinterpret_cast<void*>(context.Rsp));
#endif
success = true;
}
rv = ResumeThread(target->thread);
expect(this, rv != -1);
rv = ResumeThread(target->thread);
expect(this, rv != -1);
}
return 0;
return (success ? 0 : 1);
}
virtual uint64_t call(void* function, uintptr_t* arguments, uint8_t* types,