Pracuję nad aplikacją wielowątkową i chcę ją debugować za pomocą GDB.
Problem w tym, że jeden z moich wątków umiera wraz z komunikatem:
pure virtual method called
terminate called without an active exception
Abort
Znam przyczynę tej wiadomości, ale nie mam pojęcia, gdzie w moim wątku się pojawia. Ślad wsteczny byłby naprawdę pomocny.
Gdy uruchamiam aplikację w GDB, zatrzymuje się ona za każdym razem, gdy wątek jest zawieszany lub wznawiany. Chcę, aby moja aplikacja działała normalnie, dopóki jeden z wątków nie umrze z tym wyjątkiem, w którym to momencie wszystko powinno się zatrzymać, aby można było uzyskać ślad.
handle SIGUSR1 pass noprint nostop
Odpowiedzi:
Możesz spróbować użyć „catchpoint” (
catch throw
), aby zatrzymać debugger w punkcie, w którym generowany jest wyjątek.Poniższy fragment podręcznika gdb opisuje funkcję catchpoint.
5.1.3 Ustawianie catchpointów
Możesz użyć punktów przechwytywania, aby spowodować zatrzymanie debugera dla niektórych rodzajów zdarzeń programu, takich jak wyjątki C ++ lub ładowanie biblioteki współużytkowanej. Użyj polecenia catch, aby ustawić punkt zaczepienia.
złapać zdarzenie
rzucać
łapać
exec
widelec
vfork
load lub load libname
unload lub unload libname
tcatch zdarzenie
Użyj
info break
polecenia, aby wyświetlić bieżące punkty zaczepienia.Obecnie istnieją pewne ograniczenia dotyczące obsługi wyjątków C ++ (rzut przechwytywania i przechwytywanie) w GDB:
Jeśli wywołasz funkcję interaktywnie, GDB zwykle zwraca kontrolę po zakończeniu wykonywania funkcji. Jeśli jednak wywołanie wywoła wyjątek, wywołanie może ominąć mechanizm, który zwraca ci kontrolę i spowodować przerwanie programu lub po prostu kontynuowanie działania, aż osiągnie punkt przerwania, przechwyci sygnał, którego nasłuchuje GDB, lub zakończy działanie. Dzieje się tak nawet wtedy, gdy ustawisz punkt zaczepienia dla wyjątku; punkty przechwytywania wyjątków są wyłączone w wywołaniach interaktywnych.
Nie możesz interaktywnie zgłosić wyjątku.
Nie można zainstalować interaktywnej obsługi wyjątków.
Czasami catch nie jest najlepszym sposobem debugowania obsługi wyjątków: jeśli chcesz dokładnie wiedzieć, gdzie został zgłoszony wyjątek, lepiej zatrzymać się przed wywołaniem procedury obsługi wyjątków, ponieważ w ten sposób możesz zobaczyć stos przed jakimkolwiek odwinięciem. Jeśli zamiast tego ustawisz punkt przerwania w programie obsługi wyjątków, ustalenie, gdzie został zgłoszony wyjątek, może nie być łatwe.
Aby zatrzymać się tuż przed wywołaniem procedury obsługi wyjątków, potrzebujesz pewnej wiedzy na temat implementacji. W przypadku GNU C ++ wyjątki są zgłaszane przez wywołanie funkcji bibliotecznej o nazwie __raise_exception, która ma następujący interfejs ANSI C:
Aby debuger przechwytywał wszystkie wyjątki, zanim nastąpi rozwijanie stosu, ustaw punkt przerwania na __raise_exception (zobacz sekcję Punkty przerwania; punkty obserwacyjne; i wyjątki).
Za pomocą warunkowego punktu przerwania (zob. Sekcja Warunki przerwania), który zależy od wartości id, możesz zatrzymać program, gdy zostanie zgłoszony określony wyjątek. Możesz użyć wielu warunkowych punktów przerwania, aby zatrzymać program, gdy zostanie zgłoszony dowolny z wielu wyjątków.
źródło
catch throw std::runtime_exception
.Ustaw punkt przerwania na __pure_virtual
źródło
FWIW najwyraźniej w gcc 4.1 zmieniła się odpowiednia nazwa funkcji i należy ustawić w tej funkcji punkt przerwania.
__cxa_pure_virtual
źródło
Tylko poniżej jeden działał u mnie z gdb 8.3:
„Złap rzut” lub „przerwa __cxx_throw” nie działały dla mnie.
źródło