Минимально возможный размер стека в Windows при использовании исключений C ++ (с использованием улучшенных контекстных волокон) - PullRequest
0 голосов
/ 30 июня 2018

Я использую Boost Context 1.67 для создания волокна (fcontext API). с минимально возможным размером стека в Windows 10.

Возможно, эта проблема связана не только с повышением контекста, но и с любым сценарием, в котором мы используем поток Windows с минимальным размером стека.

Я столкнулся с проблемами при использовании очень маленьких стеков (до 10 КБ) через исключения stackoverflow, которые вызваны внутренним исключение стека разматывания, выданное контекстом повышения, как показано ниже:

enter image description here

При использовании стека большего размера (> 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;
}

Повышающий контекст используется здесь только для выполнения переключения контекста с выделенным пользователем стеком, вероятно, проблема вызвана некоторыми ограничениями исключений MSVC C ++, которые, вероятно, требуют определенного минимального размера стека для работы. Кроме того, SetThreadStackGuarantee функция WinAPI не влияет на проблему.

Стек распределяется через malloc, как показано в примере.

Можно ли использовать в Windows стеки меньшего размера, чем 10 КБ, при использовании исключений C ++? Какие обстоятельства могут быть причиной ограничения здесь?

1 Ответ

0 голосов
/ 09 июля 2018

К сожалению, Windows API не предоставляет функцию или константу, возвращающую минимальное место в стеке.

Только для 32-битных исключений Windows (SEH) вызывает записи в стеке. В Win x64 используется обработка исключений на основе таблиц - записи для обработчиков исключений хранятся в разделе pdata. Так что обработка исключений на x64 не должна влиять на мин. пространство стека. Соглашение о вызовах x64 требует некоторого пространства - например, 32 байта «теневого пространства» + пространство для регистров XMM ... но для хранения регистров требуется всего несколько байтов.

Я думаю, что мин. пространство стека ограничено «кодом инструментария» (например, файлы cookie стека и т. д.) - возможно, это может контролироваться флагами компилятора.

boost.context выделяет память и использует ее в качестве стека (+ реализует переключение контекста). boost.fiber использует стек из boost.context и резервирует место (размещение нового) для структуры управления в верхней части стека каждого волокна (но это <1 КБ). </p>

У вас есть возможность использовать интервальную вложенность, чтобы протестировать минимально необходимое пространство стека вашего приложения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...