GNU/Linux >> Linux Esercitazione >  >> Linux

Quale processo ha creato questa finestra X11?

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 tramite una connessione TCP. In tal caso, vorrei l'IP e la porta associati all'estremità remota.

La domanda è stata posta in precedenza su Stack Overflow e un metodo proposto consisteva nell'utilizzare il _NET_WM_PID proprietà. Ma questo è impostato dall'applicazione. C'è un modo per farlo se l'applicazione non funziona bene?

Risposta accettata:

A meno che il tuo server X non supporti XResQueryClientIds dall'estensione X-Resource v1.2 non conosco facile modo per affidabile ID processo di richiesta. Ci sono però altri modi.

Se hai solo una finestra di fronte a te e non conosci ancora il suo ID, è facile scoprirlo. Basta aprire un terminale vicino alla finestra in questione, eseguire xwininfo lì e fare clic su quella finestra. xwininfo ti mostrerà l'id della finestra.

Quindi supponiamo che tu conosca un window-id, ad es. 0x1600045 e vuoi trovare qual è il processo che lo possiede.

Il modo più semplice per verificare a chi appartiene quella finestra è eseguire XKillClient per essa, ad esempio:

xkill -id 0x1600045

e vedere quale processo è appena morto. Ma solo se non ti dispiace ucciderlo ovviamente!

Un altro modo semplice ma inaffidabile è controllare il suo _NET_WM_PID e WM_CLIENT_MACHINE proprietà:

xprop -id 0x1600045

Ecco quali strumenti come xlsclients e xrestop fare.

Sfortunatamente queste informazioni potrebbero essere errate non solo perché il processo era malvagio e li ha cambiati, ma anche perché era difettoso. Ad esempio, dopo alcuni arresti anomali/riavvii di Firefox ho visto finestre orfane (dal plug-in flash, immagino) con _NET_WM_PID indicando un processo, morto molto tempo fa.

Un modo alternativo è correre

xwininfo -root -tree

e controlla le proprietà dei genitori della finestra in questione. Questo potrebbe anche darti alcuni suggerimenti sulle origini della finestra.

Ma! Anche se potresti non trovare quale processo ha creato quella finestra, c'è ancora un modo per trovare da dove quel processo si è connesso a X-server. E questo è per i veri hacker. 🙂

Il window-id 0x1600045 che conosci con i bit inferiori azzerati (cioè 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 clients[], e per ogni client la sua "base" è memorizzata nella variabile clients[i]->clientAsMask. Per trovare X-socket, corrispondente a quel client, devi collegarti a X-server con gdb , passa sopra l'array clients[], trova il client con quel clientAsMask e stampa il suo descrittore di socket, memorizzato in ((OsCommPtr)(clients[i]->osPrivate))->fd.

Potrebbero esserci molti X-client collegati, quindi per non controllarli tutti manualmente, utilizziamo 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 la presa, puoi controllare chi è connesso ad essa e finalmente trovare il processo.

Correlati:come scaricare un'app dal negozio di Windows 10 per eseguire il sideload?

AVVISO :NON collegare gdb all'X-server dall'interno dell'X-server. gdb sospende il processo a cui si collega, quindi se ti colleghi ad esso dall'interno di X-session, congelerai il tuo server X e non sarai in grado di interagire con gdb. Devi passare al terminale di testo (Ctrl+Alt+F2 ) o connettiti alla tua macchina tramite ssh.

Esempio:

  1. Trova il PID del tuo server 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'ID della finestra è 0x1600045, quindi la base di clienti è 0x1600000. Collega a X-server e trova il descrittore di socket client per quella base di client. Avrai bisogno delle informazioni di debug
    installate per X-server (pacchetto -debuginfo per le 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 lsof per trovare qual è quella presa:

    $ 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 tramite TCP, quindi puoi andare alla macchina da cui è connesso e controllare netstat -nap lì 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 lsof per trovare il PID che lo tiene:

    $ 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 :Ci sono più opzioni ora come visto in Chi ha l'altra estremità di questa coppia di socket Unix?. Con Linux 3.3 o versioni successive e con lsof 4.89 o superiore, puoi sostituire i punti da 3 a 5 di cui 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.


Linux
  1. Cosa sono i processi zombi e come trovare e uccidere i processi zombi?

  2. È possibile scoprire quale programma o script ha creato un determinato file?

  3. Quali sono le cause dell'invio di vari segnali?

  4. Come verificare quali segnali sta ascoltando un processo?

  5. Come faccio a scoprire quale processo ha un blocco su un file in Linux?

Cosa indica questa statistica del processo?

Che terminale è questo?

SIGTERM vs SIGKILL:qual è la differenza?

Nessuna variabile DISPLAY X11 - cosa significa?

Cos'è un processo interrotto in Linux?

Scopri quale processo apache ad alto utilizzo della CPU sta effettivamente facendo?