Quale processo ha creato questa finestra X11?


75

Dato un ID finestra X11, c'è un modo per trovare l'ID del processo che lo ha creato?

Ovviamente questo non è sempre possibile, ad esempio se la finestra è arrivata su una connessione TCP. In tal caso, vorrei l'IP e la porta associati all'estremità remota.

La domanda era stata posta in precedenza su Stack Overflow e un metodo proposto era di utilizzare la _NET_WM_PIDproprietà. Ma questo è impostato dall'applicazione. C'è un modo per farlo se l'applicazione non funziona bene?


Risposte:


60

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:

  1. 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
    
  2. 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
    
  3. 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.

  4. 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
    
  5. 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.


6
Benvenuti nello scambio di stack Unix e Linux! La tua risposta a questa domanda è eccellente. Spero che torni a rispondere ad altre domande.

36

xdotool non ha funzionato per me. Questo ha fatto:

Correre

xprop _NET_WM_PID

e fai clic sulla finestra.

Questo si basa sulla risposta su http://www.linuxquestions.org/questions/linux-software-2/advanced-question-finding-pid-of-an-x-window-328983/


Funziona per me quando si collega il mio Iphone ha portato un prompt della finestra non reattivo.
Modulitos,

1
Utile per dimostrare che a volte è appeso completamente. kill $(xprop _NET_WM_PID|cut -d " " -f 3)
Gabriel Devillers,

Questo è quello che stavo cercando, xkill flow
Rombus,

13

Se hai installato xdotool , allora

xdotool selectwindow getwindowpid

seguito da un clic sulla finestra in questione restituirà il PID.

(Esistono altri modi per selezionare la finestra in questione, ad esempio, se si dispone del relativo ID finestra, è possibile xdotool getwindowpid <number>selezionarlo. È anche possibile selezionare per nome o classe, ecc.)

Penso che questo richieda un po 'di gioco piacevole per conto del WM. Non ho sperimentato molto, o ne avevo bisogno.


2
xdo_getwinprop(xdo, window, atom_NET_WM_PID, &nitems, &type, &size)⇒ è solo un involucro della shell da leggere _NET_WM_PID(utile, ma non quello che ho chiesto).
Gilles 'SO- smetti di essere malvagio' il

11

Il _NET_WM_PIDnon è impostato dal gestore delle finestre (come solo un altro client X11, come potrebbe saperlo?).

Invece, i client X11 (applicazioni) conformi dovrebbero essere impostati _NET_WM_PIDe WM_CLIENT_MACHINEsulla propria finestra. Supponendo un'applicazione ben educata, questo sarà vero se un gestore di finestre è in esecuzione o meno.

Se WM_CLIENT_MACHINEè il tuo nome host, allora il PID dovrebbe essere significativo.
Altrimenti, "Vorrei l'IP e la porta associati all'estremità remota" - Non sono sicuro di cosa significhi. Ad esempio, se hai una sessione ssh aperta con l'inoltro X abilitato, le finestre aperte dalle app inoltrate saranno contrassegnate con PID remoto e nome host, ma non hai necessariamente modo di riconnetterti a quell'host remoto.


2
_NET_WM_PIDè impostato dall'applicazione: giusto, ha più senso! Ma non è il protocollo X11, è la specifica di FreeDesktop relativamente recente .
Gilles 'SO- smetti di essere cattivo'

Nel caso ssh, per quanto riguarda il server X, si tratta di una connessione locale dal processo sshd. Anche se _NET_WM_PIDsembra impostato al PID remoto e WM_CLIENT_MACHINEper il collegamento remoto (testato con xterm).
Gilles 'SO- smetti di essere cattivo'

4

Sono stato in grado di utilizzare la versione xdotoolbeta di Ubuntu 11.04, ma selectwindownon era un comando valido, ho dovuto hackerare uno script con:

$ while true; do sleep 1; xdotool getactivewindow; done

quindi guarda passare l'ID della finestra mentre seleziono la finestra desiderata, quindi decodifica il PID responsabile con:

$ xdotool getwindowpid <the-window-id>
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.