Для безопасной альтернативы попробуйте эти Перспективное дополнение Firefox
, Если эта ссылка не работает, пробуют этого: https://addons.mozilla.org/en-US/firefox/addon/perspectives /
Стек тоже работает не так, как вы ожидаете. Стек представляет собой линейную последовательность страниц, последняя (верхняя) из которых отмечена битом защиты страницы. При касании этой страницы защитный бит удаляется, и страницу можно использовать. Для дальнейшего роста выделена новая страничка.
Следовательно, вам нужен ответ, где размещена страница gaurd. Но метод, который вы предлагаете, затронет рассматриваемую страницу и в результате сделает недействительным то, что вы пытаетесь измерить.
Неинвазивный способ определить, имеет ли страница (стек) защитный бит, - через VirtualQuery ()
.
Windows не выделяет память стека немедленно; вместо этого он резервирует для него адресное пространство и фиксирует его постранично при обращении к нему. Прочтите эту страницу для получения дополнительной информации.
В результате адресное пространство стека состоит из трех смежных областей:
Это позволяет нам создать функцию. который получает размер стека (с детализацией размера страницы):
static size_t GetStackUsage()
{
MEMORY_BASIC_INFORMATION mbi;
VirtualQuery(&mbi, &mbi, sizeof(mbi));
// now mbi.AllocationBase = reserved stack memory base address
VirtualQuery(mbi.AllocationBase, &mbi, sizeof(mbi));
// now (mbi.BaseAddress, mbi.RegionSize) describe reserved (uncommitted) portion of the stack
// skip it
VirtualQuery((char*)mbi.BaseAddress + mbi.RegionSize, &mbi, sizeof(mbi));
// now (mbi.BaseAddress, mbi.RegionSize) describe the guard page
// skip it
VirtualQuery((char*)mbi.BaseAddress + mbi.RegionSize, &mbi, sizeof(mbi));
// now (mbi.BaseAddress, mbi.RegionSize) describe the committed (i.e. accessed) portion of the stack
return mbi.RegionSize;
}
Одна вещь, которую следует учитывать: CreateThread
позволяет указать начальный размер фиксации стека (через параметр dwStackSize
, когда флаг STACK_SIZE_PARAM_IS_A_RESERVATION
не установлен). Если этот параметр не равен нулю, наша функция вернет правильное значение только тогда, когда использование стека станет больше, чем значение dwStackSize
.
Вы можете использовать информацию в блоке информации о потоке Win32
Если вы хотите в потоке узнать, сколько места в стеке он использует, вы можете сделать что-то вроде этого:
#include <windows.h>
#include <winnt.h>
#include <intrin.h>
inline NT_TIB* getTib()
{
return (NT_TIB*)__readfsdword( 0x18 );
}
inline size_t get_allocated_stack_size()
{
return (size_t)getTib()->StackBase - (size_t)getTib()->StackLimit;
}
void somewhere_in_your_thread()
{
// ...
size_t sp_value = 0;
_asm { mov [sp_value], esp }
size_t used_stack_size = (size_t)getTib()->StackBase - sp_value;
printf("Number of bytes on stack used by this thread: %u\n",
used_stack_size);
printf("Number of allocated bytes on stack for this thread : %u\n",
get_allocated_stack_size());
// ...
}
Вы можете использовать функцию GetThreadContext () для определения текущего указателя стека потока. Затем используйте VirtualQuery (), чтобы найти базу стека для этого указателя. Вычитание этих двух указателей даст вам размер стека для данного потока.