당신의 X 서버가 지원하지 않는 한 XResQueryClientIds
에서 X-자원 1.2 확장 나는 더 모르는 쉽게 하는 방법 안정적으로 프로세스 ID를 요청합니다. 그러나 다른 방법이 있습니다.
창문이 있고 아직 ID를 모르는 경우 쉽게 찾을 수 있습니다. 문제의 창 옆에있는 터미널을 열고 실행 한 다음 해당 창을 xwininfo
클릭하십시오. xwininfo
window-id를 보여줍니다.
따라서 0x1600045와 같은 창 ID를 알고 있고 그것을 소유하는 프로세스가 무엇인지 찾고 싶다고 가정 해 봅시다.
해당 윈도우가 누구인지 확인하는 가장 쉬운 방법은 XKillClient를 실행하는 것입니다.
xkill -id 0x1600045
어떤 프로세스가 막 죽었는지 확인하십시오. 그러나 물론 그것을 죽이는 것이 마음에 들지 않는 경우에만!
쉽고 신뢰할 수없는 또 다른 방법은 해당 속성 _NET_WM_PID
과 WM_CLIENT_MACHINE
속성 을 확인하는 것입니다 .
xprop -id 0x1600045
그것이 도구가 좋아 xlsclients
하고하는 xrestop
일입니다.
불행히도이 정보는 프로세스가 악하고 변경 되었기 때문에뿐만 아니라 버그이기 때문에 부정확 할 수 있습니다. 예를 들어 파이어 폭스 충돌 / 다시 시작 후 _NET_WM_PID
오래 전에 죽은 프로세스 를 가리키는 고아 창 (플래시 플러그인에서)을 보았습니다 .
다른 방법은 달리는 것입니다
xwininfo -root -tree
해당 창의 부모 속성을 확인하십시오. 또한 창 원점에 대한 힌트를 줄 수도 있습니다.
그러나! 해당 프로세스가 해당 창을 생성 한 프로세스를 찾을 수 없지만 해당 프로세스가 X 서버에 연결된 위치를 찾는 방법은 여전히 있습니다. 그리고 그 방법은 실제 해커를위한 것입니다. :)
하위 비트가 0 인 0x1600000과 같은 창 ID 0x1600045는 "클라이언트 기반"입니다. 그리고 해당 클라이언트에 할당 된 모든 자원 ID는 "기반"(0x1600001, 0x1600002, 0x1600003 등)입니다. X 서버는 클라이언트에 대한 정보를 clients [] 배열에 저장하고 각 클라이언트의 "기본"은 clients [i]-> clientAsMask 변수에 저장됩니다. 해당 클라이언트에 해당하는 X- 소켓을 찾으려면을 사용하여 X-server에 연결하고 gdb
clients [] 배열을 살펴보고 해당 클라이언트를 찾은 다음 clientAsMask
소켓 설명자를 인쇄하여 ((OsCommPtr) (clients [i]- > osPrivate))-> fd.
많은 X- 클라이언트가 연결되어있을 수 있으므로 모든 X- 클라이언트를 수동으로 확인하지 않으려면 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
소켓을 찾으면 누가 연결했는지 확인할 수 있으며 마지막으로 프로세스를 찾을 수 있습니다.
경고 : X 서버 내부에서 gdb를 X 서버에 연결하지 마십시오. gdb는 연결된 프로세스를 일시 중단하므로 X- 세션 내부에서 연결하면 X 서버가 정지되고 gdb와 상호 작용할 수 없습니다. 텍스트 터미널 ( Ctrl+Alt+F2
)로 전환 하거나 ssh를 통해 시스템에 연결해야합니다.
예:
X 서버의 PID를 찾으십시오.
$ ps ax | grep X
1237 tty1 Ssl+ 11:36 /usr/bin/X :0 vt1 -nr -nolisten tcp -auth /var/run/kdm/A:0-h6syCa
창 ID는 0x1600045이므로 클라이언트 기준은 0x1600000입니다. X 서버에 접속하여 해당 클라이언트 기반에 대한 클라이언트 소켓 설명자를 찾으십시오. X 서버에 설치된 디버그 정보가 필요합니다 (rpm 배포 용 -debuginfo 패키지 또는 deb 용 -dbg 패키지).
$ 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
이제 클라이언트가 서버 소켓 31에 연결되어 있음을 알았습니다. lsof
해당 소켓이 무엇인지 찾는 데 사용하십시오 .
$ sudo lsof -n | grep 1237 | grep 31
X 1237 root 31u unix 0xffff810008339340 8512422 socket
(여기서 "X"는 프로세스 이름, "1237"은 pid, "root"는 실행중인 사용자, "31u"는 소켓 설명자)
거기에서 클라이언트가 TCP를 통해 연결되어 netstat -nap
있음을 알 수 있으며 연결된 컴퓨터로 이동 하여 프로세스를 찾을 수 있습니다. 그러나 위의 그림과 같이 유닉스 소켓이 보일 것입니다. 이는 로컬 클라이언트임을 의미합니다.
해당 유닉스 소켓에 대한 쌍을 찾으려면 MvG 기술을 사용할 수 있습니다
(커널이 설치된 디버그 정보도 필요함).
$ sudo gdb -c /proc/kcore
(gdb) print ((struct unix_sock*)0xffff810008339340)->peer
$1 = (struct sock *) 0xffff810008339600
(gdb) quit
이제 클라이언트 소켓을 알고 있으므로 lsof
이를 보유한 PID를 찾는 데 사용 하십시오.
$ sudo lsof -n | grep 0xffff810008339600
firefox 7725 username 146u unix 0xffff810008339600 8512421 socket
그게 다야. 해당 창을 유지하는 프로세스는 프로세스 ID 7725를 가진 "firefox"입니다.
2017 편집 : 이 유닉스 소켓 페어의 다른 쪽 끝은 누가 있습니까? 에서 더 많은 옵션 이 있습니다. . Linux 3.3 이상 및 lsof
4.89 이상에서는 3에서 5까지의 포인트를 다음으로 바꿀 수 있습니다.
lsof +E -a -p 1237 -d 31
ID가 1237 인 X-server 프로세스의 fd 31에서 소켓의 다른 쪽 끝에있는 사람을 찾으십시오.