Proses apa yang membuat jendela X11 ini?


75

Diberi ID jendela X11, apakah ada cara untuk menemukan ID proses yang membuatnya?

Tentu saja ini tidak selalu mungkin, misalnya jika jendela datang melalui koneksi TCP. Untuk itu saya ingin IP dan port yang terkait dengan ujung jarak jauh.

Pertanyaan itu diajukan sebelumnya pada Stack Overflow , dan metode yang diusulkan adalah menggunakan _NET_WM_PIDproperti. Tapi itu diatur oleh aplikasi. Apakah ada cara untuk melakukannya jika aplikasi tidak bermain bagus?


Jawaban:


60

Kecuali X-server Anda mendukung XResQueryClientIdsdari ekstensi X-Resource v1.2, saya tidak tahu cara mudah untuk meminta ID proses dengan andal . Namun ada cara lain.

Jika Anda hanya memiliki jendela di depan Anda dan belum tahu ID-nya - mudah untuk menemukannya. Cukup buka terminal di sebelah jendela yang dimaksud, jalankan di xwininfosana dan klik pada jendela itu. xwininfoakan menunjukkan kepada Anda window-id.

Jadi mari kita asumsikan Anda tahu id-jendela, misalnya 0x1600045, dan ingin mencari, apa proses memilikinya.

Cara termudah untuk memeriksa milik siapa jendela itu adalah dengan menjalankan XKillClient untuk itu yaitu:

xkill -id 0x1600045

dan lihat proses mana yang baru saja mati. Tetapi hanya jika Anda tidak keberatan membunuhnya tentu saja!

Cara lain yang mudah tetapi tidak dapat diandalkan adalah dengan memeriksa _NET_WM_PIDdan WM_CLIENT_MACHINEpropertinya:

xprop -id 0x1600045

Itulah yang disukai xlsclientsdan xrestopdilakukan alat .

Sayangnya informasi ini mungkin salah bukan hanya karena prosesnya jahat dan mengubah itu, tetapi juga karena itu buggy. Sebagai contoh setelah beberapa firefox crash / restart saya telah melihat windows yatim (dari plugin flash, saya kira) dengan _NET_WM_PIDmenunjuk ke suatu proses, yang sudah lama meninggal.

Cara alternatif adalah dengan menjalankan

xwininfo -root -tree

dan periksa properti orang tua dari jendela yang bersangkutan. Itu juga dapat memberi Anda beberapa petunjuk tentang asal jendela.

Tapi! Meskipun Anda mungkin tidak menemukan proses apa yang telah membuat jendela itu, masih ada cara untuk menemukan dari mana proses itu terhubung ke X-server. Dan itu untuk peretas sejati. :)

Window-id 0x1600045 yang Anda tahu dengan bit yang lebih rendah memusatkan perhatian (yaitu 0x1600000) adalah "basis klien". Dan semua ID sumber daya, dialokasikan untuk klien itu "berdasarkan" di atasnya (0x1600001, 0x1600002, 0x1600003, dll). X-server menyimpan informasi tentang kliennya dalam larik klien [], dan untuk setiap klien "basis" -nya disimpan di klien [i] -> variabel clientAsMask. Untuk menemukan X-socket, yang sesuai dengan klien itu, Anda harus melampirkan ke X-server dengan gdb, walk over clients [] array, menemukan klien dengan itu clientAsMaskdan mencetak deskriptor socketnya, disimpan dalam ((OsCommPtr) (klien [i] - > osPrivate)) -> fd.

Mungkin ada banyak klien-X yang terhubung, jadi agar tidak memeriksa semuanya secara manual, mari gunakan fungsi 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

Ketika Anda menemukan soket, Anda dapat memeriksa, siapa yang terhubung, dan akhirnya menemukan prosesnya.

PERINGATAN : JANGAN pasang gdb ke server-X dari DALAM server-X. gdb menunda proses yang dilampirkannya, jadi jika Anda melampirkannya dari dalam sesi-X, Anda akan membekukan X-server Anda dan tidak akan dapat berinteraksi dengan gdb. Anda harus beralih ke terminal teks ( Ctrl+Alt+F2) atau terhubung ke mesin Anda melalui ssh.

Contoh:

  1. Temukan PID X-server Anda:

    $ 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. Window id adalah 0x1600045, jadi basis klien adalah 0x1600000. Lampirkan ke server-X dan temukan deskriptor soket klien untuk basis klien itu. Anda perlu menginstal informasi debug untuk X-server (paket -debuginfo untuk distribusi-rpm atau paket -dbg untuk deb's).

    $ 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. Sekarang Anda tahu bahwa klien terhubung ke soket server 31. Gunakan lsofuntuk menemukan apa soket itu:

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

    (di sini "X" adalah nama proses, "1237" adalah pidnya, "root" adalah tempat pengguna menjalankannya, "31u" adalah deskriptor soket)

    Di sana Anda mungkin melihat bahwa klien terhubung melalui TCP, maka Anda dapat pergi ke mesin yang terhubung dari dan memeriksa di netstat -napsana untuk menemukan prosesnya. Tetapi kemungkinan besar Anda akan melihat soket unix di sana, seperti yang ditunjukkan di atas, yang berarti itu adalah klien lokal.

  4. Untuk menemukan pasangan untuk soket unix itu, Anda dapat menggunakan teknik MvG (Anda juga akan memerlukan informasi debug untuk kernel Anda terpasang):

    $ sudo gdb -c /proc/kcore
    (gdb) print ((struct unix_sock*)0xffff810008339340)->peer
    $1 = (struct sock *) 0xffff810008339600
    (gdb) quit
    
  5. Sekarang Anda tahu soket klien, gunakan lsofuntuk menemukan PID memegangnya:

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

Itu dia. Proses menjaga jendela itu adalah "firefox" dengan proses-id 7725


Sunting 2017 : Ada lebih banyak pilihan sekarang seperti yang terlihat di Siapa yang memiliki ujung lain dari soket unix ini? . Dengan Linux 3.3 atau lebih tinggi dan dengan lsof4,89 atau lebih, Anda dapat mengganti poin 3 hingga 5 di atas dengan:

lsof +E -a -p 1237 -d 31

untuk mencari tahu siapa yang ada di ujung soket pada fd 31 dari proses X-server dengan ID 1237.


6
Selamat datang di Unix dan Linux Stack Exchange! Jawaban Anda untuk pertanyaan ini sangat bagus. Saya harap Anda kembali untuk menjawab lebih banyak pertanyaan.

36

xdotool tidak bekerja untuk saya. Ini berhasil:

Lari

xprop _NET_WM_PID

dan klik pada jendela.

Ini didasarkan pada jawaban di http://www.linuxquestions.org/questions/linux-software-2/advanced-question-finding-pid-of-an-x-window-328983/


Bekerja untuk saya ketika menghubungkan iPhone saya memunculkan jendela prompt non-responsif.
modulitos

1
Berguna untuk membuktikan bahwa kadang-kadang tergantung sepenuhnya. kill $(xprop _NET_WM_PID|cut -d " " -f 3)
Gabriel Devillers

Inilah yang saya cari, xkill flow
Rombus

13

Jika Anda sudah menginstal xdotool , maka

xdotool selectwindow getwindowpid

diikuti dengan mengklik pada jendela yang dimaksud akan mengembalikan PID.

(Ada cara lain untuk memilih jendela yang dipermasalahkan, misalnya, jika Anda memiliki ID jendelanya, cukup lakukan xdotool getwindowpid <number>. Anda juga dapat memilih berdasarkan nama atau kelas, dll.)

Saya pikir ini membutuhkan beberapa permainan bagus atas nama WM. Saya belum banyak bereksperimen, atau perlu.


2
xdo_getwinprop(xdo, window, atom_NET_WM_PID, &nitems, &type, &size)⇒ itu hanya pembungkus shell untuk dibaca _NET_WM_PID(berguna, tapi bukan yang saya minta).
Gilles

11

Tidak _NET_WM_PIDdiatur oleh manajer jendela (hanya sebagai klien X11 lainnya, bagaimana ia tahu?).

Sebaliknya, klien X11 yang sesuai (aplikasi) diharapkan untuk mengatur _NET_WM_PIDdan WM_CLIENT_MACHINEdi windows mereka sendiri. Dengan asumsi aplikasi berperilaku baik, ini akan menjadi kenyataan apakah manajer jendela sedang berjalan atau tidak.

Jika WM_CLIENT_MACHINEadalah nama host Anda sendiri, maka PID harus bermakna.
Kalau tidak, "Saya ingin IP dan port yang terkait dengan ujung jarak jauh" - Saya tidak yakin apa artinya itu. Misalnya, jika Anda memiliki sesi ssh terbuka dengan penerusan X diaktifkan, jendela yang dibuka oleh aplikasi yang diteruskan akan ditandai dengan PID jarak jauh dan nama host, tetapi Anda tidak perlu memiliki cara untuk menghubungkan kembali ke host jarak jauh itu.


2
_NET_WM_PIDdiatur oleh aplikasi: benar, itu lebih masuk akal! Tapi itu bukan protokol X11, itu adalah spesifikasi FreeDesktop yang relatif baru .
Gilles

Dalam kasus ssh, sejauh menyangkut server X, ini adalah koneksi lokal dari proses sshd. Meskipun _NET_WM_PIDtampaknya diatur ke PID jarak jauh dan WM_CLIENT_MACHINEke koneksi jarak jauh (diuji dengan xterm).
Gilles

4

Saya dapat menggunakan xdotoolUbuntu 11.04 beta, tetapi selectwindowbukan perintah yang valid, saya harus meretas skrip dengan:

$ while true; do sleep 1; xdotool getactivewindow; done

kemudian lihat ID jendela lewat sementara saya memilih jendela yang saya inginkan, lalu mendekodekan PID yang bertanggung jawab dengan:

$ xdotool getwindowpid <the-window-id>
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.