Могу ли я получить трассировку стека для необработанных (Objective) исключений C ++? - PullRequest
6 голосов
/ 01 марта 2012

Я занимаюсь разработкой приложения для iOS, которое недавно расширило базу C ++. C ++ не моя сильная сторона, и я разочарован исключениями. То, что я ищу, - это способ получить трек стека к сайту (необработанного) исключения. Я скажу, что необработанный квалификатор не обязателен; Я бы остановился на любом исключении в качестве крайней меры, хотя необработанные исключения идеальны.

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

std::vector<int> my_vector;
my_vector.at(40) = 2; // Throws std::out_of_range

Приложение прервется на main(), и я получу сообщение в журнале, говорящее «прекратить вызывать выбрасывание исключения». Не полезно.

Помещение общих блоков try / catch выше уровня callstack также не помогает, потому что callstack разматывается при обработке исключений до точки перехвата, оставляя меня в неведении относительно фактического происхождения исключения. Это также относится и к предоставлению моего terminate_handler. Утверждения более полезны, но они требуют, чтобы я до некоторой степени предвидел условия ошибки, что я не всегда могу сделать. Я все еще хотел бы, чтобы отладчик мог вмешаться, даже если неожиданное исключение проходит через мои упреждающие assert() s.

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


В Objective C я могу поставить символическую точку останова на objc_exception_throw, и всякий раз, когда я что-то напортачу, я немедленно прерву выполнение и получу хорошую трассировку стека, чтобы я знал, где проблема. Очень полезно.

Я понимаю, что это поведение действительно полезно только из-за философских различий в обработке исключений между двумя языками. Объективные исключения C предназначены только для обозначения неисправимых ошибок. Задача обычной обработки ошибок выполняется с помощью кодов возврата ошибок. Это означает, что любое исключение Objective C является отличным кандидатом на точку останова для разработчика.

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

Ответы [ 3 ]

5 голосов
/ 01 марта 2012

Вы можете быстро установить разрыв на все условия C ++ броска в XCode:

  • cmd+6
  • " + " -> Добавить точку останова исключения
    • C ++ -> std::out_of_range
    • на ходу

Обновление

Если у вас их много для фильтрации, вы можете:

  • Создать символическую точку останова
  • Символ = __cxa_throw (может варьироваться в зависимости от библиотеки STD)
  • Действие> Команда отладчика = bt
  • Автоматически продолжить после eval = On

Команда bt регистрирует обратную трассировку. Сконфигурированный таким образом, он автоматически продолжится.

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

1 голос
/ 01 марта 2012

В приложении, которое я получаю для отладки со многими исключениями c ++, я оставляю «Catch C ++ Exceptions on Throw» выключенным, пока не доберусь до точки приложения, где оно будет выдавать исключение, затем я включаю эту опцию и обычноследующее исключение - это то, что я ищу.Это пробьет несколько уровней глубже, чем там, где ошибка, но стек не поврежден, так что вы можете понять, что происходит.

0 голосов
/ 01 марта 2012

Проверка PLCrashReporter . Мы используем его с нашим приложением (которое в значительной степени опирается на C ++), и оно производит трассировки стека даже для кода C ++.

Единственная проблема, с которой вы можете столкнуться, - это использование процедур сборки, которые не были написаны изначально для iOS (компилятор Apple использует R7 для удержания стекового фрейма для отслеживания символов, что не соответствует официальному EBI ARM)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...