Я работаю над многопоточным приложением и хочу отлаживать его с помощью GDB.
Проблема в том, что одна из моих тем продолжает умирать с сообщением:
pure virtual method called
terminate called without an active exception
Abort
Я знаю причину этого сообщения, но понятия не имею, где оно происходит в моей цепочке. Обратная трассировка действительно была бы полезна.
Когда я запускаю свое приложение в GDB, оно приостанавливается каждый раз, когда поток приостанавливается или возобновляется. Я хочу, чтобы мое приложение продолжало работать нормально, пока один из потоков не умрет с этим исключением, после чего все должно остановиться, чтобы я мог получить обратную трассировку.
handle SIGUSR1 pass noprint nostop
Ответы:
Вы можете попробовать использовать "catchpoint" (
catch throw
), чтобы остановить отладчик в точке, где генерируется исключение.Следующий отрывок из руководства gdb описывает функцию точки перехвата.
5.1.3 Установка точек перехвата
Вы можете использовать точки перехвата, чтобы отладчик останавливался при определенных видах программных событий, таких как исключения C ++ или загрузка разделяемой библиотеки. Используйте команду catch, чтобы установить точку перехвата.
поймать событие
бросить
поймать
exec
вилка
vfork
загрузить или загрузить имя библиотеки
выгрузить или выгрузить имя библиотеки
событие tcatch
Используйте
info break
команду для вывода списка текущих точек перехвата.В настоящее время существуют некоторые ограничения для обработки исключений C ++ (catch throw и catch catch) в GDB:
Если вы вызываете функцию в интерактивном режиме, GDB обычно возвращает вам управление, когда функция завершает выполнение. Однако, если вызов вызывает исключение, вызов может обойти механизм, который возвращает вам управление, и привести к тому, что ваша программа либо прервется, либо просто продолжит выполнение, пока не достигнет точки останова, не перехватит сигнал, который GDB ожидает, или завершится. Это так, даже если вы установили точку перехвата для исключения; точки перехвата исключений отключены в интерактивных вызовах.
Вы не можете создать исключение в интерактивном режиме.
Вы не можете установить обработчик исключений в интерактивном режиме.
Иногда перехват - не лучший способ отладки обработки исключений: если вам нужно точно знать, где возникает исключение, лучше остановиться до вызова обработчика исключения, так как таким образом вы можете увидеть стек до того, как произойдет какая-либо раскрутка. Если вместо этого вы установите точку останова в обработчике исключений, может быть нелегко выяснить, где возникло исключение.
Чтобы остановить работу непосредственно перед вызовом обработчика исключений, вам необходимо знать реализацию. В случае GNU C ++ исключения вызываются вызовом библиотечной функции с именем __raise_exception, которая имеет следующий интерфейс ANSI C:
Чтобы отладчик перехватил все исключения до того, как произойдет разворачивание стека, установите точку останова на __raise_exception (see section Точки останова; точки наблюдения; и исключения).
С условной точкой останова (см. Раздел «Условия останова»), которая зависит от значения id, вы можете остановить свою программу при возникновении определенного исключения. Вы можете использовать несколько условных точек останова, чтобы остановить вашу программу при возникновении любого из ряда исключений.
источник
catch throw std::runtime_exception
.Установите точку останова на __pure_virtual
источник
FWIW, видимо, в gcc 4.1 изменилось соответствующее имя функции и в этой функции надо установить точку останова.
__cxa_pure_virtual
источник
Только ниже у меня работал с gdb 8.3:
"catch throw" или "break __cxx_throw" у меня не работали.
источник