As exceções “EXC_BREAKPOINT (SIGTRAP)” são causadas por pontos de interrupção de debugging?

Eu tenho um aplicativo multithread que é muito estável em todas as minhas máquinas de teste e parece ser estável para quase todos os meus usuários (com base em nenhuma queixa de falhas). O aplicativo falha com frequência para um usuário, porém, que gentilmente enviou relatórios de falha. Todos os relatórios de erros (~ 10 relatórios consecutivos) parecem essencialmente idênticos:

Date/Time: 2010-04-06 11:44:56.106 -0700 OS Version: Mac OS X 10.6.3 (10D573) Report Version: 6 Exception Type: EXC_BREAKPOINT (SIGTRAP) Exception Codes: 0x0000000000000002, 0x0000000000000000 Crashed Thread: 0 Dispatch queue: com.apple.main-thread Thread 0 Crashed: Dispatch queue: com.apple.main-thread 0 com.apple.CoreFoundation 0x90ab98d4 __CFBasicHashRehash + 3348 1 com.apple.CoreFoundation 0x90adf610 CFBasicHashRemoveValue + 1264 2 com.apple.CoreText 0x94e0069c TCFMutableSet::Intersect(__CFSet const*) const + 126 3 com.apple.CoreText 0x94dfe465 TDescriptorSource::CopyMandatoryMatchableRequest(__CFDictionary const*, __CFSet const*) + 115 4 com.apple.CoreText 0x94dfdda6 TDescriptorSource::CopyDescriptorsForRequest(__CFDictionary const*, __CFSet const*, long (*)(void const*, void const*, void*), void*, unsigned long) const + 40 5 com.apple.CoreText 0x94e00377 TDescriptor::CreateMatchingDescriptors(__CFSet const*, unsigned long) const + 135 6 com.apple.AppKit 0x961f5952 __NSFontFactoryWithName + 904 7 com.apple.AppKit 0x961f54f0 +[NSFont fontWithName:size:] + 39 

(…. mais texto segue)

Primeiro, passei muito tempo investigando [NSFont fontWithName: size:]. Imaginei que talvez as fonts do usuário estivessem estragadas de alguma forma, de modo que [NSFont fontWithName: size:] estava solicitando algo inexistente e falhando por esse motivo. Eu adicionei um monte de código usando [[NSFontManager sharedFontManager] availableFontNamesWithTraits: NSItalicFontMask] para verificar a disponibilidade da fonte com antecedência. Infelizmente, essas mudanças não resolveram o problema.

Agora percebi que esqueci de remover alguns pontos de interrupção de debugging, incluindo _NSLockError, [NSException raise] e objc_exception_throw. No entanto, o aplicativo foi definitivamente criado usando “Release” como a configuração de compilation ativa. Suponho que o uso da configuração “Release” evita a configuração de qualquer ponto de interrupção – mas, novamente, não sei exatamente como os pontos de interrupção funcionam ou se o programa precisa ser executado de dentro do gdb para que os pontos de interrupção tenham algum efeito.

Minhas perguntas são: poderia ter deixado o conjunto de pontos de interrupção como causa das falhas observadas pelo usuário? Em caso afirmativo, por que os pontos de interrupção causariam um problema apenas para esse usuário? Se não, alguém mais teve problemas semelhantes com o [NSFont fontWithName: size:]?

Provavelmente, vou tentar remover os pontos de interrupção e enviar de volta ao usuário, mas não tenho certeza da quantidade de moeda que me resta com esse usuário. E eu gostaria de entender de forma mais geral se deixar o conjunto de pontos de interrupção poderia causar um problema (quando o aplicativo é construído usando a configuração “Release”).

    As exceções “EXC_BREAKPOINT (SIGTRAP)” são causadas por pontos de interrupção de debugging?

    Não. Outro caminho, na verdade: Um SIGTRAP (armadilha de rastreamento) fará com que o depurador interrompa (interrompa) seu programa, da mesma forma que um ponto de interrupção real faria. Mas isso é porque o depurador sempre quebra em um acidente, e um SIGTRAP (como vários outros sinais ) é um tipo de falha.

    SIGTRAPs são geralmente causados ​​por NSExceptions sendo lançadas, mas nem sempre – é possível elevar uma delas diretamente.

    Agora percebi que esqueci de remover alguns pontos de interrupção de debugging, incluindo _NSLockError, [NSException raise] e objc_exception_throw.

    Aqueles não são pontos de interrupção. Dois deles são funções e -[NSException raise] é um método.

    Você quis dizer que você definiu pontos de interrupção nessas funções e nesse método?

    Eu suponho que usar a configuração “Release” impede a configuração de qualquer ponto de interrupção

    Não.

    As configurações são configurações de construção . Eles afetam como o Xcode constrói seus aplicativos.

    Pontos de interrupção não fazem parte da construção; você os coloca no depurador. Eles só existem, só são atingidos e só param o programa quando você executa o programa no depurador.

    Como eles não fazem parte da compilation, não é possível passar seus pontos de interrupção a um usuário simplesmente fornecendo o pacote do aplicativo.

    Não sei exatamente como funcionam os pontos de interrupção …

    Quando o seu programa atinge o ponto de interrupção, o depurador interrompe (interrompe) o seu programa, após o que você pode examinar o estado do programa e avançar cuidadosamente para ver como o programa corre mal.

    Como é o depurador que interrompe seu programa, os pontos de interrupção não surtem efeito quando você não está executando o programa no depurador.

    … Ou se o programa precisa ser executado de dentro do gdb para que os pontos de interrupção tenham algum efeito.

    Isso acontece. Os pontos de interrupção do depurador funcionam apenas no depurador.

    Minhas perguntas são: poderia ter deixado o conjunto de pontos de interrupção como causa das falhas observadas pelo usuário?

    Não.

    Primeiro, como observado, mesmo que esses pontos de interrupção tenham sido transferidos para o sistema do usuário, os pontos de interrupção só serão efetivos no depurador. O depurador não pode parar em um ponto de interrupção se o programa não estiver sendo executado no depurador. O usuário quase certamente não está executando seu aplicativo no depurador, especialmente porque eles tiveram um log de falhas.

    Mesmo se eles executassem seu aplicativo sob o depurador com todos esses pontos de interrupção definidos, um ponto de interrupção só será atingido quando seu programa atingir esse ponto, portanto, um desses pontos de interrupção só poderia ser _NSLockError se você ou Cocoa chamavam _NSLockError , -[NSException raise] , ou objc_exception_throw . Chegar a esse ponto não seria a causa do problema, seria um sintoma do problema.

    E se você falhou como resultado de um dos que estão sendo chamados, seu log de falhas teria pelo menos um deles nomeado nele. Não faz.

    Então, isso não estava relacionado aos seus pontos de interrupção (máquina diferente, depurador não envolvido), e não era uma exceção Cocoa – como mencionei, as exceções do Cocoa são uma das causas dos SIGTRAPs, mas elas não são as únicas. Você encontrou um diferente.

    Se não, alguém mais teve problemas semelhantes com o [NSFont fontWithName: size:]?

    Não há como saber se algum problema que tivemos é parecido porque você cortou o registro de falhas. Não sabemos nada sobre o contexto em que ocorreu o acidente.

    A única coisa boa para cortar é a seção “Imagens binárias”, já que não temos seus pacotes dSYM, o que significa que não podemos usar essa seção para simbolizar o registro de falhas.

    Você, por outro lado, pode. Eu escrevi um aplicativo para este fim; Alimente o log de travamento a ele, e ele deve detectar o pacote dSYM automaticamente (você está mantendo o pacote dSYM para cada versão que você distribuir, certo?) e restaure seus nomes de function e método no rastreamento de pilha onde quer que suas funções e methods apareçam.

    Para mais informações, consulte o Guia de Depuração do Xcode .

    É extremamente provável que esse usuário tenha uma fonte corrompida instalada. O rastreamento de pilha definitivamente suporta essa hipótese, assim como o fato de que ela afeta apenas um usuário.

    Não há muito o que fazer nesse caso, exceto fazer com que o usuário remova a fonte problemática, já que as falhas ocorrem no fundo do código da Apple.

    Tente fazer com que o usuário execute uma validação de fonte no Catálogo de Fontes. Para fazer isso, inicie o Catálogo de Fontes, clique em Todas as Fontes na lista de origem e selecione todas as fonts listadas. Você pode então selecionar Validar Fontes no menu Arquivo .

    Os pontos de interrupção não são gravados no binário. As probabilidades são boas de que essa pessoa tenha uma instalação de SO quebrada. Verifique os logs do console em busca de mensagens dyld.

    Eu tive o mesmo erro. Por uma razão inexplicável, o ponto de interrupção foi o responsável por lançar a exceção EXC_BREAKPOINT . A solução foi remover o ponto de interrupção e, em seguida, codificar funciona.

    EXC_BREAKPOINT é um tipo de exceção que os depuradores usam. Quando você define um ponto de interrupção em seu código, o compilador insere uma exceção desse tipo no código executável. Quando a execução atinge esse ponto, a exceção é lançada e o depurador a captura. Em seguida, o depurador mostra seu código na linha “breakpointed”. É assim que os depuradores funcionam. Mas, nesse caso, o depurador não manipula a exceção corretamente e é apresentado como um erro de exceção regular.

    Eu encontrei este erro duas vezes na minha vida:

    • um usando o Xcode há cerca de um ano.
    • o outro usando o Visual C ++ há cerca de 15 anos.