Xcode não mostra a linha que causa uma falha

126

Sempre que meu aplicativo trava, o Xcode destaca a chamada UIApicationMain () na função main () como a linha que causou o travamento. Em alguns casos, isso costumava ser normal (falha de segmentação, por exemplo), mas a falha com a qual estou tentando lidar é um SIGABRT simples, com informações detalhadas registradas no console:

*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFDictionary setObject:forKey:]: attempt to insert nil value (key: Date)'

O Xcode costumava mostrar a linha corretamente com SDKs mais antigos, mas desde que atualizei para o Xocde 4.2 que mudou. É bastante óbvio que o Xcode sabe exatamente o que causou a falha (ou poderia saber), mas ainda não está mostrando a linha real. Existe alguma correção ou solução alternativa para isso?

JonasG
fonte
2
Você está compilando para o Release? Nesse caso, tente configurar o esquema para Depurar.
epatel 9/10/11
Também pode ser que alguns xib estejam com problemas, causando a falha do programa em um local fora do seu próprio código-fonte, portanto, não mostrando nenhum arquivo. O erro descreve um problema para uma chave de dicionário chamada "Data"
epatel 9/11
1
Apple deve contratar mais testadores;)
Amr Lotfy

Respostas:

301

Você também deve garantir que você tenha pontos de interrupção definidos para todas as exceções. Isso fará com que o Xcode pare na linha em que a exceção está ocorrendo. Faça o seguinte [no Xcode 4]:

  1. No Navegador de projeto, no lado esquerdo do Xcode, clique no navegador do ponto de interrupção (quase todo o lado direito da barra de botões superior. O ícone se parece com uma grande seta à direita).

  2. Na parte inferior do navegador, clique no botão "+".

  3. Clique em "Adicionar ponto de interrupção de exceção".

  4. Um novo ponto de interrupção será criado. Ele deve ser configurado conforme necessário, mas você pode ajustar seu comportamento.

  5. Execute seu projeto e reproduza a exceção.

Você também mencionou que vinculou a algumas bibliotecas / estruturas de terceiros. Se a exceção estiver ocorrendo nessas estruturas, você terá dificuldades, pois o código é compilado e o Xcode não pode realmente mostrar a linha que causou a exceção. Se esse for o caso e você tiver certeza de que está usando as bibliotecas corretamente, envie um relatório de erro aos mantenedores dessas bibliotecas.

Carter
fonte
4
Eu sou um noob e desenvolvi quase um mês sem isso ... isso muda minha vida.
Jonny Burger
4
Meu amigo se registrou em uma conta SO apenas para votar neste post.
Alex Spencer
1
isso é chamado de metade Assing em maçãs parte no meu livro
ChuckKelly
1
Fiz isso, mas ainda não consigo encontrar onde ele chamava o comprimento em um valor nulo :(
Shereef Marzouk 9/09/14
1
Isso funciona, mas a desvantagem é que não gera mais detalhes da exceção no console de depuração. Para que eu possa desativar esse ponto de interrupção e ver os detalhes e o rastreio da exceção, mas não ONDE aconteceu, ou LIGAR para ver onde aconteceu, mas não com POR QUE. Alguém sabe como ter os dois?
Gabriel Jensen
27

Basta seguir as instruções nesta resposta do StackOverflow:

Ativar zumbis

Basicamente, você só precisa "Ativar Zumbis". O Xcode deve quebrar na linha que causou o problema.

insira a descrição da imagem aqui

(É absolutamente chocante que, mesmo em 2017, o Xcode ainda esteja desativado por padrão. Por que você não deseja ver a linha que causou o problema? E " Ativar objetos zumbis "?! Realmente?! Os autores do Xcode realmente Acreditamos que esse é um nome útil, o que faria algum sentido para os novos desenvolvedores? Está deprimindo a classificação ruim do Xcode, ano após ano, na App Store. Ninguém está ouvindo ...)

Mike Gledhill
fonte
6
O Xcode é o pior ambiente de programação que usei até agora.
Student
O que acho interessante (como desenvolvedor do Visual Studio) é quantos desenvolvedores do Xcode eu conheci, que insistem que o Xcode é o melhor ambiente que eles já usaram. Lógico, amigável e útil .. mas com algumas peculiaridades. Mesmo agora, em novembro de 2019, o Xcode tem uma classificação na App Store de 3,1, com a maioria das pessoas dando a ele 5 estrelas ou 1 estrela. Ninguém está escutando ....
Mike Gledhill
9

Editar o esquema atual e permitir NSZombieEnabled, MallocStackLogginge guard malloc. Em seguida, quando seu aplicativo falhar, digite isso no console gdb:

(gdb) info malloc-history 0x543216

Substitua 0x543216pelo endereço do objeto que causou o NSInvalidArgumentExceptione deve fornecer um rastreamento de pilha muito mais útil, mostrando as linhas do seu código que estão causando a falha.

chown
fonte
1
Eu tentei isso e foi gerado o erro: 'info' não é um comando válido. Algum conselho?
Achi
@EliGregory verifique se o seu depurador está definido como gdb e não como o lldb padrão. Você pode alterá-lo no menu Editar esquema, na seção de execução.
Chown #
2

Eu já vi esse comportamento em código altamente otimizado; verificar, ajustar o nível de otimização do seu alvo e o das bibliotecas de terceiros pode ajudar. (Configuração do nível de otimização do LLVM 3.0)

Você está gerando símbolos de depuração?

FluffulousChimp
fonte
Acordado. Se você estiver tentando depurar, o nível de otimização precisará ser definido como 0 (sem otimização) nas configurações de compilação.
Carter
1

Eu escrevi o código para gerar uma falha do índice fora do limite. A seguir, é apresentada a exceção.

2017-01-07 04:02:57.606 testABC[1694:52966] *** Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[__NSSingleObjectArrayI objectAtIndex:]: index 1 beyond bounds [0 .. 0]'
*** First throw call stack:
(
    0   CoreFoundation                      0x000000010e85cd4b __exceptionPreprocess + 171
    1   libobjc.A.dylib                     0x000000010e2be21e objc_exception_throw + 48
    2   CoreFoundation                      0x000000010e8b5c2f -[__NSSingleObjectArrayI objectAtIndex:] + 111
    3   testABC                             0x000000010dce962d -[ViewController ComplexFunction] + 61
    4   testABC                             0x000000010dce95db -[ViewController thirdFunction] + 43
    5   testABC                             0x000000010dce959b -[ViewController secondFunction] + 43
    6   testABC                             0x000000010dce955b -[ViewController firstFinction] + 43
    7   testABC                             0x000000010dce96c2 -[ViewController viewDidAppear:] + 50
    8   UIKit                               0x000000010ee28a6c -[UIViewController _setViewAppearState:isAnimating:] + 945
    9   UIKit                               0x000000010ee2b7da __64-[UIViewController viewDidMoveToWindow:shouldAppearOrDisappear:]_block_invoke + 42
    10  UIKit                               0x000000010ee29ac4 -[UIViewController _executeAfterAppearanceBlock] + 86
    11  UIKit                               0x000000010ec8d77c _runAfterCACommitDeferredBlocks + 653
    12  UIKit                               0x000000010ec7a273 _cleanUpAfterCAFlushAndRunDeferredBlocks + 566
    13  UIKit                               0x000000010ec9d757 __84-[UIApplication _handleApplicationActivationWithScene:transitionContext:completion:]_block_invoke_2 + 194
    14  CoreFoundation                      0x000000010e8016ac __CFRUNLOOP_IS_CALLING_OUT_TO_A_BLOCK__ + 12
    15  CoreFoundation                      0x000000010e7e66f4 __CFRunLoopDoBlocks + 356
    16  CoreFoundation                      0x000000010e7e5e65 __CFRunLoopRun + 901
    17  CoreFoundation                      0x000000010e7e5884 CFRunLoopRunSpecific + 420
    18  GraphicsServices                    0x00000001126d9a6f GSEventRunModal + 161
    19  UIKit                               0x000000010ec80c68 UIApplicationMain + 159
    20  testABC                             0x000000010dce99df main + 111
    21  libdyld.dylib                       0x000000011174968d start + 1
    22  ???                                 0x0000000000000001 0x0 + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException

Se você ler atentamente o First Throw call stack

0   CoreFoundation              0x000000010e85cd4b __exceptionPreprocess + 171
1   libobjc.A.dylib             0x000000010e2be21e objc_exception_throw + 48

0 and 1 são os processos do sistema após a falha.

 2   CoreFoundation             0x000000010e8b5c2f -[__NSSingleObjectArrayI objectAtIndex:] + 111

2 é a linha que causou a exceção.

3   testABC                     0x000000010dce962d -[ViewController ComplexFunction] + 61

3informa o nome da classe ( ViewController) e a função naem ( ComplexFunction) na qual a exceção foi lançada.

AsifHabib
fonte
4
Errr, ok. Você está absolutamente certo, mas isso é amigável? Em qualquer ambiente de desenvolvimento moderno (dos anos 90 em diante), quando ocorre uma exceção, você é levado à linha que causou o problema. Enquanto o Xcode ... bem ... fornece um rastreamento de pilha como este. Até o Turbo Pascal não estava desatualizado !!!
Mike Gledhill
4
É ridículo que a empresa supostamente conhecida pela "melhor experiência do usuário" não perceba que todos os desenvolvedores nos últimos 20 anos estão acostumados a ver o número da linha em que uma exceção é lançada e NÃO NA MONTAGEM. Estou ficando louco? Cada idioma que trabalhei com toda a minha vida fornece números de linha. Mesmo C ou C ++.
mylovemhz