Доступный размер стека для потока C++
Использую Windows 10, Visual Studio 2019 Программа генерирует потоки. Мне нужно добавить функциональность, указывающую мне, какой размер стека доступен в любое время выполнения.
#include <iostream>
#include <thread>
void thread_function()
{
//AvailableStackSize()?
//Code1 //varibales on stack allocation + function call
//AvailableStackSize()? it should decrease
//Code2 //varibales on stack allocation + function call
//AvailableStackSize()? it should decrease
//Code3 //varibales on stack allocation + function call
//AvailableStackSize()? it should decrease
}
int main()
{
std::thread t(&thread;_function);
std::cout << "main thread\n";
std::thread t2 = t;
t2.join();
return 0;
}
Я пытаюсь использовать. Но я не знаю, как мне продолжить. Я просто могу узнать, каков общий размер стека. Недоступный.
bool AvailableStackSize()
{
// Get the stack pointer
PBYTE pEsp;
_asm {
mov pEsp, esp
};
// Query the accessible stack region
MEMORY_BASIC_INFORMATION mbi;
VERIFY(VirtualQuery(pEsp, &mbi, sizeof(mbi)));
return mbi.RegionSize;//This is a total size! what is an available? Where guard is located?
}
Возможно, я также могу проверить, есть ли какой-либо адрес внутри стека
PVOID add;
(add>= mbi.BaseAddress) && (add < PBYTE(mbi.BaseAddress) + mbi.RegionSize);
Я видел несколько подобных вопросов, но на 100% никто не отвечает. Как правильно получить доступный размер стека?
1 ответ
Поскольку стек растет вниз, это разница между потенциальным низом стека и концом того, что используется в настоящее время. Кстати, вам не нужна встроенная сборка, потому что вы знаете, что локальные переменные помещаются в стек.
__declspec(noinline) size_t AvailableStackSize()
{
// Query the accessible stack region
MEMORY_BASIC_INFORMATION mbi;
VERIFY(VirtualQuery(&mbi, &mbi, sizeof(mbi)));
return uintptr_t(&mbi) - uintptr_t(mbi.AllocationBase);
}
Это будет немного отличаться от того, что фактически доступно в вызывающей программе, потому что при вызове функции использовались некоторые (для хранения адреса возврата и любых сохраненных регистров). И вам нужно будет выяснить, появляется ли последняя защитная страница в том жеVirtualQuery
результат или соседний.
Но это общий подход.