Saya sering menemukan situasi ketika mengembangkan, di mana saya menjalankan file biner, katakan a.out
di latar belakang karena melakukan pekerjaan yang panjang. Sementara melakukan itu, saya membuat perubahan pada kode C yang diproduksi a.out
dan dikompilasi a.out
lagi. Sejauh ini, saya tidak punya masalah dengan ini. Proses yang berjalan a.out
berlanjut seperti biasa, tidak pernah macet, dan selalu menjalankan kode lama dari mana awalnya dimulai.
Namun, katakanlah a.out
itu file yang sangat besar, mungkin sebanding dengan ukuran RAM. Apa yang akan terjadi dalam kasus ini? Dan katakan itu tertaut ke file objek bersama libblas.so
,, bagaimana jika saya memodifikasi libblas.so
selama runtime? Apa yang akan terjadi?
Pertanyaan utama saya adalah - apakah OS menjamin bahwa ketika saya menjalankan a.out
, maka kode asli akan selalu berjalan normal, sesuai dengan biner asli , terlepas dari ukuran biner atau file yang ditautkan .so
, bahkan ketika file .o
dan .so
file tersebut dimodifikasi selama runtime?
Saya tahu ada pertanyaan-pertanyaan ini yang membahas masalah serupa: /programming/8506865/when-a-binary-file-runs-does-it-copy-its-entire-binary-data-into-memory -at-once Apa yang terjadi jika Anda mengedit skrip selama eksekusi? Bagaimana mungkin melakukan pembaruan langsung saat program sedang berjalan?
Yang telah membantu saya memahami sedikit lebih banyak tentang ini tetapi saya tidak berpikir bahwa mereka menanyakan apa yang saya inginkan, yang merupakan aturan umum untuk konsekuensi dari memodifikasi biner selama eksekusi
if they are read-only copies of something already on disc (like an executable, or a shared object file), they just get de-allocated and are reloaded from their source
, jadi saya mendapat kesan bahwa jika biner Anda besar, maka jika bagian dari biner Anda kehabisan RAM, tetapi kemudian diperlukan lagi itu adalah "reloaded from source" - jadi setiap perubahan dalam yang.(s)o
file akan tercermin selama eksekusi. Tapi tentu saja saya mungkin salah paham - itulah sebabnya saya mengajukan pertanyaan yang lebih spesifik iniNo, it only loads the necessary pages into memory. This is demand paging.
Jadi saya sebenarnya mendapat kesan bahwa apa yang saya minta tidak dapat dijamin.Jawaban:
Sementara pertanyaan Stack Overflow tampaknya cukup pada awalnya, saya mengerti, dari komentar Anda, mengapa Anda mungkin masih ragu tentang ini. Bagi saya, ini persis seperti situasi kritis yang terlibat ketika dua subsistem UNIX (proses dan file) berkomunikasi.
Seperti yang Anda ketahui, sistem UNIX biasanya dibagi menjadi dua subsistem: subsistem file, dan subsistem proses. Sekarang, kecuali diinstruksikan sebaliknya melalui panggilan sistem, kernel seharusnya tidak memiliki dua subsistem ini berinteraksi satu sama lain. Namun ada satu pengecualian: memuat file yang dapat dieksekusi ke dalam wilayah teks proses . Tentu saja, orang mungkin berpendapat bahwa operasi ini juga dipicu oleh pemanggilan sistem (
execve
), tetapi ini biasanya dikenal sebagai satu - satunya kasus di mana subsistem proses membuat permintaan implisit ke subsistem file.Karena subsistem proses secara alami tidak memiliki cara untuk menangani file (jika tidak maka tidak ada gunanya membagi semuanya menjadi dua), ia harus menggunakan apa pun yang disediakan oleh subsistem file untuk mengakses file. Ini juga berarti bahwa subsistem proses dikirimkan ke ukuran apa pun yang diambil subsistem file terkait edisi file / penghapusan. Pada titik ini, saya akan merekomendasikan membaca jawaban Gilles untuk pertanyaan U&L ini . Sisa jawaban saya didasarkan pada yang lebih umum dari Gilles ini.
Hal pertama yang harus diperhatikan adalah bahwa secara internal, file hanya dapat diakses melalui inode . Jika kernel diberikan path, langkah pertama adalah menerjemahkannya menjadi inode yang akan digunakan untuk semua operasi lainnya. Ketika suatu proses memuat sebuah executable ke dalam memori, ia melakukannya melalui inode-nya, yang telah disediakan oleh subsistem file setelah terjemahan suatu path. Inode dapat dikaitkan dengan beberapa jalur (tautan), dan program hanya dapat menghapus tautan. Untuk menghapus file dan inode-nya, userland harus menghapus semua tautan yang ada ke inode itu, dan memastikan bahwa itu benar-benar tidak digunakan. Ketika kondisi ini terpenuhi, kernel akan secara otomatis menghapus file dari disk.
Jika Anda melihat bagian pengganti yang dapat dieksekusi dari jawaban Gilles, Anda akan melihat bahwa tergantung pada bagaimana Anda mengedit / menghapus file, kernel akan bereaksi / beradaptasi secara berbeda, selalu melalui mekanisme yang diterapkan dalam subsistem file.
ETXTBSY
). Tidak ada konsekuensi apa pun.mv
operasi adalah satu atom. Ini mungkin akan memerlukan penggunaanrename
panggilan sistem, dan karena proses tidak dapat diinterupsi saat dalam mode kernel, tidak ada yang dapat mengganggu operasi ini sampai selesai (berhasil atau tidak). Sekali lagi, tidak ada perubahan inode file lama: yang baru dibuat, dan proses yang sudah berjalan tidak akan mengetahuinya, bahkan jika dikaitkan dengan salah satu tautan inode lama.Mengkompilasi ulang file : ketika menggunakan
gcc
(dan perilaku ini mungkin serupa untuk banyak kompiler lain), Anda menggunakan strategi 2. Anda dapat melihat bahwa dengan menjalankanstrace
proses kompiler Anda:stat
danlstat
panggilan sistem.a.out
, inode dan isinya tetap pada disk, selama mereka digunakan oleh proses yang sudah berjalan.a.out
. Ini adalah inode baru, dan konten baru, yang proses yang sudah berjalan tidak peduli.Sekarang, ketika datang ke perpustakaan bersama, perilaku yang sama akan berlaku. Selama objek perpustakaan digunakan oleh suatu proses, itu tidak akan dihapus dari disk, tidak peduli bagaimana Anda mengubah tautannya. Kapan pun sesuatu harus dimuat ke dalam memori, kernel akan melakukannya melalui inode file, dan karena itu akan mengabaikan perubahan yang Anda buat pada tautannya (seperti mengaitkannya dengan file baru).
sumber
df
untuk menghitung jumlah byte gratis pada disk salah karena tidak mengambil inode yang sudahkah semua tautan sistem file dihapus diperhitungkan? Jadi saya harus menggunakandf -i
? (Ini hanya keingintahuan teknis, saya tidak benar-benar perlu tahu persis penggunaan disk!)rm
ataumv
sebagai inode ke file asli tidak dihapus sampai semua proses menghapus tautan mereka ke inode itu.df
termasuk) yang bisa mendapatkan informasi tentang inode. Apa pun informasi baru yang Anda temukan terkait dengan file baru, dan inode baru. Poin utama di sini adalah bahwa subsistem proses tidak tertarik pada masalah ini, sehingga pengertian manajemen memori (paging permintaan, swapping proses, kesalahan halaman, ...) sama sekali tidak relevan. Ini adalah masalah subsistem file, dan ditangani oleh subsistem file. Subsistem proses tidak repot dengan itu, bukan itu yang ada di sini.df -i
: alat ini mungkin mengambil informasi dari superblok fs ', atau cache-nya, yang berarti bahwa ia mungkin menyertakan inode biner lama (yang semua tautannya telah dihapus). Ini tidak berarti bahwa proses baru bebas menggunakan data lama itu.Pemahaman saya adalah bahwa karena pemetaan memori dari proses yang sedang berjalan, kernel tidak akan memperbolehkan memperbarui sebagian dari file yang dipetakan. Saya kira seandainya suatu proses sedang berjalan maka semua file disediakan maka memperbarui itu karena Anda mengkompilasi versi baru dari sumber Anda benar-benar menghasilkan pembuatan set inode baru. Singkatnya, versi yang lebih lama dari executable Anda tetap dapat diakses pada disk melalui peristiwa kesalahan halaman. Jadi, bahkan jika Anda memperbarui file besar, itu harus tetap dapat diakses dan kernel masih harus melihat versi yang tidak tersentuh selama proses berjalan. Inode file asli tidak boleh digunakan kembali selama proses berjalan.
Ini tentu saja harus dikonfirmasi.
sumber
Ini tidak selalu terjadi ketika mengganti file .jar. Sumberdaya jar dan beberapa loader kelas refleksi runtime tidak dibaca dari disk sampai program secara eksplisit meminta informasi.
Ini hanya masalah karena toples hanyalah arsip daripada satu executable yang dipetakan ke dalam memori. Ini sedikit off-stopic tetapi masih merupakan bagian dari pertanyaan Anda dan sesuatu yang telah saya bidik sendiri.
Jadi untuk executable: ya. Untuk file jar: mungkin (tergantung pada implementasi).
sumber