Es sei denn , Ihr X-Server unterstützt XResQueryClientIds
von v1.2 Erweiterung X-Ressource weiß , dass ich keine einfache Art und Weise zu zuverlässig Prozess - ID anfordern. Es gibt jedoch auch andere Möglichkeiten.
Wenn Sie nur ein Fenster vor sich haben und dessen ID noch nicht kennen, können Sie es leicht herausfinden. Öffnen Sie einfach ein Terminal neben dem betreffenden Fenster, führen Sie xwininfo
es aus und klicken Sie auf dieses Fenster. xwininfo
zeigt Ihnen die Fenster-ID.
Nehmen wir also an, Sie kennen eine Fenster-ID, z. B. 0x1600045, und möchten herausfinden, in welchem Prozess sie sich befindet.
Am einfachsten können Sie überprüfen, wem dieses Fenster gehört, indem Sie XKillClient für dieses Fenster ausführen.
xkill -id 0x1600045
und sehen, welcher Prozess gerade gestorben ist. Aber nur, wenn Sie nichts dagegen haben, es natürlich zu töten!
Eine weitere einfache aber unzuverlässig Art und Weise ist die zu überprüfen _NET_WM_PID
und WM_CLIENT_MACHINE
Eigenschaften:
xprop -id 0x1600045
Das ist, was Werkzeuge mögen xlsclients
und xrestop
tun.
Leider können diese Informationen nicht nur falsch sein, weil der Prozess schlecht war und diese geändert hat, sondern auch, weil er fehlerhaft war. Zum Beispiel habe ich nach einem Firefox-Absturz / Neustart verwaiste Fenster (vom Flash-Plugin, denke ich) mit einem _NET_WM_PID
Hinweis auf einen Prozess gesehen, der vor langer Zeit gestorben ist.
Alternative 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 Fensterherkunft geben.
Aber! Sie können möglicherweise nicht feststellen, von welchem Prozess dieses Fenster erstellt wurde, aber es gibt immer noch eine Möglichkeit, festzustellen, von wo aus dieser Prozess eine Verbindung zum X-Server hergestellt hat. Und so ist es für echte Hacker. :)
Die Windows-ID 0x1600045, die Sie kennen, wenn niedrigere Bits auf Null gesetzt sind (dh 0x1600000), ist eine "Client-Basis". Alle für diesen Client zugewiesenen Ressourcen-IDs basieren darauf (0x1600001, 0x1600002, 0x1600003 usw.). X-Server speichert Informationen zu seinen Clients im clients [] -Array und für jeden Client wird seine "Basis" in der clientAsMask-Variablen [i] -> gespeichert. Um den X-Socket zu finden, der diesem Client entspricht, müssen Sie eine Verbindung zum X-Server mit dem gdb
Array clients [] herstellen, den Client damit suchen clientAsMask
und dessen Socket-Deskriptor ausgeben, der in ((OsCommPtr) (clients [i] - > osPrivate)) -> fd.
Möglicherweise sind viele X-Clients verbunden. 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 gefunden haben, können Sie überprüfen, wer mit ihm verbunden ist, und schließlich den Prozess finden.
WARNUNG : Schließen Sie KEINE GDB von INNERHALB des X-Servers an den X-Server an. gdb unterbricht den Prozess, mit dem es verbunden ist. Wenn Sie also innerhalb von X-session eine Verbindung herstellen, frieren Sie Ihren X-Server ein und können nicht mehr mit gdb interagieren. Sie müssen entweder zum Textterminal ( Ctrl+Alt+F2
) wechseln oder über ssh eine Verbindung zu Ihrem Computer herstellen.
Beispiel:
Finden Sie die PID Ihres X-Servers:
$ ps ax | grep X
1237 tty1 Ssl+ 11:36 /usr/bin/X :0 vt1 -nr -nolisten tcp -auth /var/run/kdm/A:0-h6syCa
Die Fenster-ID lautet 0x1600045, die Client-Basis also 0x1600000. Stellen Sie eine Verbindung zum X-Server her und suchen Sie den Client-Socket-Deskriptor für diese Client-Basis. Sie müssen Debug-Informationen für X-Server installiert haben (-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
Jetzt wissen Sie, dass der Client mit einem Server-Socket 31 verbunden lsof
ist.
$ sudo lsof -n | grep 1237 | grep 31
X 1237 root 31u unix 0xffff810008339340 8512422 socket
(hier ist "X" der Prozessname, "1237" die PID, "root" der Benutzer, von dem aus er ausgeführt wird, "31u" ist ein Socket-Deskriptor)
Dort sehen Sie möglicherweise, dass der Client über TCP verbunden ist, und können dann zu dem Computer gehen, von dem aus die Verbindung hergestellt wurde, und netstat -nap
dort nach dem Prozess suchen. Aber höchstwahrscheinlich sehen Sie dort einen Unix-Socket, wie oben gezeigt, was bedeutet, dass es sich um einen lokalen Client handelt.
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
Nun, da Sie den Client-Socket kennen, können lsof
Sie die PID ermitteln, in der sich der Socket befindet :
$ sudo lsof -n | grep 0xffff810008339600
firefox 7725 username 146u unix 0xffff810008339600 8512421 socket
Das ist es. Der Prozess, der dieses Fenster beibehält, ist "Firefox" mit der Prozess-ID 7725
2017 Edit : Es gibt jetzt mehr Optionen, wie unter Wer hat das andere Ende dieses Unix-Socketpaars? . Ab Linux 3.3 und lsof
4.89 können Sie die obigen Punkte 3 bis 5 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.