I enumerate all threads in a process through the CreateToolhelp32Snapshot
function. I would like to get some basic stack information for each thread. More specifically I would like to get stack bottom address and if possible I would like to get current stack top address. Basically this is the information displayed with the ~*k
command in WinDbg. So how can I obtain the stack information from the thread's ID or HANDLE?
To understand the thread state, it is necessary to look up the ThreadState property. I can do this in the MSDN article, Win32_Thread WMI class. The ThreadState values are shown here. Initialized.
The easiest way to find a specific thread is to first get the process handle, and then use that handle in a WMI filter. The following command obtains the handle for a running instance of Notepad, and then obtains the thread information. By using the Get-CimInstance Windows PowerShell 3.0 CIM cmdlet, I arrive at the following syntax.
The dates for TechEd 2013 in New Orleans, by the way, are June 3 – June 6. To find information about threads, I use the Win32_Thread WMI class. I found this by using the Get-CimClass cmdlet as shown here. The command and its associated output are shown in the following image. I can also do the same thing by using the Get-WmiObject cmdlet.
It is best to choose as small a stack size as possible and commit the stack that is needed for the thread or fiber to run reliably. Every page that is reserved for the stack cannot be used for any other purpose. A stack is freed when its thread exits. It is not freed if the thread is terminated by another thread.
(Definitions can be found here.)
To get stack boundaries:
THREAD_BASIC_INFORMATION basicInfo;
NT_TIB tib;
// Get TEB address
NtQueryInformationThread(YOUR_THREAD_HANDLE, ThreadBasicInformation, &basicInfo, sizeof(THREAD_BASIC_INFORMATION), NULL);
// Read TIB
NtReadVirtualMemory(YOUR_PROCESS_HANDLE, basicInfo.TebBaseAddress, &tib, sizeof(NT_TIB), NULL);
// Check tib.StackBase and tib.StackLimit
To get the value of esp
, simply use GetThreadContext
.
An easier way without having to involve the Windows Driver Kit is as so:
NT_TIB* tib = (NT_TIB*)__readfsdword(0x18);
size_t* stackBottom = (size_t*)tib->StackLimit;
size_t* stackTop = (size_t*)tib->StackBase;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With