Что делать, если для DLL требуется больший размер стека, чем для основного исполняемого приложения?

У меня есть механизм моделирования, написанный на Visual C++ 2010, и я реализую подключаемый модуль DLL на его основе для другого стороннего приложения.

Однако я получаю сообщение об ошибке переполнения стека, когда моя библиотека вызывается потоком стороннего приложения. После отладки выяснилось, что для DLL требуется больший размер стека, чем есть у потока. Можно ли как-то увеличить размер стека текущего потока?

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

Я думаю о создании собственного потока в DLL с большим размером стека и возвращении результатов в вызывающий поток, когда расчет завершится. Это правильный подход?

Спасибо, Михал


person Michał Fronczyk    schedule 10.06.2014    source источник
comment
Кажется, что моя DLL требует большего размера стека, чем у потока. Вы отладили это? Имеет ли поток необычно маленький размер стека? Размер стека по умолчанию (1 МБ) довольно велик. Если вы переполняете это, я бы проверил наличие безудержной рекурсии или больших буферов, объявленных в области действия функции. Если у вас есть большие буферы в стеке, попробуйте переместить их в кучу. Создание собственного потока — это способ получить больший стек, но имейте в виду, что вы можете просто скрыть реальную ошибку или недостаток дизайна.   -  person Adrian McCarthy    schedule 10.06.2014
comment
Я отредактировал ответ - да, я отладил это. Он имеет размер стека по умолчанию, но код выделяет большие буферы и структуры данных в стеке и требует около 10 МБ стека. Да, я могу переместить материал в кучу, но я хотел бы знать альтернативы, поскольку я хотел бы избежать изменения ядра модели моделирования только потому, что стороннее приложение имеет небольшой размер стека.   -  person Michał Fronczyk    schedule 10.06.2014
comment
Верно. Но я интегрирую код другого поставщика и не хочу его изменять.   -  person Michał Fronczyk    schedule 10.06.2014
comment
Бывают ситуации, когда нет контроля над использованием стека, и для того, чтобы все заработало, требуется лишь небольшое увеличение выделения. Я написал оболочку плагина, которая приклеивает dll, которую я не контролирую, к внешнему приложению с выделением стека по умолчанию. Я могу исправить свою личную копию исполняемого файла с помощью editbin, но я не знаю, как я могу применить это решение к пользователям моего плагина.   -  person Eli S    schedule 30.11.2017


Ответы (2)


Я предлагаю вам первое проверить, сколько места в стеке вы фактически используете. Вы выделяете большие объекты в стеке? Использует ли ваша программа значительную глубину рекурсии? Напишите приложение тестового хука, которое вы можете связать со своей DLL, и проверьте, сколько места в стеке вы используете.

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

Если вы выполняете значительную рекурсию, вы можете изучить использование цикла со стеком на основе кучи, поддерживаемым вашей DLL, а не полагаться на стек приложения.

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

person Mark B    schedule 10.06.2014
comment
У меня есть доступ к исходному коду механизма моделирования, но он принадлежит другому поставщику, и мне было интересно, могу ли я что-то сделать, не изменяя их код. - person Michał Fronczyk; 10.06.2014

Visual Studio предоставляет два варианта изменения размера стека по умолчанию (1 МБ):

/F для компилятора: https://docs.microsoft.com/cpp/build/reference/f-set-stack-size

/STACK для компоновщика: https://docs.microsoft.com/cpp/build/reference/stack

person Piotr Bocian    schedule 15.08.2017