Вопрос по c++, polymorphism, multicore, debugging, gdb – Запустите приложение в GDB, пока не возникнет исключение

93

Я работаю над многопоточным приложением и хочу отладить его с помощью GDB.

Проблема в том, что одна из моих тем продолжает умирать с сообщением:

pure virtual method called
terminate called without an active exception
Abort

Я знаю причину этого сообщения, но я не знаю, где в моей теме это происходит. Обратный след был бы действительно полезен.

Когда я запускаю свое приложение в GDB, оно приостанавливается каждый раз, когда поток приостанавливается или возобновляется. Я хочу, чтобы мое приложение продолжало нормально работать, пока один из потоков не умрет с этим исключением, после чего все должно прекратиться, чтобы я мог получить обратную трассировку.

Какой сигнал сообщает GDB, когда он делает паузу? Вы должны быть в состоянии выполнить команду какhandle SIGUSR1 pass noprint nostop Hasturkun

Ваш Ответ

3   ответа
5

Установите точку останова на __pure_virtual

В ответе @JeffreyHill теперь он называется __cxa_pure_virtual. Я сам не знаю, как это проверить, поэтому не хочу редактировать ответ. Я не собираюсь понижать голос, но сейчас ответ может быть неправильным и должен быть отредактирован кем-то, кто знает, что правильно.
3

FWIW, по-видимому, в gcc 4.1, изменилось соответствующее имя функции, и в этой функции нужно установить точку останова.

__cxa_pure_virtual

135

Вы можете попробовать использовать & quot; catchpoint & quot; (catch throw) остановить отладчик в точке, где генерируется исключение.

Следующиевыдержка Из руководства GDB описывает функцию перехвата.

5.1.3 Установка точек ловли

Вы можете использовать точки перехвата, чтобы заставить отладчик останавливаться для определенных видов программных событий, таких как исключения C ++ или загрузка общей библиотеки. Используйте команду catch для установки точки перехвата.

catch event

Stop when event occurs. event can be any of the following:

throw

The throwing of a C++ exception.

catch

The catching of a C++ exception.

exec

A call to exec. This is currently only available for HP-UX.

fork

A call to fork. This is currently only available for HP-UX.

vfork

A call to vfork. This is currently only available for HP-UX.

load or load libname

The dynamic loading of any shared library, or the loading of the library libname. This is currently only available for HP-UX.

unload or unload libname

The unloading of any dynamically loaded shared library, or the unloading of the library libname. This is currently only available for HP-UX.

tcatch event

Set a catchpoint that is enabled only for one stop. The catchpoint is automatically deleted after the first time the event is caught.

Использоватьinfo break Команда для отображения текущих точек перехвата.

В настоящее время существуют некоторые ограничения в обработке исключений C ++ (catch throw и catch catch) в GDB:

* If you call a function interactively, GDB normally returns control to you when the function has finished executing. If the call raises an exception, however, the call may bypass the mechanism that returns control to you and cause your program either to abort or to simply continue running until it hits a breakpoint, catches a signal that GDB is listening for, or exits. This is the case even if you set a catchpoint for the exception; catchpoints on exceptions are disabled within interactive calls.

* You cannot raise an exception interactively.

* You cannot install an exception handler interactively. 

Иногда catch не лучший способ отладки обработки исключений: если вам нужно точно знать, где вызывается исключение, лучше остановиться перед вызовом обработчика исключений, так как таким образом вы можете увидеть стек до того, как произойдет какое-либо разматывание. Если вместо этого вы установите точку останова в обработчике исключений, может быть нелегко выяснить, где возникло исключение.

Чтобы остановиться непосредственно перед вызовом обработчика исключений, вам необходимо знать о реализации. В случае 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);

Чтобы заставить отладчик перехватывать все исключения до того, как произойдет разматывание стека, установите точку останова на __raise_exception (see section Точки останова; точки наблюдения и исключения).

С условной точкой останова (see section Условия останова), которая зависит от значения идентификатора, вы можете остановить вашу программу при возникновении определенного исключения. Вы можете использовать несколько условных точек останова, чтобы остановить вашу программу при возникновении любого из нескольких исключений.

Пожалуйста, имейте 100-й голос.
Вы также можете указать тип исключения для ловли, например,catch throw std::runtime_exception.

Похожие вопросы