Как получить информацию о стеке потоков в Windows? - PullRequest
8 голосов
/ 12 октября 2010

Я перечисляю все потоки в процессе с помощью функции CreateToolhelp32Snapshot.Я хотел бы получить основную информацию о стеке для каждого потока.Более конкретно, я хотел бы получить адрес нижнего стека и, если возможно, я хотел бы получить текущий адрес верхнего стека.В основном это информация, отображаемая с помощью команды ~*k в WinDbg.Итак, как я могу получить информацию о стеке из ID потока или HANDLE?

Ответы [ 4 ]

9 голосов
/ 13 октября 2010

(Определения можно найти здесь .)

Чтобы получить границы стека:

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

Чтобы получить значение esp, просто используйте GetThreadContext.

1 голос
/ 24 июля 2013

__ readfsdword () работает только для текущего потока. Таким образом, вариант с NtQueryInformationThread () более гибок.

Добавлены некоторые объявления, которые отсутствуют в 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;
1 голос
/ 06 июля 2012

Более простой способ без использования комплекта драйверов Windows:

NT_TIB* tib = (NT_TIB*)__readfsdword(0x18);
size_t* stackBottom = (size_t*)tib->StackLimit;
size_t* stackTop = (size_t*)tib->StackBase;
0 голосов
/ 13 октября 2010

Насколько я знаю, Toolhelp работает, делая копии базовой информации о кучах, модулях, процессах и потоках. Это не включает блок TEB, который содержит нижний адрес стека. Я думаю, что вам нужно использовать другой API, API отладчика, который предлагает функции для проверки стеков

...