2013-09-22 3 views
0

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

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

callstack

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

enter image description here

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

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

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

EDIT1: Да, я должен был более внимательно прочитать этот почтовый ящик вместо мгновенного нажатия кнопки «Отмена». Виноват.

+0

Помогает ли это? Http: // StackOverflow.com/questions/945193/how-do-i-find-the-stack-trace-in-visual-studio – us2012

+1

Нажмите «Повторить» в поле сообщения assert, и вы должны получить хороший диалог, который даст вам возможность отлаживать код , включая просмотр стоп-кадра. Для исключений: вы тоже можете это сделать: вы можете включить разбивку на исключение, которое будет выбрано, оно находится где-то в настройках. – David

+0

Возможный дубликат [Как получить полный стек вызовов в Visual Studio 2005?] (Http://stackoverflow.com/questions/111023/how-to-get-a-full-call-stack-in-visual-studio -2005) –

ответ

2

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

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

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

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

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

Смежные вопросы