Peringatan: Menjalankan perintah ini di sebagian besar shell akan menghasilkan sistem yang rusak yang akan membutuhkan shutdown paksa untuk memperbaikinya
Saya mengerti fungsi rekursif :(){ :|: & };:
dan apa fungsinya. Tapi saya tidak tahu di mana sistem panggilan fork. Saya tidak yakin, tapi saya curiga di dalam pipa |
.
linux
shell
system-calls
mavillan
sumber
sumber
Jawaban:
Sebagai hasil dari pipa dalam
x | y
, subkulit dibuat untuk berisi pipa sebagai bagian dari grup proses latar depan. Ini terus membuat subkulit (viafork()
) tanpa batas, sehingga menciptakan bom fork.Garpu tidak benar-benar muncul sampai kode dijalankan, yang merupakan doa terakhir
:
dalam kode Anda.Untuk membongkar cara kerja bom fork:
:()
- mendefinisikan fungsi baru yang disebut:
{ :|: & }
- definisi fungsi yang secara rekursif menyalurkan fungsi panggilan ke instance lain dari fungsi panggilan di latar belakang:
- Memanggil fungsi bom garpuIni cenderung tidak terlalu intensif memori, tetapi akan menyedot PID dan mengkonsumsi siklus CPU.
sumber
x | y
, mengapa ada sub-shell yang dibuat? Untuk pemahaman saya, ketika bash melihatpipe
, itu mengeksekusipipe()
system call, yang mengembalikan duafds
. Sekarang, command_left adalahexec
ed dan output diumpankan ke command_right sebagai input. Sekarang, command_right sudah dieditexec
. Jadi, mengapaBASHPID
berbeda setiap kali?x
dany
2 perintah terpisah berjalan dalam 2 proses terpisah, sehingga Anda memiliki 2 subkulit terpisah. Jikax
berjalan dalam proses yang sama dengan shell, itu berartix
harus built-in.Bit terakhir dari kode,
;:
menjalankan fungsinya:(){ ... }
. Di sinilah garpu terjadi.Titik koma mengakhiri perintah pertama, dan kita mulai yang lain, yaitu memanggil fungsi
:
. Definisi fungsi ini mencakup panggilan untuk dirinya sendiri (:
) dan output dari panggilan ini disalurkan ke versi latar belakang:
. Ini menopang proses tanpa batas.Setiap kali Anda memanggil fungsi
:()
Anda memanggil fungsi Cfork()
. Akhirnya ini akan menghabiskan semua ID proses (PID) pada sistem.Contoh
Anda dapat bertukar
|:&
dengan sesuatu yang lain sehingga Anda dapat mengetahui apa yang sedang terjadi.Siapkan pengamat
Dalam satu jendela terminal lakukan ini:
Siapkan bom garpu "fuse delay"
Di jendela lain kita akan menjalankan versi bom fork yang sedikit dimodifikasi. Versi ini akan berusaha mencekik dirinya sendiri sehingga kita dapat mempelajari apa yang dilakukannya. Versi kami akan tidur selama 61 detik sebelum memanggil fungsi
:()
.Kami juga akan melatarbelakangi panggilan awal, setelah dipanggil. Ctrl+ z, lalu ketikkan
bg
.Sekarang jika kita menjalankan
jobs
perintah di jendela awal kita akan melihat ini:Setelah beberapa menit:
Periksa dengan pengamat
Sementara itu di jendela lain tempat kami menjalankan
watch
:Hierarki proses
Dan a
ps -auxf
menunjukkan hierarki proses ini:Bersihkan waktu
A
killall bash
akan menghentikan sesuatu sebelum mereka lepas kendali. Melakukan pembersihan dengan cara ini mungkin sedikit berat, cara yang lebih lembut yang tidak berpotensi merobohkan setiapbash
shell, adalah dengan melakukan hal berikut:Tentukan terminal pseudo mana yang akan dijalankan oleh bom fork
Bunuh terminal semu
Jadi apa yang terjadi?
Yah setiap doa
bash
dansleep
adalah panggilan ke fungsi Cfork()
daribash
shell dari mana perintah itu dijalankan.sumber
bash
mungkin berjalan di terminal terpisah. Lebih baik menggunakanpkill -t pts/2
.