如何在 Windows 上获取线程堆栈信息?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3918375/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to get thread stack information on Windows?
提问by user473750
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?
我通过CreateToolhelp32Snapshot
函数枚举了一个进程中的所有线程。我想为每个线程获取一些基本的堆栈信息。更具体地说,我想获得堆栈底部地址,如果可能的话,我想获得当前堆栈顶部地址。基本上这是~*k
在 WinDbg 中使用命令显示的信息。那么如何从线程的 ID 或 HANDLE 中获取堆栈信息呢?
回答by wj32
(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
.
要获得 的值esp
,只需使用GetThreadContext
.
回答by Thomas Johnstone
An easier way without having to involve the Windows Driver Kit is as so:
无需涉及 Windows 驱动程序工具包的更简单方法如下:
NT_TIB* tib = (NT_TIB*)__readfsdword(0x18);
size_t* stackBottom = (size_t*)tib->StackLimit;
size_t* stackTop = (size_t*)tib->StackBase;
回答by Mikhail Pilin
__readfsdword() works only for the current thread. So, the variant with NtQueryInformationThread() is more flexible.
__readfsdword() 仅适用于当前线程。因此,带有 NtQueryInformationThread() 的变体更加灵活。
Added some declarations which are missed in ntdll.h:
添加了一些在 ntdll.h 中遗漏的声明:
typedef enum _THREADINFOCLASS {
ThreadBasicInformation = 0,
} THREADINFOCLASS;
typedef LONG KPRIORITY;
typedef struct _CLIENT_ID {
HANDLE UniqueProcess;
HANDLE UniqueThread;
} CLIENT_ID;
typedef CLIENT_ID *PCLIENT_ID;
typedef struct _THREAD_BASIC_INFORMATION
{
NTSTATUS ExitStatus;
PVOID TebBaseAddress;
CLIENT_ID ClientId;
KAFFINITY AffinityMask;
KPRIORITY Priority;
KPRIORITY BasePriority;
} THREAD_BASIC_INFORMATION, *PTHREAD_BASIC_INFORMATION;
回答by plodoc
As fas as I know, Toolhelp works by making a copy of basic information on heaps, modules, processes and threads. This does not include the TEB block that contains the stack bottom address. I think you need to use another API, the debugger engine API, which offers functions to examine the stacks
据我所知,Toolhelp 的工作原理是复制有关堆、模块、进程和线程的基本信息。这不包括包含堆栈底部地址的 TEB 块。我认为您需要使用另一个 API,即调试器引擎 API,它提供检查堆栈的功能