Solved

GetThreadContext giving strange results.

Posted on 2011-09-15
4
703 Views
Last Modified: 2012-06-27
Hi!
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?
0
Comment
Question by:UltraDog
  • 3
4 Comments
 
LVL 1

Author Comment

by:UltraDog
ID: 36545177
Something intersting that I saw.
It always happens for the same EIP which is in NtDelayExecution.
0
 
LVL 8

Expert Comment

by:ssnkumar
ID: 36547347
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:
SuspendThread(threadHandle);
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

0
 
LVL 1

Accepted Solution

by:
UltraDog earned 0 total points
ID: 36548910
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.
0
 
LVL 1

Author Closing Comment

by:UltraDog
ID: 36572250
I figured it out,
0

Featured Post

Highfive Gives IT Their Time Back

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

Join & Write a Comment

Suggested Solutions

Preface I don't like visual development tools that are supposed to write a program for me. Even if it is Xcode and I can use Interface Builder. Yes, it is a perfect tool and has helped me a lot, mainly, in the beginning, when my programs were small…
This tutorial is posted by Aaron Wojnowski, administrator at SDKExpert.net.  To view more iPhone tutorials, visit www.sdkexpert.net. This is a very simple tutorial on finding the user's current location easily. In this tutorial, you will learn ho…
The goal of this video is to provide viewers with basic examples to understand recursion in the C programming language.
Video by: Grant
The goal of this video is to provide viewers with basic examples to understand and use nested-loops in the C programming language.

744 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

15 Experts available now in Live!

Get 1:1 Help Now