GNU/Linux >> Tutoriales Linux >  >> Linux

¿Qué proceso creó esta ventana X11?

Dada una ID de ventana X11, ¿hay alguna forma de encontrar la ID del proceso que la creó?

Por supuesto, esto no siempre es posible, por ejemplo, si la ventana vino a través de una conexión TCP. Para ese caso, me gustaría la IP y el puerto asociados con el extremo remoto.

La pregunta se hizo antes en Stack Overflow, y un método propuesto fue usar el _NET_WM_PID propiedad. Pero eso lo establece la aplicación. ¿Hay alguna forma de hacerlo si la aplicación no funciona bien?

Respuesta aceptada:

A menos que su servidor X admita XResQueryClientIds de la extensión X-Resource v1.2 No sé fácil forma de confiable ID de proceso de solicitud. Sin embargo, hay otras formas.

Si solo tiene una ventana frente a usted y aún no conoce su ID, es fácil averiguarlo. Simplemente abra una terminal al lado de la ventana en cuestión, ejecute xwininfo allí y haga clic en esa ventana. xwininfo le mostrará la identificación de la ventana.

Entonces, supongamos que conoce una identificación de ventana, p. 0x1600045, y quiero saber cuál es el proceso que lo posee.

La forma más fácil de verificar a quién pertenece esa ventana es ejecutar XKillClient, es decir:

xkill -id 0x1600045

y ver qué proceso acaba de morir. ¡Pero solo si no te importa matarlo, por supuesto!

Otra forma fácil pero poco confiable es verificar su _NET_WM_PID y WM_CLIENT_MACHINE propiedades:

xprop -id 0x1600045

Eso es lo que hacen las herramientas como xlsclients y xrestop hacer.

Desafortunadamente, esta información puede ser incorrecta no solo porque el proceso fue malo y los cambió, sino también porque tenía errores. Por ejemplo, después de un bloqueo/reinicio de Firefox, he visto ventanas huérfanas (supongo que del complemento flash) con _NET_WM_PID apuntando a un proceso, que murió hace mucho tiempo.

La forma alternativa es correr

xwininfo -root -tree

y verifique las propiedades de los padres de la ventana en cuestión. Eso también puede darte algunas pistas sobre los orígenes de las ventanas.

¡Pero! Si bien es posible que no encuentre qué proceso ha creado esa ventana, todavía hay una manera de encontrar desde dónde se ha conectado ese proceso al servidor X. Y de esa manera es para los verdaderos piratas informáticos. 🙂

El ID de ventana 0x1600045 que conoce con los bits inferiores puestos a cero (es decir, 0x1600000) es una "base de clientes". Y todos los ID de recursos asignados para ese cliente están "basados" en él (0x1600001, 0x1600002, 0x1600003, etc.). X-server almacena información sobre sus clientes en la matriz clients[], y para cada cliente su “base” se almacena en la variable clients[i]->clientAsMask. Para encontrar el socket X, correspondiente a ese cliente, debe conectarse al servidor X con gdb , camine sobre la matriz de clientes [], encuentre el cliente con ese clientAsMask e imprima su descriptor de socket, almacenado en ((OsCommPtr)(clients[i]->osPrivate))->fd.

Puede haber muchos clientes X conectados, así que para no verificarlos todos manualmente, usemos una función 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

Cuando encuentre el enchufe, puede verificar quién está conectado a él y finalmente encontrar el proceso.

Relacionado:¿Cómo descargar una aplicación de la tienda de Windows 10 para descargarla?

ADVERTENCIA :NO adjunte gdb al servidor X desde DENTRO del servidor X. gdb suspende el proceso al que se adjunta, por lo que si se conecta desde dentro de X-session, congelará su servidor X y no podrá interactuar con gdb. Debe cambiar a la terminal de texto (Ctrl+Alt+F2 ) o conéctese a su máquina a través de ssh.

Ejemplo:

  1. Encuentre el PID de su servidor 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. La identificación de la ventana es 0x1600045, por lo que la base de clientes es 0x1600000. Conéctese al servidor X y busque el descriptor de socket del cliente para esa base de clientes. Necesitará información de depuración
    instalada para X-server (paquete -debuginfo para distribuciones rpm o paquete -dbg para 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. Ahora sabe que el cliente está conectado a un servidor socket 31. Use lsof para encontrar cuál es ese socket:

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

    (aquí "X" es el nombre del proceso, "1237" es su pid, "root" es el usuario desde el que se ejecuta, "31u" es un descriptor de socket)

    Allí puede ver que el cliente está conectado a través de TCP, luego puede ir a la máquina desde la que está conectado y verificar netstat -nap allí para encontrar el proceso. Pero lo más probable es que vea un socket de Unix allí, como se muestra arriba, lo que significa que es un cliente local.

  4. Para encontrar un par para ese socket Unix, puede usar la técnica de MvG (también necesitará información de depuración para su kernel instalado):

    $ sudo gdb -c /proc/kcore
    (gdb) print ((struct unix_sock*)0xffff810008339340)->peer
    $1 = (struct sock *) 0xffff810008339600
    (gdb) quit
    
  5. Ahora que conoce el socket del cliente, use lsof para encontrar el PID que lo contiene:

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

Eso es todo. El proceso que mantiene esa ventana es "Firefox" con ID de proceso 7725

Edición de 2017 :Hay más opciones ahora como se ve en ¿Quién tiene el otro extremo de este par de sockets de Unix?. Con Linux 3.3 o superior y con lsof 4.89 o superior, puede reemplazar los puntos 3 a 5 anteriores con:

lsof +E -a -p 1237 -d 31

para averiguar quién está en el otro extremo del socket en el fd 31 del proceso del servidor X con ID 1237.


Linux
  1. ¿Qué son los procesos zombis y cómo encontrar y eliminar procesos zombis?

  2. ¿Es posible averiguar qué programa o secuencia de comandos creó un archivo determinado?

  3. ¿Cómo verificar qué señales está escuchando un proceso?

  4. ¿Cómo averiguo qué proceso tiene un bloqueo en un archivo en Linux?

  5. Qué proceso está usando todo mi disco IO

¿Qué indica esta estadística de proceso?

¿Qué terminal es esta?

SIGTERM vs SIGKILL:¿Cuál es la diferencia?

No hay variable X11 DISPLAY - ¿qué significa?

¿Qué es un proceso detenido en Linux?

¿Qué son las señales pendientes?