Desejo ter uma maneira de relatar o rastreamento de pilha ao usuário se uma exceção for lançada. Qual é a melhor maneira de fazer isso? É preciso uma quantidade enorme de código extra?
Para responder perguntas:
Eu gostaria que fosse portátil, se possível. Quero que as informações sejam exibidas, para que o usuário possa copiar o rastreamento da pilha e enviá-lo por e-mail para mim se ocorrer um erro.
Linux
nãogcc
.libstdc++
(usado pelo GCC e potencialmente por Clang), conforme explicado nesta resposta .A resposta de Andrew Grant não ajuda a obter um rastreamento de pilha da função throwing , pelo menos não com o GCC, porque uma instrução throw não salva o rastreamento de pilha atual por conta própria e o manipulador de captura não terá acesso ao rastreamento de pilha em esse ponto mais.
A única maneira - usando o GCC - de resolver isso é gerar um rastreamento de pilha no ponto da instrução throw e salvá-lo com o objeto de exceção.
Esse método exige, é claro, que todo código que lança uma exceção use essa classe Exception específica.
Atualização 11 de julho de 2017 : Para obter um código útil, dê uma olhada na resposta de cahit beyaz, que aponta para http://stacktrace.sourceforge.net - ainda não o usei, mas parece promissor.
fonte
throw stack_runtime_error
. Estou correto ao deduzir que essa lib funciona apenas para exceções derivadas dessa classe e não parastd::exception
ou exceções de bibliotecas de terceiros?Se você estiver usando o Boost 1.65 ou superior, poderá usar o boost :: stacktrace :
fonte
Unix: backtrace
Mac: rastreamento
Windows: CaptureBackTrace
fonte
Gostaria de adicionar uma opção de biblioteca padrão (ou seja, plataforma cruzada) como gerar backtraces de exceção, que se tornou disponível no C ++ 11 :
Use
std::nested_exception
estd::throw_with_nested
Isso não dará a você uma pilha para relaxar, mas, na minha opinião, a próxima melhor coisa. É descrito no StackOverflow aqui e aqui , como você pode obter um retorno das suas exceções dentro do seu código sem a necessidade de um depurador ou log complicado, simplesmente escrevendo um manipulador de exceções adequado que irá repetir exceções aninhadas.
Como você pode fazer isso com qualquer classe de exceção derivada, você pode adicionar muitas informações a esse backtrace! Você também pode dar uma olhada no meu MWE no GitHub , onde um backtrace seria algo como isto:
fonte
O AFAIK libunwind é bastante portátil e até agora não encontrei nada mais fácil de usar.
fonte
Eu recomendo http://stacktrace.sourceforge.net/ project. Ele suporta Windows, Mac OS e também Linux
fonte
throw stack_runtime_error
. Estou correto ao deduzir que essa lib funciona apenas para exceções derivadas dessa classe e não parastd::exception
ou exceções de bibliotecas de terceiros?Se você estiver usando C ++ e não quiser / não puder usar o Boost, poderá imprimir o backtrace com nomes desmembrados usando o seguinte código [link para o site original] .
Observe que esta solução é específica para Linux. Ele usa as funções libc do GNU, backtrace () / backtrace_symbols () (de execinfo.h) para obter os backtraces e, em seguida, usa __cxa_demangle () (de cxxabi.h) para desmantelar os nomes dos símbolos de backtrace.
HTH!
fonte
no linux com g ++ confira esta lib
https://sourceforge.net/projects/libcsdbg
faz todo o trabalho para você
fonte
No Windows, confira BugTrap . Não está mais no link original, mas ainda está disponível no CodeProject.
fonte
Tenho um problema semelhante e, embora goste de portabilidade, preciso apenas de suporte ao gcc. No gcc, o execinfo.h e as chamadas de backtrace estão disponíveis. Para desmontar os nomes das funções, o Sr. Bingmann possui um bom pedaço de código. Para despejar um backtrace em uma exceção, eu crio uma exceção que imprime o backtrace no construtor. Se eu esperava que isso funcionasse com uma exceção lançada em uma biblioteca, pode ser necessário reconstruir / vincular para que a exceção de retorno seja usada.
Compilar e executar isso com o gcc 4.8.4 gera um backtrace com nomes de funções C ++ não-manipuladas:
fonte
Como a pilha já está desenrolada ao entrar no bloco catch, a solução no meu caso foi não capturar certas exceções que levam a um SIGABRT. No manipulador de sinal do SIGABRT, então fork () e execl () gdb (em compilações de depuração) ou stackpads do Google breakpads (em compilações de versão). Também tento usar apenas funções seguras do manipulador de sinal.
GDB:
minidump_stackwalk:
Edit: Para fazê-lo funcionar para o breakpad, eu também tive que adicionar isso:
Fonte: Como obter um rastreamento de pilha para C ++ usando o gcc com informações de número de linha? e É possível anexar o gdb a um processo travado (também conhecido como depuração "just-in-time")
fonte
Poppy pode coletar não apenas o rastreamento da pilha, mas também valores de parâmetros, variáveis locais, etc. - tudo o que levou à falha.
fonte
O código a seguir interrompe a execução logo após uma exceção ser lançada. Você precisa definir um windows_exception_handler junto com um manipulador de terminação. Eu testei isso em MinGW 32bits.
Verifique o seguinte código para a função windows_exception_handler: http://www.codedisqus.com/0ziVPgVPUk/exception-handling-and-stacktrace-under-windows-mingwgcc.html
fonte
Cpp-tool ex_diag - peso fácil, multiplataforma, uso mínimo de recursos, simples e flexível no rastreamento.
fonte