Dada una ID de ventana X11, ¿hay alguna manera 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 sobre Stack Overflow , y un método propuesto era usar la _NET_WM_PID
propiedad. Pero eso lo establece la aplicación. ¿Hay alguna manera de hacerlo si la aplicación no funciona bien?
Respuestas:
A menos que su servidor X sea compatible
XResQueryClientIds
con la extensión X-Resource v1.2, no conozco una manera fácil de solicitar de manera confiable la identificación del proceso. Sin embargo, hay otras formas.Si solo tiene una ventana frente a usted y aún no conoce su ID, es fácil descubrirlo. Simplemente abra una terminal al lado de la ventana en cuestión, ejecute
xwininfo
allí y haga clic en esa ventana.xwininfo
le mostrará el id de la ventana.Así que supongamos que conoce un id de ventana, por ejemplo, 0x1600045, y desea encontrar 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 para ello, es decir:
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 sus propiedades
_NET_WM_PID
yWM_CLIENT_MACHINE
propiedades:Eso es lo que les gusta
xlsclients
yxrestop
hacen las herramientas .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 (desde el complemento flash, supongo) que
_NET_WM_PID
apuntan a un proceso que murió hace mucho tiempo.La forma alternativa es correr
y verifique las propiedades de los padres de la ventana en cuestión. Eso también puede darle 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 hackers reales. :)
El identificador de ventana 0x1600045 que conoce con bits más bajos 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 de clientes [], y para cada cliente su "base" se almacena en la variable clientes [i] -> clientAsMask. Para encontrar el socket X, que corresponde a ese cliente, debe conectarse al servidor X con
gdb
, recorrer la matriz de clientes [], encontrar el cliente con esoclientAsMask
e imprimir su descriptor de socket, almacenado en ((OsCommPtr) (clients [i] - > osPrivate)) -> fd.Puede haber muchos clientes X conectados, por lo que para no verificarlos todos manualmente, usemos una función gdb:
Cuando encuentre el zócalo, puede verificar quién está conectado a él y finalmente encontrar el proceso.
ADVERTENCIA : NO conecte gdb al servidor X dentro del servidor X. gdb suspende el proceso al que se adjunta, por lo que si lo adjunta desde dentro de X-session, congelará su servidor X y no podrá interactuar con gdb. Debe cambiar a terminal de texto (
Ctrl+Alt+F2
) o conectarse a su máquina a través de ssh.Ejemplo:
Encuentre el PID de su servidor X:
El ID de la ventana es 0x1600045, por lo que la base de clientes es 0x1600000. Adjunte al servidor X y busque el descriptor de socket del cliente para esa base de clientes. Necesitará la información de depuración instalada para X-server (paquete -debuginfo para distribuciones rpm o paquete -dbg para deb).
Ahora sabe que el cliente está conectado a un socket de servidor 31. Use
lsof
para encontrar qué es ese socket:(aquí "X" es el nombre del proceso, "1237" es su pid, "root" es el usuario desde el que se está ejecutando, "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 Unix allí, como se muestra arriba, lo que significa que es un cliente local.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 núcleo instalado):
Ahora que conoce el socket del cliente, use
lsof
para encontrar el PID que lo contiene:Eso es. El proceso que mantiene esa ventana es "firefox" con process-id 7725
Edición de 2017 : ahora hay más opciones, como se ve en ¿Quién tiene el otro extremo de este par de socket de Unix? . Con Linux 3.3 o superior y con
lsof
4.89 o superior, puede reemplazar los puntos 3 a 5 anteriores con:para averiguar quién está en el otro extremo del socket en fd 31 del proceso del servidor X con ID 1237.
fuente
xdotool no funcionó para mí. Esto hizo:
correr
xprop _NET_WM_PID
y haz clic en la ventana.
Esto se basa en la respuesta en http://www.linuxquestions.org/questions/linux-software-2/advanced-question-finding-pid-of-an-x-window-328983/
fuente
kill $(xprop _NET_WM_PID|cut -d " " -f 3)
Si tiene instalado xdotool , entonces
xdotool selectwindow getwindowpid
seguido haciendo clic en la ventana en cuestión devolverá el PID.
(Hay otras formas de seleccionar la ventana en cuestión, por ejemplo, si tiene su ID de ventana, simplemente puede hacerlo
xdotool getwindowpid <number>
. También puede seleccionar por nombre o clase, etc.)Creo que esto requiere algo de juego agradable en nombre de WM. No he experimentado mucho, o lo necesitaba.
fuente
xdo_getwinprop(xdo, window, atom_NET_WM_PID, &nitems, &type, &size)
⇒ es solo un envoltorio para leer_NET_WM_PID
(útil, pero no es lo que pedí).El
_NET_WM_PID
administrador de ventanas no establece el (como otro cliente X11, ¿cómo lo sabría?).En lugar de ello, se espera que los clientes X11 compatibles (aplicaciones) para establecer
_NET_WM_PID
yWM_CLIENT_MACHINE
en sus propias ventanas. Asumiendo una aplicación que se comporte bien, esto será cierto tanto si se está ejecutando un administrador de ventanas como si no.Si
WM_CLIENT_MACHINE
es su propio nombre de host, entonces el PID debe ser significativo.De lo contrario, "Me gustaría la IP y el puerto asociados con el extremo remoto": no estoy seguro de lo que eso significa. Por ejemplo, si tiene una sesión ssh abierta con el reenvío X habilitado, las ventanas abiertas por las aplicaciones reenviadas se marcarán con PID remoto y nombre de host, pero no necesariamente tiene ninguna forma de conectarse de nuevo a ese host remoto.
fuente
_NET_WM_PID
lo establece la aplicación: correcto, ¡eso tiene más sentido! Pero no es el protocolo X11, es la relativamente reciente especificación de FreeDesktop ._NET_WM_PID
parece estar configurado para el PID remoto yWM_CLIENT_MACHINE
para la conexión remota (probado con xterm).Pude usar la
xdotool
versión beta de Ubuntu 11.04, peroselectwindow
no era un comando válido, tuve que hackear un script con:luego mire la identificación de la ventana mientras seleccioné la ventana que quería, luego decodifiqué el PID responsable con:
fuente