• C

GetThreadContext giving strange results.

I trying to get the thread context of another thread using GetThreadContext like this:
static CONTEXT threadContext; 
memset(&threadContext, 0, sizeof(CONTEXT)); 
threadContext.ContextFlags = CONTEXT_FULL; 
bool contextOk = GetThreadContext(threadHandle, &threadContext); 

Open in new window

sometimes the result make sense but sometimes I see that threadContext.EBP = 0
or that threadContext.EBP and threadContext.EIP are very very VERY far apart.

I do suspend the thread before I try this.
The process i'm looking at its thread context is compiled with Frame Pointer Omission DISABLED so I can't have FPO Frames.
GetLastError() returns 0.

What is going on?
Who is Participating?
UltraDogAuthor Commented:
no, I just ran into a method in the callstack with a FPO frame.
this method is in another DLL which IS compiled with FPO optimization and that's why I couldn't find its real EBP value.
UltraDogAuthor Commented:
Something intersting that I saw.
It always happens for the same EIP which is in NtDelayExecution.
In the msdn page on GetThreadContext, I observed that, the value of threadContext is set like this:
threadContext.ContextFlags = (CONTEXT_FULL);

But, in your code, I see this:
threadContext.ContextFlags = CONTEXT_FULL;

Why don't you put a parenthesis and give it a try - I don't know if it makes a difference. I am suggesting this based only on visual review.

And hope that you are checking the value of contextOk to see if it has succeeded.

And why don't you add the code:
before calling GetThreadContext(), so that, everything happens in a synchronous fashion.

This is what is written in Richter/Nassare's "Windows via C++ 5Ed" regarding SuspendThread() and GetThreadContext() vagaries:
DWORD SuspendThread(HANDLE hThread);

Any thread can call this function to suspend another thread (as long as you have the thread's handle). It goes without saying (but I'll say it anyway) that a thread can suspend itself but cannot resume itself. Like ResumeThread, SuspendThread returns the thread's previous suspend count. A thread can be suspended as many as MAXIMUM_SUSPEND_COUNT times (defined as 127 in WinNT.h). Note that SuspendThread is asynchronous with respect to kernel-mode execution, but user-mode execution does not occur until the thread is resumed.

In real life, an application must be careful when it calls SuspendThread because you have no idea what the thread might be doing when you attempt to suspend it. If the thread is attempting to allocate memory from a heap, for example, the thread will have a lock on the heap. As other threads attempt to access the heap, their execution will be halted until the first thread is resumed. SuspendThread is safe only if you know exactly what the target thread is (or might be doing) and you take extreme measures to avoid problems or deadlocks caused by suspending the thread.


Windows actually lets you look inside a thread's kernel object and grab its current set of CPU registers. To do this, you simply call GetThreadContext:

BOOL GetThreadContext( HANDLE hThread, PCONTEXT pContext);

To call this function, just allocate a CONTEXT structure, initialize some flags (the structure's ContextFlags member) indicating which registers you want to get back, and pass the address of the structure to GetThreadContext. The function then fills in the members you've requested.

You should call SuspendThread before calling GetThreadContext; otherwise, the thread might be scheduled and the thread's context might be different from what you get back. A thread actually has two contexts: user mode and kernel mode. GetThreadContext can return only the user-mode context of a thread. If you call SuspendThread to stop a thread but that thread is currently executing in kernel mode, its user-mode context is stable even though SuspendThread hasn't actually suspended the thread yet. But the thread cannot execute any more user-mode code until it is resumed, so you can safely consider the thread suspended and GetThreadContext will work.

Open in new window

UltraDogAuthor Commented:
I figured it out,
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.