Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get thread stack information on Windows?

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?

like image 632
user473750 Avatar asked Oct 12 '10 19:10

user473750


People also ask

How do I find the thread state?

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.

How do I find a specific thread in Notepad?

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.

Where can I find information about threads in TechEd 2013?

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.

What is the best way to choose a stack size?

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.


2 Answers

(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.

like image 166
wj32 Avatar answered Oct 12 '22 05:10

wj32


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;
like image 25
Thomas Johnstone Avatar answered Oct 12 '22 07:10

Thomas Johnstone