Отладка Visual Studio C ++ с помощью стека вызовов

Я недавно начал изучать C ++, исходя из C # фона. Моя проблема в том, как обрабатываются исключения.

Если у меня есть nullptr где-то, что приводит к чтению из запрещенного местоположения, затем я получаю красивый callstack в VS, как это:

стек вызовов

Однако, если я выбрасываю свое собственное исключение или утверждение не выполняется, я не понимаю, что пошло не так. VS просто показывает окно ошибки:

введите описание изображения здесь

A: Это немного неудобно для меня, так как в C # я получу трассировку стека в обоих случаях. Есть ли способ напечатать трассировку стека? Или есть какой-нибудь плагин для VS для достижения этой функциональности?

B: И почему AccessViolationException отличается от наших собственных исключений? Почему у нас нет стека трассировки для ошибок утверждений?

C: Насколько плохо было бы создать собственную функцию assert, которая вызывала бы исключение AccessViolationException при сбое подтверждения?

РЕДАКТИРОВАТЬ1: Да, я должен был прочитать более внимательно этот ящик сообщений, вместо того, чтобы сразу нажать Abort. Виноват.

0

Решение

И почему AccessViolationException отличается от наших собственных исключений?

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

Поймать и обработать AV технически возможно, вы должны использовать Структурную обработку исключений. Это требует использования нестандартных ключевых слов __try и __except в MSVC ++. Но вы не должны этого делать, так как обработка исключения требует, чтобы вы также восстанавливали состояние вашей программы до того состояния, в котором она находилась до запуска кода, который не удался. Это невозможно сделать надежно, поскольку вы больше не можете рассуждать об этом состоянии, вы не знаете, какой код был пропущен исключением.

Вы можете заставить свою программу завершать работу довольно разумным способом, для этого необходимо использовать функцию winapi SetUnhandledExceptionFilter (). Эквивалент AppDomain.UnhandledException в C #. Все это, конечно, совершенно нестандартный C ++. Стандарт C ++ гласит, что соответствующая программа C ++ никогда не должна вызывать неопределенное поведение, и не указывает, что должно произойти, когда вы все равно это делаете.

В остальном это прямое следствие программирования, близкого к металлу. Есть много контрмер в управляемом коде для предотвращения попадания программы в такое состояние. Эти контрмеры не предоставляются бесплатно, нативный C ++ заботится о том, чтобы код работал максимально быстро. Потеря диагностики является частью этого компромисса. Не вызывайте неопределенное поведение.

2

Другие решения

Других решений пока нет …

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector