Nada que eu tentasse consertava isso (tentei os dois compiladores, os depuradores etc.) Após atualizar o XCode para a atualização do iOS 5, nenhum rastreamento de pilha parecia funcionar.
No entanto, eu encontrei uma solução alternativa eficaz - criando meu próprio manipulador de exceções (que também é útil por outros motivos). Primeiro, crie uma função que lida com o erro e a envie para o console (assim como qualquer outra coisa que você queira fazer com ele):
void uncaughtExceptionHandler(NSException *exception) {
NSLog(@"CRASH: %@", exception);
NSLog(@"Stack Trace: %@", [exception callStackSymbols]);
// Internal error reporting
}
Em seguida, adicione o manipulador de exceções ao delegado do aplicativo:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
NSSetUncaughtExceptionHandler(&uncaughtExceptionHandler);
// Normal launch stuff
}
É isso aí!
Se isso não funcionar, existem apenas dois motivos possíveis :
- Algo está sobrescrevendo sua
NSSetUncaughtExceptionHandler
chamada (pode haver apenas um manipulador para todo o aplicativo). Por exemplo, algumas bibliotecas de terceiros definem seu próprio uncaughtExceptionHandler. Portanto, tente configurá-lo no final da sua didFinishLaunchingWithOptions
função (ou desativar seletivamente as bibliotecas de terceiros). Ou, melhor ainda, defina um ponto de interrupção simbólico NSSetUncaughtExceptionHandler
para ver rapidamente quem está ligando. O que você pode querer fazer é modificar o atual, em vez de adicionar outro.
- Você não está realmente encontrando uma exceção (por exemplo, não
EXC_BAD_ACCESS
é uma exceção; crédito aos comentários de @Erik B, abaixo)
uncaughtExceptionHandler
rotina nunca é invocada.Existe uma opção útil para adicionar um ponto de interrupção de exceção (usando o + na parte inferior do navegador de ponto de interrupção). Isso será interrompido em qualquer exceção (ou você pode definir condições). Não sei se essa opção é nova na versão 4.2 ou se finalmente a notei tentando solucionar o problema dos símbolos ausentes.
Depois de atingir esse ponto de interrupção, você pode usar o Navegador de Depuração para navegar na pilha de chamadas, examinar variáveis etc., como de costume.
Se você deseja uma pilha de chamadas simbolizada adequada para copiar / colar ou algo semelhante, o backdrace gdb funcionará bem a partir daí:
(etc)
fonte
Há um novo recurso no depurador. Você pode definir um ponto de interrupção sempre que uma exceção for lançada e interromper a execução ali, exatamente como costumava acontecer no 4.0.
No "Navegador do ponto de interrupção", adicione um "Ponto de interrupção de exceção" e pressione "Concluído" na janela pop-up de opções.
Isso é tudo!
PS: Em alguns casos, seria melhor interromper apenas as exceções de Objective-C.
fonte
Aqui está mais uma solução, não tão elegante quanto a anterior, mas se você não adicionou pontos de interrupção ou manipuladores de exceção, pode ser apenas um caminho a percorrer.
Quando o aplicativo falha, e você obtém sua pilha bruta de primeira chamada (em números hexadecimais), digite no console do Xcode
info line *hex
(não se esqueça do0x
especificador de estrela e hexadecimal), por exemplo:Se você estiver usando lldb , poderá digitar
image lookup -a hex
(sem estrela nesta situação) e obter uma saída semelhante.Com esse método, você pode passar da parte superior da pilha de lançamento (haverá cerca de 5-7 propagadores de exceção do sistema) para a sua função que causou uma falha e determinar o arquivo e a linha de código exatos.
Além disso, para um efeito semelhante, você pode usar o utilitário atos no terminal, apenas digite:
e você obtém o rastreamento de pilha simbolizado (pelo menos para funções com símbolos de depuração). Esse método é mais preferível, porque você não tem para cada chamada de endereço
info line
, apenas copie os endereços da saída do console e cole-os no terminal.fonte
Você pode adicionar um ponto de interrupção de exceção (usando o + na parte inferior do navegador de ponto de interrupção) e adicionar a ação
bt
a ele (clique no botão Adicionar ação, selecione Comando do depurador, insira "bt" no campo de texto). Isso exibirá o rastreamento da pilha assim que uma exceção for lançada.fonte
Este é um problema comum, não obtendo rastreamentos de pilha no 4.2. Você pode tentar trocar entre LLDB e GDB para ver se obtém melhores resultados.
Arquive um relatório de bug aqui.
http://developer.apple.com/bugreporter/
EDITAR:
Acredito que se você voltar ao LLVM GCC 4.2, não verá isso acontecer. Você pode perder os recursos necessários.
fonte
Use este código em sua função principal:
fonte
No prompt do console de depuração do Xcode, digite:
E isso mostrará algo como:
fonte
Ativar novamente 'Compilar para o Thumb' (configuração de depuração) funcionou para mim.
fonte