Dado um ID da janela X11, existe uma maneira de encontrar o ID do processo que o criou?
Obviamente, isso nem sempre é possível, por exemplo, se a janela vier através de uma conexão TCP. Nesse caso, eu gostaria do IP e da porta associados ao terminal remoto.
A pergunta foi feita anteriormente no Stack Overflow , e um método proposto era usar a _NET_WM_PID
propriedade Mas isso é definido pelo aplicativo. Existe uma maneira de fazer isso se o aplicativo não funcionar bem?
Respostas:
A menos que o seu servidor X suporte
XResQueryClientIds
da extensão X-Resource v1.2, não conheço uma maneira fácil de solicitar com segurança o ID do processo. Existem outras maneiras, no entanto.Se você apenas tem uma janela à sua frente e ainda não sabe o seu ID - é fácil descobrir. Basta abrir um terminal ao lado da janela em questão, correr para
xwininfo
lá e clicar nessa janela.xwininfo
mostrará o ID da janela.Então, vamos supor que você conhece um ID de janela, por exemplo, 0x1600045 e deseja descobrir qual é o processo que o possui.
A maneira mais fácil de verificar a quem essa janela pertence é executar o XKillClient, ou seja:
e ver qual processo acabou de morrer. Mas só se você não se importa de matá-lo, é claro!
Outra maneira fácil, porém não confiável, é verificar suas propriedades
_NET_WM_PID
eWM_CLIENT_MACHINE
:É isso que as ferramentas gostam
xlsclients
exrestop
fazem.Infelizmente, essas informações podem estar incorretas não apenas porque o processo foi mal e as alterou, mas também porque eram de buggy. Por exemplo, após algum travamento / reinicialização do firefox, vi janelas órfãs (do plugin flash, eu acho)
_NET_WM_PID
apontando para um processo que morreu há muito tempo.Maneira alternativa é correr
e verifique as propriedades dos pais da janela em questão. Isso também pode lhe dar algumas dicas sobre as origens da janela.
Mas! Embora você não encontre qual processo criou essa janela, ainda há uma maneira de descobrir de onde esse processo se conectou ao X-server. E é assim para hackers reais. :)
O ID da janela 0x1600045 que você conhece com bits inferiores zerados (ou seja, 0x1600000) é uma "base de clientes". E todas as IDs de recursos alocadas para esse cliente são "baseadas" nele (0x1600001, 0x1600002, 0x1600003 etc.). O servidor X armazena informações sobre seus clientes na matriz clients [] e para cada cliente sua "base" é armazenada na variável clients [i] -> clientAsMask. Para encontrar o soquete X, correspondente a esse cliente, você precisa se conectar ao servidor X com
gdb
, percorrer a matriz clients [], encontrar o cliente com issoclientAsMask
e imprimir seu descritor de soquete, armazenado em ((OsCommPtr) (clients [i] - > osPrivate)) -> fd.Pode haver muitos clientes X conectados, portanto, para não verificar todos eles manualmente, vamos usar uma função gdb:
Quando você encontra o soquete, pode verificar quem está conectado a ele e finalmente encontrar o processo.
AVISO : NÃO anexe gdb ao servidor X DENTRO do servidor X. O gdb suspende o processo ao qual ele se conecta, portanto, se você se conectar a ele de dentro da X-session, congelará seu servidor X e não poderá interagir com o gdb. Você deve mudar para o terminal de texto (
Ctrl+Alt+F2
) ou conectar-se à sua máquina pelo ssh.Exemplo:
Encontre o PID do seu servidor X:
O ID da janela é 0x1600045, portanto, a base de clientes é 0x1600000. Anexe ao servidor X e encontre o descritor de soquete do cliente para essa base de clientes. Você precisará das informações de depuração instaladas no X-server (pacote -debuginfo para rpm-distributions ou pacote -dbg para deb's).
Agora você sabe que o cliente está conectado a um soquete 31 do servidor. Use
lsof
para encontrar o que é esse soquete:(aqui "X" é o nome do processo, "1237" é o seu pid, "root" é o usuário do qual ele está sendo executado, "31u" é um descritor de soquete)
Lá, você pode ver que o cliente está conectado por TCP, depois pode ir à máquina da qual está conectado e verificar
netstat -nap
lá para encontrar o processo. Mas provavelmente você verá um soquete unix lá, como mostrado acima, o que significa que é um cliente local.Para encontrar um par para esse soquete unix, você pode usar a técnica do MvG (você também precisará de informações de depuração para o kernel instalado):
Agora que você conhece o soquete do cliente, use o
lsof
PID para encontrá-lo:É isso aí. O processo que mantém essa janela é "firefox" com o ID do processo 7725
Edição de 2017 : Existem mais opções agora, como visto em Quem tem a outra extremidade deste socket unix? . Com o Linux 3.3 ou superior e com
lsof
4.89 ou superior, você pode substituir os pontos 3 a 5 acima por:para descobrir quem está do outro lado do soquete no fd 31 do processo do X-server com o ID 1237.
fonte
O xdotool não funcionou para mim. Isso fez:
Corre
xprop _NET_WM_PID
e clique na janela.
Isso é baseado na resposta em http://www.linuxquestions.org/questions/linux-software-2/advanced-question-finding-pid-of-an-x-window-328983/
fonte
kill $(xprop _NET_WM_PID|cut -d " " -f 3)
Se você tiver o xdotool instalado, então
xdotool selectwindow getwindowpid
seguido de clicar na janela em questão retornará o PID.
(Existem outras maneiras de selecionar a janela em questão, por exemplo, se você tiver o ID da janela, basta fazê-lo
xdotool getwindowpid <number>
. Você também pode selecionar por nome ou classe, etc.)Eu acho que isso requer um bom desempenho em nome do WM. Não experimentei muito ou precisei.
fonte
xdo_getwinprop(xdo, window, atom_NET_WM_PID, &nitems, &type, &size)
⇒ é apenas um invólucro de shell para ler_NET_WM_PID
(útil, mas não o que eu pedi).O
_NET_WM_PID
não é definido pelo gerenciador de janelas (como apenas outro cliente X11, como ele saberia?).Em vez disso, espera-se que os clientes X11 compatíveis (aplicativos) sejam configurados
_NET_WM_PID
eWM_CLIENT_MACHINE
em suas próprias janelas. Supondo que um aplicativo com bom comportamento, isso será verdade se um gerenciador de janelas está sendo executado ou não.Se
WM_CLIENT_MACHINE
é o seu próprio nome de host, o PID deve ser significativo.Caso contrário, "eu gostaria do IP e da porta associados à extremidade remota" - não tenho certeza do que isso significa. Por exemplo, se você tiver uma sessão ssh aberta com o encaminhamento X ativado, as janelas abertas pelos aplicativos encaminhados serão marcadas com PID remoto e nome do host, mas você não necessariamente tem como conectar-se novamente a esse host remoto.
fonte
_NET_WM_PID
é definido pelo aplicativo: certo, isso faz mais sentido! Mas não é o protocolo X11, é a especificação relativamente recente do FreeDesktop ._NET_WM_PID
pareça estar definido para o PID remoto eWM_CLIENT_MACHINE
a conexão remota (testado com xterm).Consegui usar o
xdotool
Ubuntu 11.04 beta, masselectwindow
não era um comando válido, tive que hackear um script com:observe a identificação da janela passar enquanto selecionei a janela que queria e decodifiquei o PID responsável com:
fonte