Estou trabalhando em um aplicativo multithread e quero depurá-lo usando GDB.
O problema é que um dos meus tópicos continua morrendo com a mensagem:
pure virtual method called
terminate called without an active exception
Abort
Eu sei a causa dessa mensagem, mas não tenho ideia de onde ela ocorre no meu tópico. Um backtrace seria realmente útil.
Quando executo meu aplicativo no GDB, ele pausa toda vez que um thread é suspenso ou retomado. Quero que meu aplicativo continue executando normalmente até que um dos threads morra com essa exceção, ponto em que tudo deve parar para que eu possa obter um backtrace.
handle SIGUSR1 pass noprint nostop
Respostas:
Você pode tentar usar um "catchpoint" (
catch throw
) para parar o depurador no ponto onde a exceção é gerada.O seguinte trecho do manual do gdb descreve o recurso catchpoint.
5.1.3 Definir pontos de controle
Você pode usar pontos de captura para fazer com que o depurador pare para certos tipos de eventos de programa, como exceções C ++ ou o carregamento de uma biblioteca compartilhada. Use o comando catch para definir um ponto de encontro.
pegar evento
lançar
pegar
exec
garfo
vfork
carregar ou carregar libname
descarregar ou descarregar libname
evento tcatch
Use o
info break
comando para listar os pontos de interesse atuais.Atualmente, existem algumas limitações para o tratamento de exceções C ++ (catch throw e catch catch) no GDB:
Se você chamar uma função interativamente, o GDB normalmente retorna o controle para você quando a função termina de ser executada. Se a chamada gerar uma exceção, no entanto, a chamada pode ignorar o mecanismo que retorna o controle para você e fazer com que seu programa aborte ou simplesmente continue em execução até atingir um ponto de interrupção, capturar um sinal de que o GDB está escutando ou sair. Esse é o caso mesmo se você definir um ponto de captura para a exceção; pontos de interesse em exceções são desabilitados em chamadas interativas.
Você não pode lançar uma exceção interativamente.
Você não pode instalar um manipulador de exceção interativamente.
Às vezes, catch não é a melhor maneira de depurar o tratamento de exceções: se você precisa saber exatamente onde uma exceção é gerada, é melhor parar antes que o manipulador de exceções seja chamado, já que dessa forma você pode ver a pilha antes que ocorra qualquer desenrolamento. Se, em vez disso, você definir um ponto de interrupção em um manipulador de exceção, pode não ser fácil descobrir onde a exceção foi gerada.
Para parar um pouco antes de um manipulador de exceção ser chamado, você precisa de algum conhecimento da implementação. No caso do GNU C ++, as exceções são levantadas chamando uma função de biblioteca chamada __raise_exception que tem a seguinte interface ANSI C:
Para fazer o depurador capturar todas as exceções antes que ocorra qualquer desenrolamento da pilha, defina um ponto de interrupção em __raise_exception (consulte a seção Pontos de interrupção; pontos de controle; e exceções).
Com um ponto de interrupção condicional (consulte a seção Condições de quebra) que depende do valor de id, você pode interromper seu programa quando uma exceção específica for levantada. Você pode usar vários pontos de interrupção condicionais para interromper seu programa quando qualquer uma das várias exceções for levantada.
fonte
catch throw std::runtime_exception
.Defina um ponto de interrupção em __pure_virtual
fonte
FWIW, aparentemente, no gcc 4.1, o nome da função apropriada foi alterado e deve-se definir um ponto de interrupção nesta função.
__cxa_pure_virtual
fonte
Apenas abaixo de um funcionou para mim com gdb 8.3:
"catch throw" ou "break __cxx_throw" não funcionou para mim.
fonte