Question

J'écris un débogueur orienté graphique qui cible principalement Linux, mais je prévois des ports pour d'autres systèmes d'exploitation dans le futur. Parce que l'interface graphique doit rester interactive à tout moment, j'ai quelques threads qui gèrent des choses différentes.

J'ai principalement un " événement de débogage " thread qui boucle simplement en attente du retour de waitpid et transmet les événements reçus aux autres threads. Je le fais parce que waitpid n’a pas de délai d’expiration, ce qui rend très difficile son intégration dans d’autres boucles d’événements et le maintien de la réactivité (waitpid peut être suspendu indéfiniment!).

Cette stratégie a fonctionné à merveille pour les versions de Linux jusqu’à présent. Dernièrement, j'ai essayé de rendre mon thread de débogueur conscient (comme dans les threads de l'application déboguée, pas avec le débogueur lui-même).

J'ai donc défini les options de ptrace pour suivre les événements de clonage et rechercher un statut dont les 16 bits supérieurs sont définis sur PTRACE_EVENT_CLONE . Ensuite, j'utilise PTRACE_GETEVENTMSG pour obtenir le TID du nouveau thread. Tout cela fonctionne bien dans mes petites applications de harnais de test. Mais pour une raison quelconque, il échoue lorsque je mets ce code dans mon débogueur actuel. (Je reçois un code d'erreur "Aucun processus de ce type")

La seule chose qui me soit venue à l’esprit est que Windows a pour règle que seul le fil relié à une application peut écouter les événements de débogage. Ptrace de Linux a-t-il une limitation similaire? Si tel est le cas, pourquoi mon code fonctionne-t-il pour d'autres événements de débogage?

EDIT:

Il semble qu'au moins waitpid prenne en charge l'attente d'un autre thread, la page de manuel indique:

  

Avant Linux 2.4, un thread était juste un   cas particulier d'un processus, et en tant que   conséquence un fil ne pouvait pas attendre sur le   les enfants d'un autre fil, même quand   ce dernier appartient au même fil   groupe. Cependant, POSIX prescrit   telle fonctionnalité, et depuis Linux 2.4 une   thread peut, et par défaut   va, attendre sur les enfants d'autres   discussions dans le même groupe de discussions.

Donc, tout au plus, c’est une limitation de ptrace.

Était-ce utile?

La solution

Autant que je sache, ceci n’est pas autorisé. Une tâche ne peut pas utiliser ptrace sur une tâche qu’elle n’a pas jointe. De plus, une tâche peut être tracée par au plus une autre tâche, vous ne pouvez donc pas simplement l'attacher une fois dans chaque fil. Je pense que cela est dû au fait que, lorsqu'une tâche est attachée à une autre tâche, la tâche de traçage devient le parent de la tâche suivie et chaque tâche ne peut avoir qu'un seul parent.

Il semble que le traçage multi-thread devrait être autorisé car les threads font partie du même processus, mais en ce qui concerne l'implémentation, il n'y a pas beaucoup de distinction entre les threads et les processus dans le noyau Linux. Un thread est simplement une tâche qui partage la plupart de ses ressources avec une autre tâche.

Si cela vous intéresse, vous pouvez parcourir le code source pour ptrace dans le noyau. En particulier, consultez ptrace_check_attach , appelé par sys_ptrace pour la plupart des demandes. Il renvoie -ESRCH (cela ressemble au code d'erreur que vous obtenez) si le parent de la tâche cible n'est pas la tâche actuelle.

Autres conseils

J'ai eu le même problème (plus de nombreux autres!) en implémentant la partie spécifique à Linux du Débogueur Maxine VM . Vous avez raison de penser que seul un thread du débogueur peut utiliser ptrace pour contrôler le débogage. Pour ce faire, nous effectuons tous les appels à ptrace sur un thread dédié. Vous trouverez peut-être utile de consulter les fichiers LinuxTask.java, linuxTask.h et linuxTask.c dans les sources Maxine disponibles à l'adresse kenai.com/projects/maxine/sources/maxine/show

.
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top