Chcę mieć sposób na zgłoszenie śladu stosu użytkownikowi, jeśli zostanie zgłoszony wyjątek. Jak najlepiej to zrobić? Czy to wymaga dużej ilości dodatkowego kodu?
Aby odpowiedzieć na pytania:
Chciałbym, żeby to było przenośne, jeśli to możliwe. Chcę, aby pojawiły się informacje, aby użytkownik mógł skopiować ślad stosu i wysłać mi wiadomość e-mail, jeśli pojawi się błąd.
Linux
nie”gcc
.libstdc++
(używany przez GCC i potencjalnie Clanga), jak wyjaśniono w tej odpowiedzi .Odpowiedź Andrew Granta nie pomaga w uzyskaniu śladu stosu funkcji rzucania , przynajmniej nie w przypadku GCC, ponieważ instrukcja throw nie zapisuje bieżącego śladu stosu samodzielnie, a moduł obsługi przechwytywania nie będzie miał dostępu do śladu stosu na ten punkt już.
Jedynym sposobem - za pomocą GCC - aby rozwiązać ten problem, jest wygenerowanie śledzenia stosu w punkcie instrukcji rzucania i zapisanie go z obiektem wyjątku.
Ta metoda wymaga oczywiście, aby każdy kod zgłaszający wyjątek używał tej konkretnej klasy wyjątków.
Aktualizacja 11 lipca 2017 r . : Aby uzyskać pomocny kod, spójrz na odpowiedź cahit beyaz, która wskazuje na http://stacktrace.sourceforge.net - jeszcze go nie użyłem, ale wygląda obiecująco.
źródło
throw stack_runtime_error
. Czy mam rację, wydedukowując, że ta biblioteka działa tylko dla wyjątków pochodzących z tej klasy, a nie dlastd::exception
wyjątków z bibliotek stron trzecich?Jeśli używasz Boost 1.65 lub wyższej, możesz użyć boost :: stacktrace :
źródło
Unix: ślad
Mac: ślad
Windows: CaptureBackTrace
źródło
Chciałbym dodać standardową opcję biblioteki (tj. Wieloplatformową), jak generować wyjątki śledzenia, które stały się dostępne w C ++ 11 :
Użyj
std::nested_exception
istd::throw_with_nested
To nie zapewni ci odprężenia stosu, ale moim zdaniem kolejna najlepsza rzecz. Jest to opisane na StackOverflow tutaj i tutaj , w jaki sposób można uzyskać ślad na swoim wyjątkami wewnątrz kodu bez konieczności uciążliwego debugger lub logowania, po prostu pisząc odpowiedni program obsługi wyjątków, które będą rethrow zagnieżdżone wyjątki.
Ponieważ możesz to zrobić z dowolną pochodną klasą wyjątku, możesz dodać wiele informacji do takiego śladu wstecznego! Możesz także rzucić okiem na moją MWE na GitHub , gdzie ślad może wyglądać mniej więcej tak:
źródło
AFAIK libunwind jest dość przenośny i do tej pory nie znalazłem nic łatwiejszego w użyciu.
źródło
Polecam projekt http://stacktrace.sourceforge.net/ . Obsługuje Windows, Mac OS, a także Linux
źródło
throw stack_runtime_error
. Czy mam rację, wydedukowując, że ta biblioteka działa tylko dla wyjątków pochodzących z tej klasy, a nie dlastd::exception
wyjątków z bibliotek stron trzecich?Jeśli używasz C ++ i nie chcesz / nie możesz użyć Boost, możesz wydrukować ślad ze zdemodowanymi nazwami, używając następującego kodu [link do oryginalnej strony] .
Uwaga: to rozwiązanie jest specyficzne dla systemu Linux. Używa funkcji libc GNU backtrace () / backtrace_symbols () (z execinfo.h), aby uzyskać ślady wsteczne, a następnie używa __cxa_demangle () (z cxxabi.h) do rozplątywania nazw symboli śledzenia.
HTH!
źródło
na Linuksie z g ++ sprawdź tę bibliotekę
https://sourceforge.net/projects/libcsdbg
wykonuje całą pracę za Ciebie
źródło
W systemie Windows sprawdź BugTrap . Nie jest już pod oryginalnym linkiem, ale nadal jest dostępny w CodeProject.
źródło
Mam podobny problem i chociaż lubię przenośność, potrzebuję tylko obsługi gcc. W gcc dostępne są wywołania execinfo.h i backtrace . Aby rozplątać nazwy funkcji, pan Bingmann ma niezły kawałek kodu. Aby zrzucić ślad wyjątku, tworzę wyjątek, który drukuje ślad w konstruktorze. Jeśli spodziewałem się, że zadziała to z wyjątkiem zgłoszonym w bibliotece, może to wymagać przebudowania / połączenia, aby można było zastosować wyjątek śledzenia wstecznego.
Kompilacja i uruchomienie tego z gcc 4.8.4 daje ślad wsteczny z ładnie niezmienionymi nazwami funkcji C ++:
źródło
Ponieważ stos jest już rozwijany po wejściu do bloku catch, w moim przypadku rozwiązaniem było nie wychwycenie pewnych wyjątków które następnie prowadziły do SIGABRT. W module obsługi sygnałów dla SIGABRT I następnie fork () i execl () albo gdb (w kompilacjach debugowania), albo Google breakpads stosu stosów (w kompilacjach wersji). Staram się również używać tylko bezpiecznych funkcji obsługi sygnałów.
GDB:
minidump_stackwalk:
Edycja: Aby działało na breakpad, musiałem również dodać:
Źródło: Jak uzyskać ślad stosu dla C ++ przy użyciu gcc z informacjami o numerze linii? oraz Czy można dołączyć gdb do zawieszonego procesu (czyli debugowania „just-in-time”)
źródło
Poppy może gromadzić nie tylko ślad stosu, ale także wartości parametrów, zmienne lokalne itp. - wszystko, co prowadzi do awarii.
źródło
Poniższy kod zatrzymuje wykonywanie zaraz po zgłoszeniu wyjątku. Musisz ustawić moduł obsługi wyjątków systemu Windows wraz z procedurą obsługi zakończenia. Przetestowałem to w MinGW 32 bity.
Sprawdź następujący kod funkcji Windows_exception_handler: http://www.codedisqus.com/0ziVPgVPUk/exception-handling-and-stacktrace-under-windows-mingwgcc.html
źródło
Cpp-tool ex_diag - easyweight, wieloplatformowy, minimalne wykorzystanie zasobów, prosty i elastyczny w śledzeniu.
źródło