LINUX.ORG.RU

Поймать переполнение стека в C++

 


1

3

По странным причинам задам простой вопрос:

А можно ли в C++ инструментом try/catch поймать переполнение стека? Если да, то можно пример?

P.S. причины почему не по-дак-дак-гоить простые и крайне смешные: возможный ответ тонет в бесконечном количестве статей ресурса stackoverflow, имя которого совпадает с главным ключевым словом :-)))

★★★

Последнее исправление: shaplov (всего исправлений: 1)
Ответ на: комментарий от Stil

ASAN

Спасибо, добрый человек, мне как раз надо поймать stack_overflow раньше ASan’а, чтобы он там где не надо (и там где можно случайно уйти в бесконечную рекурсию) не сработал…

shaplov ★★★
() автор топика
Ответ на: комментарий от fluorite

Переполнение стека - это не исключение с++.

Переполнение стека – это событие. ;-)

Можно ли о нем узнать используя механизм исключений?

shaplov ★★★
() автор топика
Последнее исправление: shaplov (всего исправлений: 1)

физически - можно самому себе сделать стек и ловить в сигнал его переполнение/исчерпание. Не обязательно C++.

В try/catch вряд-ли не попадёт, потому что стек уже тю-тю, переполнился, дальше некуда и плюсы нагнулись. Если только в том-же сигнале не предпринять меры (увеличить сегмент или лимит)

MKuznetsov ★★★★★
()

Ох сейчас у кого-то пригорит:

Note that some platforms do notify a program when a stack overflow occurs and allow the program to handle the error. On Windows, for example, an exception is thrown. This exception is not a C++ exception, though, it is an asynchronous exception. Whereas a C++ exception can only be thrown by a throw statement, an asynchronous exception may be thrown at any time during the execution of a program. This is expected, though, because a stack overflow can occur at any time: any function call or stack allocation may overflow the stack.

Ну и гляньте что на свете бывает, хотя-бы ради интереса.

alex0x08 ★★★
()

да можно

это механизм по которым сделано перепланирование в go языке

насколько помню доступно как минимум в gcc

а возможно только в gcc

там при переполнениии стека можно ловить это все через скажем хук

точно уже не помню, погуглите все же

voipdev
()

В Windows точно можно, переполнение стека обрабатывается как обычное SEH исключение.

В Линуксе вероятно придётся делать кастомный обработчик сигналов и сборку с асинхронными исключениями если хочется вызывать исключение из обработчика сигнала.

X512 ★★★★★
()
Ответ на: комментарий от theNamelessOne

Можно ли о нем узнать используя механизм исключений?

Скорее всего нет, по крайней мере портабельно, т.к.

А мне, что характерно, портабельно и не надо… Мне строго под линуксом достаточно…

shaplov ★★★
() автор топика
Ответ на: комментарий от MKuznetsov

физически - можно самому себе сделать стек и ловить в сигнал его переполнение/исчерпание. Не обязательно C++.

В try/catch вряд-ли не попадёт, потому что стек уже тю-тю, переполнился, дальше некуда и плюсы нагнулись. Если только в том-же сигнале не предпринять меры (увеличить сегмент или лимит)

А вот это выглядит как годный вариант…

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

А если там можно стек еще чуть увеличить и прекратить дальнейшую рекурсию (мне так можно на самом деле) то это вообще праздник какой-то…

Не подскажете место откуда начинать копать?

shaplov ★★★
() автор топика
Ответ на: комментарий от shaplov

копать в стороны:

  • mmap (выделять/ресайзить память с нужными аттрибутами),

  • всё про сигналы,

  • немного ассемблера или man clone или longjmp для работы в новом стеке

  • и про устройство С :-) чтобы изначально правильно всё положить в новый стек (параметры,возвраты)

собственно получится что запускаете full-stack корутину и ловите сигналы о срывах. Возможно есть готовые рецепты/библиотеки, корутины популярны. Фантастики нет, просто очень кропотливо

PS/ Чтобы стек можно было увеличивать вручную, придётся ещё обеспокоится о выравниваниях. И упороться в анализе причин

MKuznetsov ★★★★★
()
Последнее исправление: MKuznetsov (всего исправлений: 2)

Динамически нельзя. Можно наверное только измерить сколько % осталось, но непонятно в какой момент это делать. На каждый вызов – дорого как-то.

Статически можно по всему коду проанализировать самую жадную до стека цепочку вызовов через gcc -fstack-usage. Обычно это для микроконтроллеров используют, где стек измеряется килобайтами и нет рекурсии.

snizovtsev ★★★★★
()
Ответ на: комментарий от shaplov

А если там можно стек еще чуть увеличить и прекратить дальнейшую рекурсию

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

snizovtsev ★★★★★
()

Считать вложенные вызовы уже предлагали? Зная в каком месте их число число взлетает можно сузить рамки поиска.

А точно это переполнение стека? Может где-то в другом месте память затирается?

dvetutnev
()
Ответ на: комментарий от shaplov

Мне строго под линуксом достаточно…

В ядре есть опция:

Symbol: DEBUG_STACKOVERFLOW [=n]

Посмотри, как оно там реализовано.

PS: если разберешься в вопросе – расскажи, интересно.

soomrack ★★★★★
()
Последнее исправление: soomrack (всего исправлений: 1)

Может если запустить в qemu без всяких ускорялок и дебажить/отловить в нём хоть побитовое состояние программы, наверняка что-то подобное есть.

LINUX-ORG-RU ★★★★★
()