A meno che il tuo X-server supporti XResQueryClientIdsdall'estensione X-Resource v1.2 non conosco un modo semplice per richiedere in modo affidabile l' ID del processo. Ci sono altri modi comunque.
Se hai solo una finestra davanti a te e non conosci ancora il suo ID - è facile scoprirlo. Basta aprire un terminale vicino alla finestra in questione, correre xwininfolì e fare clic su quella finestra. xwininfoti mostrerà l'ID finestra.
Supponiamo quindi che tu conosca un ID finestra, ad es. 0x1600045, e desideri trovare qual è il processo che lo possiede.
Il modo più semplice per verificare a chi appartiene quella finestra è eseguire XKillClient per questo, ovvero:
xkill -id 0x1600045
e vedi quale processo è appena morto. Ma solo se non ti dispiace ucciderlo ovviamente!
Un altro modo semplice ma inaffidabile è di controllarne le proprietà _NET_WM_PIDe le WM_CLIENT_MACHINEproprietà:
xprop -id 0x1600045
Ecco cosa piacciono xlsclientse xrestopfanno gli strumenti .
Sfortunatamente queste informazioni potrebbero essere errate non solo perché il processo era malvagio e ha cambiato quelle, ma anche perché era difettoso. Ad esempio, dopo un arresto / riavvio di Firefox, ho visto finestre orfane (dal plug-in flash, immagino) con _NET_WM_PIDun processo che è morto molto tempo fa.
Un modo alternativo è quello di correre
xwininfo -root -tree
e controlla le proprietà dei genitori della finestra in questione. Ciò potrebbe anche darti alcuni suggerimenti sulle origini delle finestre.
Ma! Anche se potresti non trovare quale processo ha creato quella finestra, c'è ancora un modo per trovare da dove quel processo si è connesso all'X-server. E in questo modo è per veri hacker. :)
L'ID finestra 0x1600045 che si conosce con bit inferiori azzerati (ovvero 0x1600000) è una "base client". E tutti gli ID risorsa, allocati per quel client, sono "basati" su di esso (0x1600001, 0x1600002, 0x1600003, ecc.). X-server memorizza le informazioni sui suoi client nell'array client [] e per ogni client la sua "base" è memorizzata nei client [i] -> clientAsMask. Per trovare X-socket, corrispondente a quel client, è necessario collegarsi a X-server con gdb, camminare sull'array client [], trovare client con quello clientAsMaske stampare il suo descrittore socket, memorizzato in ((OsCommPtr) (client [i] - > osPrivate)) -> fd.
Potrebbero esserci molti client X collegati, quindi per non controllarli tutti manualmente, usiamo una funzione 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
Quando trovi il socket, puoi controllare chi è collegato ad esso e infine trovare il processo.
ATTENZIONE : NON collegare gdb a X-server da INSIDE X-server. gdb sospende il processo a cui si allega, quindi se ci si collega da dentro X-session, si bloccherà il proprio X-server e non sarà in grado di interagire con gdb. È necessario passare al terminale di testo ( Ctrl+Alt+F2) o connettersi al proprio computer tramite ssh.
Esempio:
Trova il PID del tuo X-server:
$ ps ax | grep X
1237 tty1 Ssl+ 11:36 /usr/bin/X :0 vt1 -nr -nolisten tcp -auth /var/run/kdm/A:0-h6syCa
L'ID della finestra è 0x1600045, quindi la base client è 0x1600000. Collegarsi a X-server e trovare il descrittore del socket client per quella base client. Avrai bisogno di informazioni di debug installate per X-server (pacchetto -debuginfo per distribuzioni rpm o pacchetto -dbg per 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
Ora sai che il client è connesso a un socket del server 31. Usa lsofper trovare cos'è quel socket:
$ sudo lsof -n | grep 1237 | grep 31
X 1237 root 31u unix 0xffff810008339340 8512422 socket
(qui "X" è il nome del processo, "1237" è il suo pid, "root" è l'utente da cui è in esecuzione, "31u" è un descrittore di socket)
Lì potresti vedere che il client è connesso su TCP, quindi puoi andare al computer da cui è connesso e controllare netstat -naplì per trovare il processo. Ma molto probabilmente vedrai un socket unix lì, come mostrato sopra, il che significa che è un client locale.
Per trovare una coppia per quel socket unix puoi usare la tecnica di MvG
(avrai anche bisogno di informazioni di debug per il tuo kernel installato):
$ sudo gdb -c /proc/kcore
(gdb) print ((struct unix_sock*)0xffff810008339340)->peer
$1 = (struct sock *) 0xffff810008339600
(gdb) quit
Ora che conosci il socket client, usa lsofper trovare PID che lo trattiene:
$ sudo lsof -n | grep 0xffff810008339600
firefox 7725 username 146u unix 0xffff810008339600 8512421 socket
Questo è tutto. Il processo che mantiene quella finestra è "firefox" con ID processo 7725
Modifica 2017 : ora ci sono più opzioni come visto in Chi ha l'altra estremità di questa socket unix? . Con Linux 3.3 o versioni successive e con lsof4.89 o versioni successive, è possibile sostituire i punti da 3 a 5 sopra con:
lsof +E -a -p 1237 -d 31
per scoprire chi si trova all'altra estremità del socket su fd 31 del processo X-server con ID 1237.