Обработка переполнений стека во встроенных системах

Этот вопрос так открыт, что трудно дать корректный ответ. Я мог сказать Вам, что Наблюдатель шаблон важен в MVC (и для webapplication), и это был бы хороший ответ. Обо всем шаблоне разработки, которые существуют, распространены в большом веб-приложении. Вы потребуете для использования [приблизительно 118], Фабрика , чтобы создать объект complexe и получить доступ к некоторому разделу требует [приблизительно 119] Фасада .

, Если бы Вы хотите больше "подсказок" или хорошая практика вместо шаблон разработки , я предложил бы, чтобы Вы использовали МОК и использование хороших Платформа вместо того, чтобы запуститься с нуля. Я могу предложить, Вы для объяснения преимущества наличия пользы механизм ORM для управления Вами слой постоянства быстрее также (обычно может прибывать из Платформы также).

8
задан Ether 2 February 2010 в 06:28
поделиться

4 ответа

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

Прежде чем вы сможете «обработать» переполнение стека, вы должны идентифицировать его. Хороший способ сделать это - загрузить в стек шаблон во время инициализации, а затем отслеживать, какая часть шаблона исчезает во время выполнения. Таким образом вы можете определить наивысшую точку, которой достиг стек.

Алгоритм проверки шаблона должен выполняться в направлении, противоположном увеличению стека. Итак, если стек вырастет с 0x1000 до 0x2000, тогда ваша проверка шаблона может начинаться с 0x2000 для повышения эффективности. Если ваш шаблон был 0xAA, а значение 0x2000 содержит что-то отличное от 0xAA, вы знаете, что, вероятно, произошло какое-то переполнение.

Вам также следует рассмотреть возможность размещения пустого буфера RAM сразу после стека, чтобы при обнаружении переполнения вы может выключить систему без потери данных. Если сразу за стеком следуют данные кучи или SRAM, то обнаружение переполнения будет означать, что вы уже испытали повреждение. Ваш буфер защитит вас немного дольше. На 32-битном микроконтроллере у вас должно быть достаточно ОЗУ, чтобы обеспечить хотя бы небольшой буфер.

Вам также следует подумать о размещении пустого буфера RAM сразу после стека, чтобы в случае обнаружения переполнения вы могли выключить систему без потери данных. Если сразу за стеком следуют данные кучи или SRAM, то обнаружение переполнения будет означать, что вы уже испытали повреждение. Ваш буфер будет защищать вас немного дольше. На 32-битном микроконтроллере у вас должно быть достаточно ОЗУ, чтобы обеспечить хотя бы небольшой буфер.

Вам также следует подумать о размещении пустого буфера RAM сразу после стека, чтобы в случае обнаружения переполнения вы могли выключить систему без потери данных. Если сразу за стеком следуют данные кучи или SRAM, то обнаружение переполнения будет означать, что вы уже испытали повреждение. Ваш буфер будет защищать вас немного дольше. На 32-битном микроконтроллере у вас должно быть достаточно ОЗУ, чтобы обеспечить хотя бы небольшой буфер.

2
ответ дан 5 December 2019 в 10:43
поделиться

В идеале вы пишете свой код с использованием статического стека (без рекурсивных вызовов). Затем вы можете оценить максимальное использование стека с помощью:

  1. статического анализа (с использованием инструментов)
  2. измерения использования стека при выполнении кода с полным покрытием кода (или с максимально возможным покрытием кода до тех пор, пока у вас не появится разумная уверенность в том, что вы установили степень использования стека, при условии, что ваш редко запускаемый код не использует больше стека, чем обычные пути выполнения)

Но даже при этом вы все равно хотите иметь средства обнаружения , а затем обрабатывает переполнение стека , если оно происходит, если это вообще возможно, для большей устойчивости. Это может быть особенно полезно на этапе разработки проекта. Некоторые методы обнаружения переполнения :

  1. Если процессор поддерживает прерывание чтения / записи памяти (т. Е. Прерывание точки останова доступа к памяти), то его можно настроить так, чтобы он указывал на самый дальний экстент области стека.
  2. В конфигурации карты памяти установите небольшой ( или большой) блок ОЗУ, который является областью «защиты стека». Заполните его известными значениями. Во встроенном программном обеспечении регулярно (как можно чаще) проверяйте содержимое этой области. Если он когда-либо изменится, предположим, что произошло переполнение стека.

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

  1. записать ошибку. прерывание от точки останова доступа к памяти), то его можно настроить так, чтобы оно указывало на самый дальний экстент области стека.
  2. В конфигурации карты памяти установите небольшой (или большой) блок ОЗУ, который является областью «защиты стека». Заполните его известными значениями. Во встроенном программном обеспечении регулярно (как можно чаще) проверяйте содержимое этой области. Если он когда-либо изменится, предположим, что произошло переполнение стека.

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

  1. записать ошибку. прерывание от точки останова доступа к памяти), то его можно настроить так, чтобы оно указывало на самый дальний экстент области стека.
  2. В конфигурации карты памяти установите небольшой (или большой) блок ОЗУ, который является областью «защиты стека». Заполните его известными значениями. Во встроенном ПО регулярно (как можно чаще) проверяйте содержимое этой области. Если он когда-либо изменится, предположим, что произошло переполнение стека.

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

  1. записать ошибку. Заполните его известными значениями. Во встроенном ПО регулярно (как можно чаще) проверяйте содержимое этой области. Если он когда-либо изменится, предположим, что произошло переполнение стека.

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

  1. записать ошибку. Заполните его известными значениями. Во встроенном ПО регулярно (как можно чаще) проверяйте содержимое этой области. Если он когда-либо изменится, предположим, что произошло переполнение стека.

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

  1. записать ошибку. ваша программная логика почти наверняка недействительна. Итак, все, что вы можете сделать, это

    1. записать ошибку. ваша программная логика почти наверняка недействительна. Итак, все, что вы можете сделать, это

      1. записать ошибку.
        1. Регистрация ошибки очень полезна, потому что в противном случае симптомы (неожиданные перезагрузки) могут быть очень трудно диагностировать.
        2. Предостережение: процедура регистрации должна иметь возможность надежно работать даже в сценарии с поврежденным стеком. Рутина должна быть простой. Т.е. с поврежденным стеком вы, вероятно, не сможете попытаться записать в EEPROM, используя свою причудливую фоновую задачу записи EEPROM. Возможно, просто зарегистрируйте ошибку в структуре, зарезервированной для этой цели, в ОЗУ без инициализации, которое затем можно будет проверить после перезагрузки.
      2. Перезагрузка (или, возможно, завершение работы, особенно если ошибка повторяется повторно)
        1. Возможная альтернатива: перезапустить только конкретную задачу, если вы используете RTOS, и ваша система спроектирована таким образом, что повреждение стека изолировано, и все другие задачи могут справиться с перезапуском этой задачи. Это потребует серьезного внимания при проектировании.
12
ответ дан 5 December 2019 в 10:43
поделиться

Произошло переполнение стека, память стека исчерпана из-за слишком большого стека вызовов ? например, слишком многоуровневая рекурсивная функция.

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

Имеется статический исходный код инструменты анализа, такие как GnatStack, StackAnalyzer от AbsInt и Bound-T, которые можно использовать для определения или предположения о максимальном размере стека времени выполнения.

1
ответ дан 5 December 2019 в 10:43
поделиться

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

Настройте область памяти в MMU, которая будет использоваться для стека. Он должен быть ограничен двумя областями памяти, к которым MMU не разрешает доступ. Когда ваше приложение запущено, вы получите исключение / прерывание, как только переполните стек.

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

Я успешно использовал это на процессорах PPC и AVR32. Когда вы начинаете использовать MMU, вы чувствуете, что это пустая трата времени, поскольку вы прекрасно обходились без него в течение многих лет, но как только вы увидите преимущества исключения именно в том месте, где возникает проблема с памятью, вы никогда не вернетесь назад. MMU также может обнаруживать обращения с нулевым указателем, если вы запрещаете доступ к памяти к нижнему парку вашего RAM.

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

В дополнение к этому процессор с MMU обычно также имеет много оперативной памяти, ваша программа с гораздо меньшей вероятностью переполнит ваш стек, и вы этого не сделаете. Не нужно настраивать все, чтобы ваше приложение работало правильно с небольшим объемом памяти.

Альтернативой этому могло бы быть использование средств отладки процессора для прерывания доступа к памяти к концу вашего стека. Вероятно, это будет зависеть от процессора.

1
ответ дан 5 December 2019 в 10:43
поделиться
Другие вопросы по тегам:

Похожие вопросы: