J'ai une application multithread qui est très stable sur toutes mes machines de test et semble être stable pour presque chacun de mes utilisateurs (basée sur aucune plainte de crash). L'application se bloque fréquemment pour un utilisateur, qui a cependant eu la gentillesse d'envoyer des rapports d'incident. Tous les rapports d'incident (environ 10 rapports consécutifs) sont essentiellement identiques:
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
(.... plus de texte suit)
Premièrement, j'ai passé beaucoup de temps à étudier [NSFont fontWithName: size:]. J'ai pensé que les polices de l'utilisateur étaient peut-être foutues d'une manière ou d'une autre, de sorte que [NSFont fontWithName: size:] demandait quelque chose d'inexistant et échouait pour cette raison. J'ai ajouté un tas de code utilisant [[NSFontManager sharedFontManager] availableFontNamesWithTraits: NSItalicFontMask] pour vérifier la disponibilité des polices à l'avance. Malheureusement, ces changements n'ont pas résolu le problème.
J'ai maintenant remarqué que j'avais oublié de supprimer certains points d'arrêt de débogage, notamment _NSLockError, [NSException raise] et objc_exception_throw. Cependant, l'application a été définitivement construite avec "Release" comme configuration de construction active. J'imagine que l'utilisation de la configuration "Release" empêche la définition de points d'arrêt - mais je ne suis pas sûr de savoir exactement comment fonctionnent les points d'arrêt ni de savoir si le programme doit être exécuté à partir de gdb pour que les points d'arrêt aient un effet.
Mes questions sont les suivantes: est-ce que le fait d’avoir laissé les points d’arrêt définis puisse être la cause des accidents observés par l’utilisateur? Si tel est le cas, pourquoi les points d'arrêt ne poseraient-ils un problème que pour cet utilisateur? Sinon, quelqu'un d'autre a-t-il eu des problèmes similaires avec [NSFont fontWithName: size:]?
Je vais probablement essayer de supprimer les points d'arrêt et de le renvoyer à l'utilisateur, mais je ne suis pas sûr de la quantité de monnaie qu'il me reste avec cet utilisateur. Et j'aimerais comprendre plus généralement si le fait de laisser les points d'arrêt définis pourrait éventuellement poser un problème (lorsque l'application est créée à l'aide de la configuration "Release").
Les exceptions «EXC_BREAKPOINT (SIGTRAP)» sont-elles causées par des points d'arrêt de débogage?
Non, autrement, en fait: un SIGTRAP (trappe) fera que le débogueur interrompra (interrompra) votre programme, de la même manière qu'un point d'arrêt réel. Mais c’est parce que le débogueur s’interrompt toujours lors d’un crash et qu’un SIGTRAP (comme plusieurs autres signaux ) est un type de crash.
Les SIGTRAPs sont généralement causés par les exceptions NSException, mais pas toujours - il est même possible de directement augmenter une vous-même.
J'ai maintenant remarqué que j'avais oublié de supprimer certains points d'arrêt de débogage, notamment _NSLockError, [NSException raise] et objc_exception_throw.
Ce ne sont pas des points d'arrêt. Deux d'entre elles sont des fonctions et -[NSException raise]
est une méthode.
Voulez-vous dire que vous définissez des points d'arrêt sur ces fonctions et cette méthode?
Je suppose que l'utilisation de la configuration "Release" empêche la configuration de points d'arrêt--
Non.
Les configurations sont les configurations build. Ils affectent la façon dont Xcode construit vos applications.
Les points d'arrêt ne font pas partie de la construction; vous les définissez dans le débogueur. Ils existent uniquement, sont uniquement touchés et n'arrêtent votre programme que lorsque vous l'exécutez sous le débogueur.
Comme ils ne font pas partie de la construction, il est impossible de transmettre vos points d'arrêt à un utilisateur en leur donnant simplement le paquet d'applications.
Je ne sais pas exactement comment fonctionnent les points d'arrêt…
Lorsque votre programme atteint le point d'arrêt, le débogueur interrompt (interrompt) votre programme, ce qui vous permet d'examiner l'état du programme et de procéder avec prudence pour voir si le programme a mal tourné.
Etant donné que c'est le débogueur qui arrête votre programme, les points d'arrêt n'ont aucun effet si vous n'exécutez pas votre programme sous le débogueur.
… Ou si le programme doit être exécuté à partir de gdb pour que les points d'arrêt aient un effet.
Cela fait. Les points d'arrêt du débogueur fonctionnent uniquement dans le débogueur.
Mes questions sont les suivantes: est-ce que le fait d’avoir laissé les points d’arrêt définis puisse être la cause des accidents observés par l’utilisateur?
Non.
Premièrement, comme indiqué, même si ces points d'arrêt ont en quelque sorte été reportés sur le système de l'utilisateur, ils ne sont efficaces que dans le débogueur. Le débogueur ne peut pas s'arrêter sur un point d'arrêt si votre programme ne s'exécute pas sous le débogueur. L’utilisateur n’exécute presque certainement pas votre application sous le débogueur, d’autant plus qu’il enregistre un journal des incidents.
Même s'ils ont exécuté votre application sous le débogueur avec tous ces points d'arrêt définis, un point d'arrêt n'est atteint que lorsque votre programme atteint ce point. L'un de ces points d'arrêt ne peut donc se déclencher que si vous ou Cocoa avez appelé _NSLockError
, -[NSException raise]
ou objc_exception_throw
. Arriver à ce point ne serait pas la cause du problème, ce serait un symptôme du problème.
Et si vous rencontriez un problème suite à l'appel de l'un de ceux-ci, l'un au moins de ces journaux serait nommé dans celui-ci. Ce n'est pas.
Donc, cela n'était pas lié à vos points d'arrêt (machine différente, débogueur non impliqué), et ce n'était pas une exception Cocoa - comme je l'ai mentionné, les exceptions Cocoa sont l'une des causes des SIGTRAP, mais elles ne sont pas les seules. Vous avez rencontré un autre.
Sinon, quelqu'un d'autre a-t-il eu des problèmes similaires avec [NSFont fontWithName: size:]?
Nous ne pouvons absolument pas savoir si les problèmes que nous avons rencontrés sont similaires, car vous avez coupé le journal des accidents. Nous ne savons rien du contexte dans lequel l'accident s'est produit.
La seule chose qu’il est bon de supprimer est la section «Images binaires», car nous n’avons pas vos bundles dSYM, ce qui signifie que nous ne pouvons pas utiliser cette section pour symboliser le journal des pannes.
Vous, d'autre part, pouvez. J'ai écrit une application à cette fin. alimentez le journal des incidents et il devrait détecter automatiquement le groupe dSYM (vous le conservez pour chaque version de version distribuée, n'est-ce pas?) et restaurez les noms de vos fonctions et méthodes dans la trace de la pile, où que vos fonctions et méthodes apparaissent.
Pour plus d'informations, consultez le Guide de débogage Xcode .
Il est extrêmement probable qu'une police corrompue soit installée sur cet utilisateur. Le tracé de la pile confirme définitivement cette hypothèse, tout comme le fait qu’elle n’affecte que le même utilisateur.
Dans ce cas, il n'y a pas grand chose à faire à part demander à l'utilisateur de supprimer la police incriminée, car les blocages survenus se produisent au plus profond du code Apple.
Essayez de demander à l'utilisateur d'exécuter une validation de police dans le livre de polices. Pour ce faire, lancez Font Book, cliquez sur Toutes les polices dans la liste des sources, puis sélectionnez toutes les polices répertoriées. Vous pouvez ensuite sélectionner Valider les polices dans le menu Fichier .
Les points d'arrêt ne sont pas écrits dans le binaire. Les chances sont bonnes que cette personne ait une installation de système d'exploitation défectueuse. Vérifiez les journaux de la console pour les messages dyld.
J'ai eu la même erreur. Pour une raison inexplicable, le point d'arrêt était responsable du lancement de l'exception EXC_BREAKPOINT. La solution consistait à supprimer le point d'arrêt, puis le code fonctionnait.
EXC_BREAKPOINT est un type d'exception utilisé par les débogueurs. Lorsque vous définissez un point d'arrêt dans votre code, le compilateur insère une exception de ce type dans le code exécutable. Lorsque l'exécution atteint ce point, l'exception est levée et le débogueur l'attrape. Ensuite, le débogueur affiche votre code dans la ligne "Point d'arrêt". Voici comment fonctionnent les débogueurs. Mais dans ce cas, le débogueur ne gère pas l’exception correctement et est présenté comme une erreur d’exception ordinaire.
J'ai trouvé cette erreur deux fois dans ma vie: