Я использую boost context 1.67 для создания волокна (fcontext API) с минимально возможным размером стека в Windows 10.
Вероятно, эта проблема характерна не только для повышения контекста и применима к любому сценарию, в котором мы используем поток Windows с минимальным размером стека.
Я столкнулся с проблемами при использовании очень маленьких стеков (менее 10 КБ) из-за исключений stackoverflow, которые вызваны внутренним исключением раскрутки стека, вызванным контекстом повышения, как показано ниже:
При использовании большего стека (> 10 КБ) проблем не возникает.
Для воспроизведения достаточно следующего примера:
#include <memory>
#include <utility>
#include <boost/context/all.hpp>
#define STACK_SIZE 8000
struct my_allocator
{
boost::context::stack_context allocate()
{
void* memory = std::malloc(STACK_SIZE);
return {STACK_SIZE,
static_cast<char*>(memory) +
STACK_SIZE};
}
void deallocate(
boost::context::stack_context& context)
{
std::free(static_cast<char*>(context.sp) -
STACK_SIZE);
}
};
int main(int, char**)
{
boost::context::fiber fiber(
std::allocator_arg, my_allocator{},
[](boost::context::fiber&& sink) mutable {
// ...
return std::move(sink);
});
// Will cause a stack unwind exception and
// reproduces the issue
return 0;
}
Контекст Boost используется здесь только для выполнения переключения контекста с выделенным пользователем стеком, возможно, проблема вызвана некоторыми ограничениями исключений MSVC C++, которые, вероятно, требуют для работы определенного минимального размера стека. Также функция SetThreadStackGuarantee
WinAPI никак не влияет на проблему.
Стек выделяется через malloc, как показано в примере.
Можно ли использовать стеки меньше 10 КБ в Windows при использовании исключений C++? Какое обстоятельство, возможно, вызывает здесь ограничение?