2010-09-02 4 views
3

Je travaille sur un projet, où j'ai besoin d'obtenir une pile native de l'application Java. Je suis capable d'y parvenir partiellement. grâce à ptrace/multiprocessing et aux signaux.Multithreading, Multiprocessing avec STOP et Continue Signaux

sous Linux l'application Java normale a un nombre minimum de 14 threads. sur ces 14 je suis intéressé par le fil principal dont je dois obtenir la pile natif. compte tenu de cet objectif j'ai commencé un processus séparé en utilisant fork() qui surveille la pile native du thread principal. En bref, j'ai 2 processus séparés: l'un est surveillé et l'autre fait la surveillance en utilisant ptrace et la gestion des signaux.

étapes dans le processus de suivi:

1) obtenir thread principal-id de l'autre 14 fil du processus.

2) ptrace_attach main_ID

3) PTRACE_CONT main_ID

boucle continue commence

{

4) tuer (main_ID, SIGSTOP),

5) nanosleep et vérifier l'état à partir de/proc/[p id]/stat dir

6) PTRACE_PEEKDATA pour lire la pile et de naviguer

7) PTRACE_CONT main_ID

8) nanosleep et vérifier l'état de la/proc/[pid]/stat dir

}

9) PTRACE_DETACH main_ID

cela donne parfaitement la pile native i informations en continu. mais parfois je fais face à un problème.

La question:

quand j'envoie tuer (main_ID, SIGSTOP) pour fil conducteur, les autres threads du processus obtenir dans l'état fini ou stoped (T) et les blocs entiers de processus. ce n'est pas le comportement de consistance et tout le processus s'exécute correctement. Je ne pouvais pas comprendre ce comportement car je ne fais que signaler le thread principal, pourquoi d'autres threads en sont affectés? Est-ce que quelqu'un pourrait m'aider à analyser le problème? J'ai également essayé de faire des signaux CONT et STOP sur tous les threads du processus, mais le problème persiste parfois.

Merci, Sandeep

+0

d'après ce que j'ai compris jusqu'à présent. –

+0

il y a un gestionnaire de signal par défaut correspondant au signal au niveau du processus. lorsque le processus trouve un signal pour l'un quelconque de ses fils enfants, le signal respectif est traité par l'un quelconque du fil en fonction de l'état, c'est-à-dire occupé ou libre. cela pourrait être la raison des résultats incohérents pour moi. –

Répondre

0

En supposant que vous utilisez Linux, vous devriez utiliser tkill (2) ou tgkill (2) au lieu de tuer (2). Sur FreeBSD, vous devriez utiliser le SYS_thr_kill2 syscall. Par la tkill (2) manpage:

tgkill() envoie le signal sig au filetage avec le filetage ID tid dans le groupe de fils tgid.(En revanche, tuer (2) ne peut être utilisé pour envoyer un signal à un processus (c.-à-groupe de threads) dans son ensemble, et le signal seront livrés à un fil arbitraire dans ce processus.)

Ignorer les informations sur tkill (2) et les amis étant destinés à l'utilisation de la bibliothèque de threads interne, il est généralement utilisé par les débogueurs/traceurs pour envoyer des signaux à des threads spécifiques.

De même, vous devez utiliser waitpid (2) (ou une variante de celui-ci) pour attendre que le thread reçoive le signal SIGSTOP au lieu d'interroger/proc/[pid]/stat. Cette approche sera plus efficace et plus réactive. Enfin, il semble que vous effectuez une sorte d'échantillonnage de pile. Vous pouvez vouloir vérifier Google PerfTools car ces outils incluent un échantillonneur de CPU qui fait l'échantillonnage de pile pour obtenir des estimations des fonctions qui consomment le plus de temps de processeur. Vous pourriez peut-être réutiliser le travail que ces outils ont déjà fait, car l'échantillonnage en pile peut être difficile à rendre robuste.