From f6a52e260b9d76074ea5c390f1b330619d6007e6 Mon Sep 17 00:00:00 2001 From: Joel Dice Date: Tue, 24 Nov 2009 19:16:22 -0700 Subject: [PATCH] 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. --- src/windows.cpp | 32 +++++++++++++++++++------------- 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/src/windows.cpp b/src/windows.cpp index f15c2996d2..4ac44e4d05 100644 --- a/src/windows.cpp +++ b/src/windows.cpp @@ -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(context.Eip), - reinterpret_cast(context.Ebp), - reinterpret_cast(context.Esp)); + visitor->visit(reinterpret_cast(context.Eip), + reinterpret_cast(context.Ebp), + reinterpret_cast(context.Esp)); #elif defined ARCH_x86_64 - visitor->visit(reinterpret_cast(context.Rip), - reinterpret_cast(context.Rbp), - reinterpret_cast(context.Rsp)); + visitor->visit(reinterpret_cast(context.Rip), + reinterpret_cast(context.Rbp), + reinterpret_cast(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,