GDB позволяет ловить исключения, когда они выбрасываются и когда их ловят. Но иногда строка, в которую выдается исключение, не имеет символов, или точка прерывания срабатывает во время обработки исключения. Как мне проверить значение текущего исключения?
обновленный
Вот некоторая информация из Руководства GDB
В настоящее время существуют некоторые ограничения в обработке исключений в C ++ (catch
кинь и лови лови) в gdb:Если вы вызываете функцию в интерактивном режиме, GDB обычно возвращает управление
Вы, когда функция завершила выполнение. Если вызов поднимает
исключение, однако, вызов может обойти механизм, который возвращает
контролировать вас и заставить вашу программу либо прервать, либо просто
продолжать работать, пока не достигнет точки останова, ловит сигнал, что GDB
слушает или выходит. Это так, даже если вы установили
точка ловли для исключения; точки перехвата исключений отключены
в интерактивных звонках. Вы не можете вызвать исключение в интерактивном режиме.
Вы не можете установить обработчик исключений в интерактивном режиме. Иногда ловить
не лучший способ отладки обработки исключений: если вам нужно знать
именно там, где возникает исключение, лучше остановиться
вызывается обработчик исключений, так как таким образом вы можете видеть стек
до того, как происходит раскрутка. Если вы установите точку останова в
вместо обработчика исключений может быть нелегко выяснить, где
исключение было поднято.Чтобы остановить непосредственно перед вызовом обработчика исключений, вам нужно
знание реализации. В случае GNU C ++, исключения
вызываются вызовом библиотечной функции с именем __raise_exception, которая
имеет следующий интерфейс ANSI C:/* addr is where the exception identifier is stored. id is the exception identifier. */ void __raise_exception (void **addr, void *id); To make the debugger catch all exceptions before any stack unwinding takes place,
установить точку останова на __raise_exception (см. Точки останова; Точки наблюдения;
и исключения).
Что сказал
Это зависит от кода и того, где вы находитесь в стеке. Если вы действительно поймали исключение, как в:
try { .... } catch (std::exception &e) {
//do stuff
}
Вы могли бы попробовать распечатать e.what()
Или посмотрите на членов исключения. Если вы просто поймали это как (…), тогда я не уверен, что вы сможете собрать.
Еще одна вещь, которую вы можете сделать, это перехватить throw в gdb и перехватить catch, если вы действительно хотите следовать всему потоку.
gdb> catch catch
gdb> catch throw
Таким образом, вы получите точки останова прямо перед тем, как будут сгенерированы исключения, и когда они будут перехвачены, вы можете пройтись по стеку, чтобы получить больше информации о происходящем. Даже если вы находитесь в другой точке останова, вы сможете пройти вверх по стеку (используя вверх или вниз), чтобы получить кадр, в котором видимо исключение.
Более ранние ответы были правильными при написании (в 2013 году), но с тех пор gdb и libstdc ++ изменились.
В libstdc ++ теперь есть несколько хуков, которые позволяют gdb лучше взаимодействовать с системой исключений. В частности, теперь GDB предоставляет достаточно информации для предоставления $_exception
удобная переменная для пользователя. Эта переменная содержит генерируемое исключение. Это действительно только в том месте, где происходит исключение; который вы можете остановить при использовании catch catch
,
Увидеть страница из руководства для деталей.
Краткий ответ: вы не можете, потому что большая часть работы по обработке исключений выполняется вне вашей программы и, следовательно, выходит за рамки GDB.
Объяснил ответ:
иногда выбрасывается строка, исключающая символы
Если двоичный файл, который вы отлаживаете, не имеет отладочных символов, то двоичный файл, вероятно, будет удален, и вы вообще не сможете ничего узнать о типах / значениях чего-либо.
Как мне проверить значение текущего исключения?
Я думаю, что вы предполагаете, что исключением является языковая функция, которую может проверить gdb; на самом деле исключение в C ++ представляет собой сочетание возможностей C ++ как языка, libc ++ и ABI. И может даже быть больше чем одно активное текущее исключение.
Как указывает UpAndAdam, вы можете установить точку останова в блоке catch с помощью спецификатора типа, а затем проверить этот элемент, но я подозреваю, что ваша проблема в тех случаях, когда вы обнаружите «catch (…)». В этих случаях вы не сможете много узнать о текущем исключении, если не углубитесь в реализацию обработки исключений.
С очень коротким и неполным описанием мы могли бы сказать, что бросить исключение:
Сейчас трудно говорить о деталях, потому что большая часть обработки исключений зависит от вашей цепочки инструментов (компилятор, платформа, архитектура, libc ++ и т. Д.), Но в большинстве случаев «catch (…)» даже не получит исходное исключение в качестве аргумента. В любом случае, чтобы как-то ответить на ваш вопрос: в gcc с libc ++ от gnu вы можете попробовать что-то вроде этого:
В любом случае вам, вероятно, придется потратить немало времени, пытаясь понять, как обработка исключений реализована на вашей платформе. Если вы хотите прочитать немного больше об обработке исключений, в прошлом я потратил некоторое время на написание темы @ http://monoinfinito.wordpress.com/series/exception-handling-in-c/. Это не официальный источник, но в нем есть ссылки на спецификации каждой части, связанной с обработкой исключения.