2015-10-14 1 views
0

Considérons ce scénario:Android NDK: Poignée SIGSEGVs causés par un fil de Java côté

Il est une application Android qui fait des choses, ce qui pourrait être dans différents threads. Certains d'entre eux peuvent provoquer des violations de segmentation (SIGSEGV). Je veux être en mesure d'attraper toutes les violations, quel que soit le fil qui l'a causé, à partir d'un gestionnaire de signal écrit en C en utilisant NDK.

En fait, j'ai écrit un tel gestionnaire en utilisant sigaction. Et cela fonctionne mais seulement pour le thread qui va exécuter le code NDK. Cela est dû au fait que SIGSEGVs est livré au thread qui a causé la violation, contrairement à SIGKILL qui est livré au processus. Par conséquent, mon gestionnaire ne reçoit pas SIGSEGV provoqué par d'autres threads, et le programme est tué.

Existe-t-il un moyen de rediriger tous les SIGSEGV vers mon gestionnaire? Ou, alternativement, un moyen de remplacer le gestionnaire par défaut pour TOUS les threads?

Et oui, il y a une raison pour laquelle je veux cette chose particulière dans la façon dont je l'ai décrit! ;)

+1

Quelques informations ici: http://stackoverflow.com/questions/1083154/how-can-i-catch-sigsegv-segmentation-fault-and-get-a-stack-trace-under-jni-on/. Effectuez un appel JNI à partir de chacun de vos threads pour définir les gestionnaires de ce thread. Assurez-vous d'identifier vos plantages et chaînes spécifiques au gestionnaire précédent. – fadden

+0

@fadden désolé, ma question n'était pas très claire! Supposons que je n'aurai pas accès aux discussions. Je ne sais pas ce qu'une application pourrait faire, je veux juste gérer tous les SIGSEGV causés par elle. – Paschalis

+0

Ce que vous voulez est appelé handler d'exception uncaught. Il existe en Java, pas sûr de ce qu'on appelle en c/C++. – 18446744073709551615

Répondre

0

Vous pouvez attraper un SIGSEGV, mais vous ne pouvez pas libérer des ressources qui seraient gratuites si ce SIGSEGV ne s'est pas produit. Java a un garbage collector (et dans certains cas même gc ne sauvegarde pas des fuites de mémoire), mais le code c/C++ doit free() ou delete ou delete[] ce qu'il a alloué (mais pas alloca() -ed).

Je placerais les choses qui font les choses natives risquées dans un processus séparé. (Les applications Android peuvent être composées de plusieurs processus.) Lorsqu'un processus meurt, ses déchets meurent également. Et le processus principal devrait détecter que le processus de travail est mort.

+0

Je ne fais pas ça pour 'free's ou' malloc's! Je supprime les autorisations des pages virtuelles en utilisant 'mprotect'. Ces pages sont probablement utilisées par d'autres threads. Un 'sigsegv' se produit dans ce thread, et ce que je veux, c'est pouvoir le gérer. Donc j'ai besoin de le rediriger, ou autre chose. ** Est-ce possible? ** – Paschalis

+1

En d'autres termes, vous supprimez des autorisations sur les pages virtuelles et lorsqu'une exception se produit dans un thread, vous souhaitez redonner l'autorisation et reprendre l'exécution de ce thread. En théorie, cela devrait être possible. Ceci est très similaire à ce que font les débogueurs. Mais les débogueurs commencent généralement un processus enfant. Probablement un module noyau pourrait vous aider. Rédigez une description de votre tâche de gestion de mémoire en plus de simplement "attraper SIGSEGV", et posez une autre question SO l'étiquetant POSIX (ou recherchez en utilisant les mots de votre description et probablement "débogueur" et "module noyau"). – 18446744073709551615