Solved

GetThreadContext giving strange results.

Posted on 2011-09-15
4
712 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

NAS Cloud Backup Strategies

This article explains backup scenarios when using network storage. We review the so-called “3-2-1 strategy” and summarize the methods you can use to send NAS data to the cloud

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
SQL Statment to match two tables in c# 6 79
C++ check and remove last word from a string 5 176
Problem to ASCII 1 184
C++ :Change value from  DisableCMD registry 4 60
An Outlet in Cocoa is a persistent reference to a GUI control; it connects a property (a variable) to a control.  For example, it is common to create an Outlet for the text field GUI control and change the text that appears in this field via that Ou…
Windows programmers of the C/C++ variety, how many of you realise that since Window 9x Microsoft has been lying to you about what constitutes Unicode (http://en.wikipedia.org/wiki/Unicode)? They will have you believe that Unicode requires you to use…
The goal of this video is to provide viewers with basic examples to understand and use structures in the C programming language.
The goal of this video is to provide viewers with basic examples to understand and use switch statements in the C programming language.

831 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