web-dev-qa-db-fra.com

Comment attraper un crash de Swift et faire de la journalisation

Dans Objective-C, la variable NSSetUncaughtExceptionHandler peut enregistrer certaines fonctionnalités permettant de consigner des informations de dernière minute sur l'exception.

Cela n'attrape pas quelque chose qui tombe en panne de Swift.

Est-il possible de faire quelque chose comme ça au niveau mondial dans Swift? Par exemple. faire de la journalisation si un plantage survient dans le code Swift, comme le décompressage forcé de la valeur nil optionnel.

Plus précisément, je crée un utilitaire pour enregistrer le trafic réseau dans l'application et je voudrais vider mes données en mémoire sur le disque en cas de blocage.

12
Ken Ko

NSSetUncaughtExceptionHandler fonctionne uniquement avec NSExceptions. Voir this SO answer pour une explication brillante.

Pour corriger les erreurs de temps d'exécution Swift, implémentez le gestionnaire de signal pour SIGTRAP. Autant que je sache, le code Swift mettra fin au programme avec le type d'exception SIGTRAP s'il détecte une condition inattendue à l'exécution, c'est-à-dire que seul SIGTRAP est utile pour intercepter les erreurs Swift. Restez comme SIGSEGV, SIGBUS, SIGILL ne fonctionne pas. J'ai trouvé cette information dans this Apple link.

Si votre code est un mélange d'Objective-C et de Swift, alors implémentez NSSetUncaughtExceptionHandler et le gestionnaire de signaux pour gérer les plantages.

Pour comprendre et mettre en œuvre le traitement du signal, reportez-vous à this link.

J'espère que cela t'aides.

6
SHN

Vos questions comportent de nombreux aspects. Permettez-moi d’essayer d’y répondre:

  1. NSSetUncaughtExceptionHandler ne détecte que les exceptions non capturées, qui ne représentent qu'un petit sous-ensemble d'accidents possibles.
  2. Les exceptions dans Objective-C sont définies comme fatales et il est déconseillé de les intercepter et encore plus de ne pas exécuter de code non asynchrone, qui inclut tout code Objective-C et Swift.
  3. Pour intercepter des blocages, vous devez configurer les gestionnaires de signaux, puis n'exécuter que du code asynchrone au moment du blocage, qui n'est qu'un petit sous-ensemble de C. Vous pouvez notamment ne pas allouer de nouvelle mémoire au moment du blocage.
  4. Rappelez-vous que lorsque votre application est bloquée, il s'agit d'un code extrêmement instable et les références d'objet ou de variable peuvent indiquer un événement complètement inattendu. Donc, vous ne devriez vraiment rien faire au moment de l'accident.
  5. Le meilleur moyen open source de gérer les pannes consiste à utiliser PLCrashReporter , qui fournit également une méthode permettant d’appeler du code au moment de la défaillance. Mais encore une fois, cela doit être asynchrone.

Pour votre scénario spécifique: vous ne devriez pas faire cela et ne pas essayer. Cela peut entraîner la corruption des données utilisateur ou la perte de davantage de données. L'application s'est écrasée avec des problèmes graves, résolvez plutôt le problème.

1
Kerni
NSSetUncaughtExceptionHandler(&HandleException);
signal(SIGABRT, SignalHandler);
signal(SIGILL, SignalHandler);
signal(SIGSEGV, SignalHandler);
signal(SIGFPE, SignalHandler);
signal(SIGBUS, SignalHandler);
signal(SIGPIPE, SignalHandler);

Cela fonctionnera dans la plupart des situations. Mais j'essaie aussi de trouver un moyen d'attraper tous les accidents. Eh bien, si vous appuyez sur ces signaux pour voir les documents, vous constaterez qu’il existe plus de 20 types de signaux. Ce que j’ai fait est le signal (, ) de tous les types de signaux. Cela semble fonctionner, mais peut-être encore un crash ne peut pas collecter.

0
Benjamin