Запустите приложение в GDB, пока не возникнет исключение


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

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

pure virtual method called
terminate called without an active exception
Abort

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

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

3 91

3 ответа:

вы можете попробовать использовать "точку захвата" (catch throw), чтобы остановить отладчик в точке, где исключение.

следующее цитата в руководстве gdb описывается функция catchpoint.


5.1.3 установка точек захвата

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

  • лови событие

    остановить, когда событие происходит. событие может быть любым из следующих:

    • бросить

      выбрасывание исключения C++.

    • лови

      перехват исключения C++.

    • exec

      A звонок на exec. В настоящее время это доступно только для HP-UX.

    • вилки

      вызов на вилку. В настоящее время это доступно только для HP-UX.

    • vfork

      звонок в vfork. В настоящее время это доступно только для HP-UX.

    • загрузить или загрузить libname

      динамическая загрузка любой общей библиотеки, или загрузка библиотеки libname. В настоящее время это доступно только для HP-UX.

    • выгрузить или выгрузить libname

      выгрузка любой динамически загружаемой общей библиотеки или выгрузка библиотеки libname. В настоящее время это доступно только для HP-UX.

  • tcatch event

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

использовать 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 (см. раздел точки останова; точки наблюдения; и исключения).

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

установить точку останова на __чистого_виртуальный

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

__специалист_чисто_виртуальный