Imprimer les pids et les noms des processus lors de leur création

10

De la question ici , l'OP veut interroger à plusieurs reprises le pid d'un processus utilisant pidofdans un script shell. Bien sûr, cela est inefficace car un nouveau processus doit être démarré pidofplusieurs fois par seconde pour le programme (je ne sais pas si c'est la cause des pics de CPU dans la question, mais cela semble probable).

Habituellement, le moyen de contourner ce genre de chose dans un script shell est de travailler avec un seul programme qui génère les données dont vous avez besoin stdout, puis de faire du traitement de texte si nécessaire. Bien que cela implique davantage de programmes à exécuter simultanément, il est probable que le processeur soit moins gourmand car de nouveaux processus ne sont pas continuellement créés à des fins d'interrogation.

Donc, pour la question ci-dessus, une solution pourrait être d'avoir un programme qui génère les noms et les pids des processus lors de leur création. Ensuite, vous pourriez faire quelque chose comme:

pids-names |
  grep some_program |
  cut -f 2 |
  while read pid; do
    process-pid "$pid"
  done

Le problème avec cela est qu'il soulève une question plus fondamentale, comment les pids et les noms de processus peuvent-ils être imprimés lors de leur création?

J'ai trouvé un programme appelé ps-watcher, bien que le problème avec ceci soit que ce soit juste un perlscript qui s'exécute à plusieurs reprises, psdonc il ne résout pas vraiment le problème. Une autre option consiste à utiliser auditdce qui pourrait probablement fonctionner si le journal a été traité directement via tail -f. Une solution idéale serait plus simple et plus portable que cela, bien que j'accepte une auditdsolution si c'est la meilleure option.

Graeme
la source
1
Une note intéressante est que le pid est d'abord créé comme une copie du processus de création ( forkou variante), puis le nouveau programme est démarré en utilisant un membre de la execfamille. Donc, vous voulez probablement enregistrer le exec*, pas le fork.
derobert
2
Le seul moyen efficace et portable que je connaisse est d'utiliser la comptabilité de processus Unix ordinaire, qui écrira un enregistrement après la fin d' un processus. Si vous souhaitez intercepter les processus lors de leur création ou de leur exécution, vous avez probablement besoin d'éléments spécifiques au système tels que Linux auditd, systemtap ou dtrace.
Mark Plotnick
Donc, pour la question ci-dessus, une solution pourrait être d'avoir un programme qui génère les noms et les pids des processus lors de leur création. - Comme ils sont créés? Sons ce que vous pensez est un observateur (c'est ce qu'ils appellent dans le monde du navigateur Web). Je me demande si Python serait approprié pour agir en tant que "gardien de porte"? Les faits sont que Python peut creuser très profondément dans le fonctionnement interne du système (par exemple dbus).
erreur de syntaxe
1
@syntaxerror DBus est loin du fonctionnement interne du système dans ce cas - il s'agit en fait d'environ deux niveaux au-dessus de ce qui est discuté ici.
peterph
OK, dans le jargon OSI, le niveau discuté ici pourrait être encore inférieur à celui de dbus. J'avoue que je n'avais pas réfléchi en profondeur à savoir si les deux étaient au même niveau ou non.
erreur de syntaxe

Réponses:

6

Réponse spécifique à Linux:

perf-tools contient un execsnoop qui fait exactement cela. Il utilise diverses fonctionnalités spécifiques à Linux telles que ftrace. Sur Debian, son dans le paquet perf-tools-unstable .

Exemple de moi fonctionnant man catdans un autre terminal:

root@Zia:~# execsnoop 
TIME        PID   PPID ARGS
17:24:26  14189  12878 man cat 
17:24:26  14196  14189 tbl 
17:24:26  14195  14189 preconv -e UTF-8 
17:24:26  14199  14189 /bin/sh /usr/bin/nroff -mandoc -Tutf8 
17:24:26  14200  14189 less 
17:24:26  14201  14199 locale charmap 
17:24:26  14202  14199 groff -mtty-char -Tutf8 -mandoc 
17:24:26  14203  14202 troff -mtty-char -mandoc -Tutf8 
17:24:26  14204  14202 grotty 

Je doute qu'il existe un moyen portable de le faire.

derobert
la source
2

Il Right Way TM de faire cela dépend en grande partie sur ce système et noyau que vous êtes réellement en cours d' exécution sur. DTrace devrait fonctionner sur Solaris, Free / NetBSD et Linux.

Pour Linux en particulier, vous pouvez utiliser soit ftrace (qui doit être activé au moment de la compilation - c'est généralement le cas) soit des événements proc sur netlink - voir la réponse SO au problème pour plus de détails (et n'oubliez pas de voter, le score ~ 30 contre 0 pour la réponse acceptée semble drôle). Le traceur du pauvre pourrait probablement être mis en œuvre en utilisant strace -eexec,fork(bien qu'avec des frais généraux déraisonnables).

peterph
la source