GNU/Linux >> Tutoriels Linux >  >> Linux

Quel processus a créé cette fenêtre X11 ?

Étant donné un ID de fenêtre X11, existe-t-il un moyen de trouver l'ID du processus qui l'a créé ?

Bien sûr, ce n'est pas toujours possible, par exemple si la fenêtre est arrivée via une connexion TCP. Dans ce cas, j'aimerais connaître l'adresse IP et le port associés à l'extrémité distante.

La question a déjà été posée sur Stack Overflow, et une méthode proposée consistait à utiliser le _NET_WM_PID biens. Mais c'est défini par l'application. Existe-t-il un moyen de le faire si l'application ne fonctionne pas correctement ?

Réponse acceptée :

Sauf si votre serveur X prend en charge XResQueryClientIds de l'extension X-Resource v1.2 je ne connais pas facile moyen de fiable ID de processus de demande. Il existe cependant d'autres moyens.

Si vous avez juste une fenêtre devant vous et que vous ne connaissez pas encore son identifiant, il est facile de le découvrir. Ouvrez simplement un terminal à côté de la fenêtre en question, exécutez xwininfo là et cliquez sur cette fenêtre. xwininfo vous montrera le window-id.

Supposons donc que vous connaissiez un identifiant de fenêtre, par ex. 0x1600045, et que vous voulez trouver, quel est le processus qui le possède.

Le moyen le plus simple de vérifier à qui appartient cette fenêtre est d'exécuter XKillClient pour elle, c'est-à-dire :

xkill -id 0x1600045

et voir quel processus vient de mourir. Mais seulement si cela ne vous dérange pas de le tuer bien sûr !

Un autre moyen simple mais peu fiable est de vérifier son _NET_WM_PID et WM_CLIENT_MACHINE propriétés :

xprop -id 0x1600045

C'est ce que des outils comme xlsclients et xrestop faire.

Malheureusement, ces informations peuvent être incorrectes non seulement parce que le processus était mauvais et les a modifiés, mais aussi parce qu'il était bogué. Par exemple, après un crash/redémarrage de firefox, j'ai vu des fenêtres orphelines (du plugin flash, je suppose) avec _NET_WM_PID pointant vers un processus, qui est mort il y a longtemps.

Une autre façon est de courir

xwininfo -root -tree

et vérifiez les propriétés des parents de la fenêtre en question. Cela peut également vous donner des indices sur les origines des fenêtres.

Mais! Bien que vous ne trouviez peut-être pas quel processus a créé cette fenêtre, il existe toujours un moyen de savoir d'où ce processus s'est connecté au serveur X. Et cette façon est pour les vrais pirates. 🙂

L'identifiant de fenêtre 0x1600045 que vous connaissez avec les bits inférieurs mis à zéro (c'est-à-dire 0x1600000) est une "base client". Et tous les ID de ressource, alloués pour ce client sont "basés" dessus (0x1600001, 0x1600002, 0x1600003, etc.). Le serveur X stocke des informations sur ses clients dans le tableau clients[] et, pour chaque client, sa "base" est stockée dans la variable clients[i]->clientAsMask. Pour trouver X-socket, correspondant à ce client, vous devez vous connecter au serveur X avec gdb , parcourez le tableau clients[], trouvez le client avec ce clientAsMask et affiche son descripteur de socket, stocké dans ((OsCommPtr)(clients[i]->osPrivate))->fd.

Il peut y avoir de nombreux clients X connectés, donc pour ne pas tous les vérifier manuellement, utilisons une fonction gdb :

define findclient
  set $ii = 0
  while ($ii < currentMaxClients)
    if (clients[$ii] != 0 && clients[$ii]->clientAsMask == $arg0 && clients[$ii]->osPrivate != 0)
      print ((OsCommPtr)(clients[$ii]->osPrivate))->fd
    end
    set $ii = $ii + 1
  end
end

Lorsque vous trouvez la prise, vous pouvez vérifier qui y est connecté et enfin trouver le processus.

Connexe :Comment télécharger une application à partir de la boutique Windows 10 pour la télécharger ?

AVERTISSEMENT :N'attachez PAS gdb au serveur X depuis l'INTÉRIEUR du serveur X. gdb suspend le processus auquel il s'attache, donc si vous vous y attachez depuis l'intérieur de la session X, vous gèlerez votre serveur X et ne pourrez pas interagir avec gdb. Vous devez soit passer en terminal texte (Ctrl+Alt+F2 ) ou connectez-vous à votre machine via ssh.

Exemple :

  1. Trouvez le PID de votre serveur X :

    $ ps ax | grep X
     1237 tty1     Ssl+  11:36 /usr/bin/X :0 vt1 -nr -nolisten tcp -auth /var/run/kdm/A:0-h6syCa
    
  2. L'identifiant de la fenêtre est 0x1600045, donc la base client est 0x1600000. Connectez-vous au serveur X et recherchez le descripteur de socket client pour cette base de clients. Vous aurez besoin des informations de débogage
    installées pour le serveur X (paquet -debuginfo pour les distributions rpm ou paquet -dbg pour deb).

    $ sudo gdb
    (gdb) define findclient
    Type commands for definition of "findclient".
    End with a line saying just "end".
    >  set $ii = 0
    >  while ($ii < currentMaxClients)
     >   if (clients[$ii] != 0 && clients[$ii]->clientAsMask == $arg0 && clients[$ii]->osPrivate != 0)
      >     print ((OsCommPtr)(clients[$ii]->osPrivate))->fd
      >     end
     >   set $ii = $ii + 1
     >   end
    >  end
    (gdb) attach 1237
    (gdb) findclient 0x1600000
    $1 = 31
    (gdb) detach
    (gdb) quit
    
  3. Vous savez maintenant que le client est connecté à un serveur socket 31. Utilisez lsof pour trouver ce qu'est cette prise :

    $ sudo lsof -n | grep 1237 | grep 31
    X        1237    root   31u   unix 0xffff810008339340       8512422 socket
    

    (ici "X" est le nom du processus, "1237" est son pid, "root" est l'utilisateur à partir duquel il s'exécute, "31u" est un descripteur de socket)

    Là, vous pouvez voir que le client est connecté via TCP, vous pouvez alors accéder à la machine à partir de laquelle il est connecté et vérifier netstat -nap là pour trouver le processus. Mais vous y verrez très probablement un socket Unix, comme indiqué ci-dessus, ce qui signifie qu'il s'agit d'un client local.

  4. Pour trouver une paire pour ce socket unix, vous pouvez utiliser la technique de MvG (vous aurez également besoin d'informations de débogage pour votre noyau installé) :

    $ sudo gdb -c /proc/kcore
    (gdb) print ((struct unix_sock*)0xffff810008339340)->peer
    $1 = (struct sock *) 0xffff810008339600
    (gdb) quit
    
  5. Maintenant que vous connaissez le socket client, utilisez lsof pour trouver le PID qui le contient :

    $ sudo lsof -n | grep 0xffff810008339600
    firefox  7725  username  146u   unix 0xffff810008339600       8512421 socket
    

C'est ça. Le processus qui conserve cette fenêtre est "firefox" avec l'ID de processus 7725

Modification 2017 :Il y a plus d'options maintenant comme on le voit sur Qui a l'autre bout de cette paire de sockets unix ?. Avec Linux 3.3 ou supérieur et avec lsof 4.89 ou supérieur, vous pouvez remplacer les points 3 à 5 ci-dessus par :

lsof +E -a -p 1237 -d 31

pour savoir qui est à l'autre bout du socket sur fd 31 du processus X-server avec l'ID 1237.


Linux
  1. Quel est votre gestionnaire de fenêtres Linux préféré ?

  2. Que sont les processus zombies et comment trouver et tuer les processus zombies ?

  3. Comment savoir de quelles capacités Linux un processus a besoin pour fonctionner ?

  4. Que sont les signaux en attente ?

  5. Découvrez ce que fait réellement le processus apache à forte utilisation du processeur ?

Qu'est-ce que cette statistique de processus indique ?

De quel terminal s'agit-il ?

SIGTERM vs SIGKILL :Quelle est la différence ?

Pas de variable DISPLAY X11 - qu'est-ce que cela signifie ?

Qu'est-ce qu'un processus arrêté sous Linux ?

Qu'est-ce qu'une commande pour trouver la priorité d'un processus sous Linux ?