GNU/Linux >> LINUX-Kenntnisse >  >> Linux

Welcher Prozess hat dieses X11-Fenster erstellt?

Gibt es bei einer X11-Fenster-ID eine Möglichkeit, die ID des Prozesses zu finden, der sie erstellt hat?

Das ist natürlich nicht immer möglich, zum Beispiel wenn das Fenster über eine TCP-Verbindung kam. Für diesen Fall möchte ich die IP und den Port, die dem Remote-Ende zugeordnet sind.

Die Frage wurde zuvor bei Stack Overflow gestellt, und eine vorgeschlagene Methode war die Verwendung von _NET_WM_PID Eigentum. Aber das wird von der Anwendung festgelegt. Gibt es eine Möglichkeit, dies zu tun, wenn die Anwendung nicht gut funktioniert?

Akzeptierte Antwort:

Es sei denn, Ihr X-Server unterstützt XResQueryClientIds Von X-Resource v1.2 Extension kenne ich keine easy Weg zu zuverlässig Prozess-ID anfordern. Es gibt jedoch auch andere Möglichkeiten.

Wenn Sie gerade ein Fenster vor sich haben und seine ID noch nicht kennen, ist es einfach, sie herauszufinden. Öffnen Sie einfach ein Terminal neben dem betreffenden Fenster und führen Sie xwininfo aus dort und klicken Sie auf dieses Fenster. xwininfo zeigt Ihnen die Fenster-ID.

Nehmen wir also an, Sie kennen eine Fenster-ID, z. 0x1600045 und möchten herausfinden, welcher Prozess es besitzt.

Der einfachste Weg, um zu überprüfen, wem dieses Fenster gehört, besteht darin, XKillClient dafür auszuführen, z. B.:

xkill -id 0x1600045

und sehen, welcher Prozess gerade gestorben ist. Aber natürlich nur, wenn es dir nichts ausmacht, es zu töten!

Eine weitere einfache, aber unzuverlässige Möglichkeit besteht darin, die _NET_WM_PID zu überprüfen und WM_CLIENT_MACHINE Eigenschaften:

xprop -id 0x1600045

Dafür sorgen Tools wie xlsclients und xrestop tun.

Leider können diese Informationen nicht nur falsch sein, weil der Prozess böse war und diese geändert hat, sondern auch weil er fehlerhaft war. Zum Beispiel habe ich nach einem Absturz/Neustart von Firefox verwaiste Fenster (vom Flash-Plugin, schätze ich) mit _NET_WM_PID gesehen Hinweis auf einen Prozess, der vor langer Zeit gestorben ist.

Alternativer Weg ist zu laufen

xwininfo -root -tree

und überprüfen Sie die Eigenschaften der Eltern des betreffenden Fensters. Das kann Ihnen auch Hinweise auf die Herkunft von Fenstern geben.

Aber! Auch wenn Sie möglicherweise nicht herausfinden, welcher Prozess dieses Fenster erstellt hat, gibt es dennoch eine Möglichkeit herauszufinden, von wo aus sich dieser Prozess mit dem X-Server verbunden hat. Und dieser Weg ist für echte Hacker. 🙂

Die Fenster-ID 0x1600045, von der Sie wissen, dass die unteren Bits auf Null gesetzt sind (dh 0x1600000), ist eine „Client-Basis“. Und alle diesem Client zugewiesenen Ressourcen-IDs „basieren“ darauf (0x1600001, 0x1600002, 0x1600003 usw.). Der X-Server speichert Informationen über seine Clients im Array "clients[]", und für jeden Client wird seine "Basis" in der Variablen "clients[i]->clientAsMask" gespeichert. Um den X-Socket zu finden, der diesem Client entspricht, müssen Sie sich mit gdb an den X-Server anhängen , gehen Sie über das client[]-Array, finden Sie den Client mit diesem clientAsMask und drucke seinen Socket-Deskriptor, gespeichert in ((OsCommPtr)(clients[i]->osPrivate))->fd.

Es können viele X-Clients verbunden sein, um sie also nicht alle manuell zu überprüfen, verwenden wir eine gdb-Funktion:

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

Wenn Sie den Socket finden, können Sie überprüfen, wer damit verbunden ist, und schließlich den Prozess finden.

Verwandte:Wie lade ich eine App aus dem Windows 10 Store herunter, um sie von der Seite zu laden?

WARNUNG :Hängen Sie gdb NICHT von INNERHALB des X-Servers an den X-Server an. gdb unterbricht den Prozess, an den es angehängt ist. Wenn Sie sich also innerhalb von X-session daran anhängen, werden Sie Ihren X-Server einfrieren und können nicht mit gdb interagieren. Sie müssen entweder zum Textterminal wechseln (Ctrl+Alt+F2 ) oder stellen Sie über ssh eine Verbindung zu Ihrem Computer her.

Beispiel:

  1. Finden Sie die PID Ihres X-Servers heraus:

    $ 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. Die Fenster-ID ist 0x1600045, also ist die Client-Basis 0x1600000. Verbinden Sie sich mit dem X-Server und finden Sie den Client-Socket-Deskriptor für diese Client-Basis. Sie müssen Debug-Informationen
    für X-Server installieren (-debuginfo-Paket für RPM-Distributionen oder -dbg-Paket für Debs).

    $ 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. Jetzt wissen Sie, dass der Client mit einem Server-Socket 31 verbunden ist. Verwenden Sie lsof um herauszufinden, was dieser Socket ist:

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

    (hier ist „X“ der Prozessname, „1237“ ist seine PID, „root“ ist der Benutzer, von dem aus er läuft, „31u“ ist ein Socket-Deskriptor)

    Dort sehen Sie möglicherweise, dass der Client über TCP verbunden ist, dann können Sie zu dem Computer gehen, von dem aus er verbunden ist, und netstat -nap überprüfen dort, um den Prozess zu finden. Aber höchstwahrscheinlich sehen Sie dort einen Unix-Socket, wie oben gezeigt, was bedeutet, dass es sich um einen lokalen Client handelt.

  4. Um ein Paar für diesen Unix-Socket zu finden, können Sie die MvG-Technik verwenden (Sie benötigen auch Debug-Informationen für Ihren installierten Kernel):

    $ sudo gdb -c /proc/kcore
    (gdb) print ((struct unix_sock*)0xffff810008339340)->peer
    $1 = (struct sock *) 0xffff810008339600
    (gdb) quit
    
  5. Nachdem Sie nun den Client-Socket kennen, verwenden Sie lsof um die PID zu finden, die sie enthält:

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

Das ist es. Der Prozess, der dieses Fenster behält, ist „firefox“ mit der Prozess-ID 7725

2017 bearbeiten :Es gibt jetzt mehr Optionen, wie unter Who’s got the other end of this unix socketpair? zu sehen ist. Mit Linux 3.3 oder höher und mit lsof 4.89 oder höher können Sie die Punkte 3 bis 5 oben ersetzen durch:

lsof +E -a -p 1237 -d 31

um herauszufinden, wer sich am anderen Ende des Sockets auf fd 31 des X-Server-Prozesses mit der ID 1237 befindet.


Linux
  1. Was ist Ihr Lieblings-Linux-Fenstermanager?

  2. Was sind Zombie-Prozesse und wie findet und tötet man Zombie-Prozesse?

  3. Wie finde ich heraus, welche Linux-Fähigkeiten ein Prozess benötigt, um zu funktionieren?

  4. Was sind ausstehende Signale?

  5. Finden Sie heraus, was der Apache-Prozess mit hoher CPU-Auslastung tatsächlich tut?

Was zeigt diese Prozessstatistik an?

Welches Terminal ist das?

SIGTERM vs. SIGKILL:Was ist der Unterschied?

Keine X11-DISPLAY-Variable - was bedeutet das?

Was ist ein gestoppter Prozess unter Linux?

Was ist ein Befehl, um die Priorität des Prozesses in Linux zu finden?