Miri adalah alat deteksi Perilaku Tidak Terdefinisi untuk Rust. Ia dapat menjalankan biner dan rangkaian pengujian proyek kargo dan mendeteksi kode tidak aman yang gagal memenuhi persyaratan keselamatannya. Misalnya:
unreachable_unchecked
tercapai, memanggil copy_nonoverlapping
dengan rentang yang tumpang tindih, ...)bool
yang bukan 0 atau 1, atau diskriminan enum yang tidak valid) Selain itu, Miri juga akan memberi tahu Anda tentang kebocoran memori: ketika masih ada memori yang dialokasikan di akhir eksekusi, dan memori tersebut tidak dapat dijangkau dari static
global, Miri akan memunculkan kesalahan.
Anda dapat menggunakan Miri untuk meniru program pada target lain, misalnya untuk memastikan bahwa manipulasi data tingkat byte berfungsi dengan benar pada sistem little-endian dan big-endian. Lihat interpretasi silang di bawah.
Miri telah menemukan banyak bug di dunia nyata. Jika Anda menemukan bug pada Miri, kami akan menghargai jika Anda memberi tahu kami dan kami akan menambahkannya ke daftar!
Secara default, Miri memastikan eksekusi yang sepenuhnya deterministik dan mengisolasi program dari sistem host. Beberapa API yang biasanya mengakses host, seperti mengumpulkan entropi untuk penghasil angka acak, variabel lingkungan, dan jam, digantikan oleh implementasi "palsu" deterministik. Setel MIRIFLAGS="-Zmiri-disable-isolation"
untuk mengakses API sistem sebenarnya. (Khususnya, API RNG sistem "palsu" membuat Miri tidak cocok untuk penggunaan kriptografi ! Jangan membuat kunci menggunakan Miri.)
Meski begitu, ketahuilah bahwa Miri tidak mendeteksi setiap pelanggaran spesifikasi Rust di program Anda, terutama karena tidak ada spesifikasi seperti itu. Miri menggunakan perkiraannya sendiri tentang apa yang termasuk dan bukan Perilaku Tidak Terdefinisi di Rust. Sejauh pengetahuan kami, semua Perilaku Tidak Terdefinisi yang berpotensi memengaruhi kebenaran program terdeteksi oleh Miri (bug modulo), namun Anda harus membaca Referensi untuk mengetahui definisi resmi Perilaku Tidak Terdefinisi. Miri akan diperbarui dengan kompiler Rust untuk melindungi dari UB seperti yang dipahami oleh kompiler saat ini, tetapi tidak memberikan janji tentang versi Rustc yang akan datang.
Peringatan lebih lanjut yang harus diperhatikan oleh pengguna Miri:
-Zrandomize-layout
untuk mendeteksi beberapa kasus ini.)-Zmiri-seed
, namun hal tersebut masih belum mengeksplorasi semua kemungkinan eksekusi.--target x86_64-unknown-linux-gnu
untuk mendapatkan dukungan yang lebih baik.SeqCst
digunakan yang sebenarnya tidak diizinkan oleh model memori Rust, dan tidak dapat menghasilkan semua perilaku yang mungkin dapat diamati pada perangkat keras sebenarnya.Selain itu, Miri pada dasarnya tidak dapat memastikan bahwa kode Anda masuk akal . Kesehatan adalah properti yang tidak pernah menyebabkan perilaku tidak terdefinisi ketika dipanggil dari kode aman yang sewenang-wenang, bahkan dalam kombinasi dengan kode suara lainnya. Sebaliknya, Miri hanya bisa memberi tahu Anda jika cara tertentu berinteraksi dengan kode Anda (misalnya rangkaian pengujian) menyebabkan perilaku tidak terdefinisi dalam eksekusi tertentu (yang mungkin ada banyak, misalnya saat konkurensi atau bentuk non-determinisme lainnya terlibat). Ketika Miri menemukan UB, kode Anda pasti tidak masuk akal, tetapi ketika Miri tidak menemukan UB, Anda mungkin harus menguji lebih banyak input atau lebih banyak kemungkinan pilihan non-deterministik.
Instal Miri di Rust nightly melalui rustup
:
rustup +nightly component add miri
Semua perintah berikut mengasumsikan rantai alat nightly disematkan melalui rustup override set nightly
. Alternatifnya, gunakan cargo +nightly
untuk setiap perintah berikut.
Sekarang Anda dapat menjalankan proyek Anda di Miri:
cargo miri test
.cargo miri run
.Pertama kali Anda menjalankan Miri, ia akan melakukan beberapa pengaturan tambahan dan menginstal beberapa dependensi. Ini akan meminta Anda konfirmasi sebelum menginstal apa pun.
cargo miri run/test
mendukung tanda yang sama persis dengan cargo run/test
. Misalnya, cargo miri test filter
hanya menjalankan pengujian yang mengandung filter
di namanya.
Anda dapat meneruskan bendera ke Miri melalui MIRIFLAGS
. Misalnya, MIRIFLAGS="-Zmiri-disable-stacked-borrows" cargo miri run
menjalankan program tanpa memeriksa aliasing referensi.
Saat mengkompilasi kode melalui cargo miri
, flag konfigurasi cfg(miri)
disetel untuk kode yang akan ditafsirkan di bawah Miri. Anda dapat menggunakan ini untuk mengabaikan kasus pengujian yang gagal pada Miri karena kasus tersebut melakukan hal-hal yang tidak didukung Miri:
# [ test ]
# [ cfg_attr ( miri , ignore ) ]
fn does_not_work_on_miri ( ) {
tokio :: run ( futures :: future :: ok :: < _ , ( ) > ( ( ) ) ) ;
}
Tidak ada cara untuk membuat daftar semua hal tak terbatas yang tidak dapat dilakukan Miri, namun penerjemah akan secara eksplisit memberi tahu Anda ketika ia menemukan sesuatu yang tidak didukung:
error: unsupported operation: can't call foreign function: bind
...
= help: this is likely not a bug in the program; it indicates that the program
performed an operation that Miri does not support
Miri tidak hanya dapat menjalankan biner atau test suite untuk target host Anda, ia juga dapat melakukan interpretasi silang untuk target asing yang sewenang-wenang: cargo miri run --target x86_64-unknown-linux-gnu
akan menjalankan program Anda seolah-olah itu adalah Linux program, apa pun OS host Anda. Ini sangat berguna jika Anda menggunakan Windows, karena target Linux didukung lebih baik daripada target Windows.
Anda juga dapat menggunakan ini untuk menguji platform dengan properti berbeda dari platform host Anda. Misalnya cargo miri test --target s390x-unknown-linux-gnu
akan menjalankan rangkaian pengujian Anda pada target big-endian, yang berguna untuk menguji kode sensitif endian.
Bagian tertentu dari eksekusi dipilih secara acak oleh Miri, seperti alokasi alamat dasar yang tepat disimpan dan interleaving dari thread yang dijalankan secara bersamaan. Kadang-kadang, akan berguna untuk mengeksplorasi beberapa eksekusi yang berbeda, misalnya untuk memastikan bahwa kode Anda tidak bergantung pada "penyelarasan super" yang tidak disengaja dari alokasi baru dan untuk menguji interleaving thread yang berbeda. Hal ini dapat dilakukan dengan flag --many-seeds
:
cargo miri test --many-seeds # tries the seeds in 0..64
cargo miri test --many-seeds=0..16
Default 64 seed berbeda cukup lambat, jadi Anda mungkin ingin menentukan rentang yang lebih kecil.
Saat menjalankan Miri di CI, gunakan cuplikan berikut untuk menginstal nightly toolchain dengan komponen Miri:
rustup toolchain install nightly --component miri
rustup override set nightly
cargo miri test
Berikut adalah contoh pekerjaan untuk GitHub Actions:
miri :
name : " Miri "
runs-on : ubuntu-latest
steps :
- uses : actions/checkout@v4
- name : Install Miri
run : |
rustup toolchain install nightly --component miri
rustup override set nightly
cargo miri setup
- name : Test with Miri
run : cargo miri test
cargo miri setup
yang eksplisit membantu menjaga output dari langkah pengujian yang sebenarnya tetap bersih.
Miri tidak mendukung semua target yang didukung oleh Rust. Kabar baiknya, apa pun OS/platform host Anda, mudah untuk menjalankan kode untuk target apa pun menggunakan --target
!
Target berikut diuji pada CI dan karenanya harus selalu berhasil (sejauh yang didokumentasikan di bawah):
s390x-unknown-linux-gnu
didukung sebagai "target pilihan big-endian" kami.linux
, macos
, atau windows
, Miri secara umum seharusnya berfungsi, namun kami tidak memberikan janji dan kami tidak menjalankan pengujian untuk target tersebut.solaris
/ illumos
: dikelola oleh @devnexen. Mendukung std::{env, thread, sync}
, tetapi tidak std::fs
.freebsd
: ingin pengelola . Mendukung std::env
dan bagian dari std::{thread, fs}
, tetapi tidak std::sync
.android
: pengelola diinginkan . Dukungan sangat tidak lengkap, tetapi dasar "hello world" berfungsi.wasi
: ingin pengelola . Dukungan sangat tidak lengkap, bahkan keluaran standar tidak berfungsi, tetapi fungsi main
yang kosong berfungsi.main
.Namun, bahkan untuk target yang kami dukung, tingkat dukungan untuk mengakses API platform (seperti sistem file) berbeda antar target: umumnya, target Linux memiliki dukungan terbaik, dan target macOS biasanya setara. Windows kurang didukung.
Meskipun mengimplementasikan Rust threading, Miri sendiri adalah penerjemah single-threaded. Ini berarti bahwa saat menjalankan cargo miri test
, Anda mungkin akan melihat peningkatan dramatis dalam jumlah waktu yang diperlukan untuk menjalankan seluruh rangkaian pengujian karena perlambatan intepreter dan hilangnya paralelisme.
Anda bisa mendapatkan kembali paralelisme rangkaian pengujian Anda dengan menjalankan cargo miri nextest run -jN
(perhatikan bahwa Anda perlu menginstal cargo-nextest
). Ini berfungsi karena cargo-nextest
mengumpulkan daftar semua pengujian lalu meluncurkan cargo miri run
terpisah untuk setiap pengujian. Anda harus menentukan -j
atau --test-threads
; secara default cargo miri nextest run
menjalankan satu pengujian dalam satu waktu. Untuk lebih jelasnya, lihat dokumentasi Miri cargo-nextest
.
Catatan: Model satu pengujian per proses ini berarti cargo miri test
mampu mendeteksi data race ketika dua pengujian dilakukan pada sumber daya bersama, namun cargo miri nextest run
tidak akan mendeteksi balapan tersebut.
Catatan: cargo-nextest
tidak mendukung doctests, lihat nextest-rs/nextest#16
Saat menggunakan petunjuk di atas, Anda mungkin mengalami sejumlah kesalahan kompiler yang membingungkan.
RUST_BACKTRACE=1
variabel lingkungan untuk menampilkan penelusuran balik" Anda mungkin melihat ini ketika mencoba membuat Miri menampilkan penelusuran balik. Secara default, Miri tidak mengekspos lingkungan apa pun ke program, jadi menjalankan RUST_BACKTRACE=1 cargo miri test
tidak akan memberikan hasil yang Anda harapkan.
Untuk mendapatkan penelusuran balik, Anda perlu menonaktifkan isolasi menggunakan -Zmiri-disable-isolation
:
RUST_BACKTRACE=1 MIRIFLAGS= " -Zmiri-disable-isolation " cargo miri test
std
yang dikompilasi oleh versi rustic yang tidak kompatibel" Anda mungkin menjalankan cargo miri
dengan versi kompiler yang berbeda dari yang digunakan untuk membuat libstd khusus yang digunakan Miri, dan Miri gagal mendeteksinya. Coba jalankan cargo miri clean
.
-Z
dan variabel lingkungan Miri menambahkan kumpulan flag -Z
miliknya sendiri, yang biasanya disetel melalui variabel lingkungan MIRIFLAGS
. Pertama-tama kami mendokumentasikan flag yang paling relevan dan paling umum digunakan:
-Zmiri-address-reuse-rate=<rate>
mengubah probabilitas bahwa alokasi non-stack yang dibebaskan akan ditambahkan ke kumpulan untuk penggunaan kembali alamat, dan probabilitas bahwa alokasi non-stack baru akan diambil dari kumpulan. Alokasi tumpukan tidak pernah ditambahkan atau diambil dari kumpulan. Standarnya adalah 0.5
.-Zmiri-address-reuse-cross-thread-rate=<rate>
mengubah probabilitas bahwa alokasi yang mencoba menggunakan kembali blok memori yang sebelumnya dibebaskan juga akan mempertimbangkan blok yang dibebaskan oleh thread lain . Standarnya adalah 0.1
, yang berarti secara default, dalam 90% kasus ketika upaya penggunaan kembali alamat dilakukan, hanya alamat dari thread yang sama yang akan dipertimbangkan. Penggunaan kembali alamat dari thread lain menyebabkan sinkronisasi antar thread tersebut, yang dapat menutupi data race dan bug memori yang lemah.-Zmiri-compare-exchange-weak-failure-rate=<rate>
mengubah tingkat kegagalan operasi compare_exchange_weak
. Standarnya adalah 0.8
(jadi 4 dari 5 operasi lemah akan gagal). Anda dapat mengubahnya ke nilai apa pun antara 0.0
dan 1.0
, dengan 1.0
berarti akan selalu gagal dan 0.0
berarti tidak akan pernah gagal. Perhatikan bahwa menyetelnya ke 1.0
kemungkinan akan menyebabkan hang, karena ini berarti program yang menggunakan compare_exchange_weak
tidak dapat membuat kemajuan.-Zmiri-disable-isolation
menonaktifkan isolasi host. Akibatnya, program memiliki akses ke sumber daya host seperti variabel lingkungan, sistem file, dan keacakan.-Zmiri-disable-leak-backtraces
menonaktifkan laporan penelusuran balik untuk kebocoran memori. Secara default, penelusuran balik diambil untuk setiap alokasi saat dibuat, untuk berjaga-jaga jika alokasi tersebut bocor. Hal ini menimbulkan sejumlah overhead memori untuk menyimpan data yang hampir tidak pernah digunakan. Bendera ini tersirat oleh -Zmiri-ignore-leaks
.-Zmiri-env-forward=<var>
meneruskan variabel lingkungan var
ke program yang ditafsirkan. Dapat digunakan berkali-kali untuk meneruskan beberapa variabel. Eksekusi akan tetap bersifat deterministik jika nilai variabel yang diteruskan tetap sama. Tidak berpengaruh jika -Zmiri-disable-isolation
disetel.-Zmiri-env-set=<var>=<value>
menyetel variabel lingkungan var
ke value
dalam program yang ditafsirkan. Ini dapat digunakan untuk meneruskan variabel lingkungan tanpa perlu mengubah lingkungan host. Ini dapat digunakan beberapa kali untuk mengatur beberapa variabel. Jika -Zmiri-disable-isolation
atau -Zmiri-env-forward
disetel, nilai yang disetel dengan opsi ini akan memiliki prioritas dibandingkan nilai dari lingkungan host.-Zmiri-ignore-leaks
menonaktifkan pemeriksa kebocoran memori, dan juga memungkinkan beberapa thread yang tersisa ada saat thread utama keluar.-Zmiri-isolation-error=<action>
mengonfigurasi respons Miri terhadap operasi yang memerlukan akses host saat isolasi diaktifkan. abort
, hide
, warn
, dan warn-nobacktrace
adalah tindakan yang didukung. Standarnya adalah abort
, yang menghentikan mesin. Beberapa (tetapi tidak semua) operasi juga mendukung eksekusi berkelanjutan dengan kesalahan "izin ditolak" yang dikembalikan ke program. warn
mencetak penelusuran balik penuh setiap kali hal itu terjadi; warn-nobacktrace
tidak terlalu bertele-tele dan ditampilkan paling banyak satu kali per operasi. hide
menyembunyikan peringatan itu seluruhnya.-Zmiri-num-cpus
menyatakan jumlah CPU yang tersedia untuk dilaporkan oleh miri. Secara default, jumlah CPU yang tersedia adalah 1
. Perhatikan bahwa tanda ini tidak memengaruhi cara miri menangani thread dengan cara apa pun.-Zmiri-permissive-provenance
menonaktifkan peringatan untuk cast integer-to-pointer dan ptr::with_exposed_provenance
. Hal ini tentu akan menghilangkan beberapa bug karena operasi tersebut tidak dapat diimplementasikan secara efisien dan akurat dalam pembersih, namun hanya akan melewatkan bug yang berhubungan dengan memori/pointer yang tunduk pada operasi ini.-Zmiri-preemption-rate
mengonfigurasi probabilitas bahwa pada akhir blok dasar, thread aktif akan didahului. Standarnya adalah 0.01
(yaitu 1%). Menyetel ini ke 0
akan menonaktifkan preemption.-Zmiri-report-progress
membuat Miri sesekali mencetak stacktrace saat ini, sehingga Anda dapat mengetahui apa yang dilakukannya ketika sebuah program terus berjalan. Anda dapat menyesuaikan seberapa sering laporan dicetak melalui -Zmiri-report-progress=<blocks>
, yang mencetak laporan setiap N blok dasar.-Zmiri-seed=<num>
mengonfigurasi benih RNG yang digunakan Miri untuk menyelesaikan non-determinisme. RNG ini digunakan untuk memilih alamat dasar untuk alokasi, untuk menentukan preemption dan kegagalan compare_exchange_weak
, dan untuk mengontrol buffering penyimpanan untuk emulasi memori yang lemah. Ketika isolasi diaktifkan (default), ini juga digunakan untuk meniru entropi sistem. Seed defaultnya adalah 0. Anda dapat meningkatkan cakupan pengujian dengan menjalankan Miri beberapa kali dengan seed yang berbeda.-Zmiri-strict-provenance
memungkinkan pemeriksaan asal yang ketat di Miri. Ini berarti bahwa memasukkan bilangan bulat ke sebuah pointer akan menghasilkan hasil dengan asal yang 'tidak valid', yaitu dengan asal yang tidak dapat digunakan untuk akses memori apa pun.-Zmiri-symbolic-alignment-check
membuat pemeriksaan penyelarasan lebih ketat. Secara default, perataan diperiksa dengan mengarahkan penunjuk ke bilangan bulat, dan memastikan bahwa itu merupakan kelipatan perataan. Hal ini dapat mengakibatkan suatu program lolos dari pemeriksaan penyelarasan secara kebetulan, karena segala sesuatunya "kebetulan" cukup selaras -- tidak ada UB dalam eksekusi ini tetapi akan ada UB pada eksekusi lainnya. Untuk menghindari kasus seperti ini, pemeriksaan penyelarasan simbolis hanya memperhitungkan penyelarasan yang diminta dari alokasi relevan, dan offset ke dalam alokasi tersebut. Hal ini untuk menghindari hilangnya bug tersebut, tetapi juga menimbulkan beberapa kesalahan positif ketika kode melakukan aritmatika bilangan bulat manual untuk memastikan keselarasan. (Metode align_to
perpustakaan standar berfungsi dengan baik di kedua mode; dalam penyelarasan simbolik, metode ini hanya mengisi bagian tengah ketika alokasi menjamin penyelarasan yang memadai.)Tanda yang tersisa hanya untuk penggunaan tingkat lanjut, dan kemungkinan besar akan diubah atau dihapus. Beberapa di antaranya tidak masuk akal , yang berarti dapat menyebabkan Miri gagal mendeteksi kasus perilaku tidak terdefinisi dalam suatu program.
-Zmiri-disable-alignment-check
menonaktifkan pemeriksaan penyelarasan penunjuk, sehingga Anda dapat fokus pada kegagalan lainnya, tetapi itu berarti Miri dapat melewatkan bug dalam program Anda. Penggunaan bendera ini tidak masuk akal .-Zmiri-disable-data-race-detector
menonaktifkan pemeriksaan data race. Penggunaan bendera ini tidak masuk akal . Ini menyiratkan -Zmiri-disable-weak-memory-emulation
.-Zmiri-disable-stacked-borrows
menonaktifkan pemeriksaan aturan aliasing eksperimental untuk melacak pinjaman (Stacked Borrows dan Tree Borrows). Hal ini dapat membuat Miri berjalan lebih cepat, namun juga berarti tidak ada pelanggaran alias yang terdeteksi. Penggunaan tanda ini tidak masuk akal (tetapi aturan kesehatan yang terpengaruh bersifat eksperimental). Tanda selanjutnya akan diutamakan: pelacakan peminjaman dapat diaktifkan kembali dengan -Zmiri-tree-borrows
.-Zmiri-disable-validation
menonaktifkan penerapan invarian validitas, yang diterapkan secara default. Hal ini sangat berguna untuk fokus pada kegagalan lain (seperti akses di luar batas) terlebih dahulu. Menyetel tanda ini berarti Miri dapat melewatkan bug di program Anda. Namun, hal ini juga dapat membantu membuat Miri berlari lebih cepat. Penggunaan bendera ini tidak masuk akal .-Zmiri-disable-weak-memory-emulation
menonaktifkan emulasi beberapa efek memori lemah C++11.-Zmiri-native-lib=<path to a shared object file>
adalah tanda eksperimental untuk memberikan dukungan untuk memanggil fungsi asli dari dalam penerjemah melalui FFI. Fungsi yang tidak disediakan oleh file tersebut masih dijalankan melalui shim Miri biasa. PERINGATAN : Jika file .so
yang ditentukan tidak valid/salah, ini dapat menyebabkan Perilaku Tidak Terdefinisi di Miri itu sendiri! Dan tentu saja, Miri tidak dapat melakukan pemeriksaan apa pun terhadap tindakan yang diambil oleh kode asli. Perhatikan bahwa Miri memiliki penanganan tersendiri terhadap deskriptor file, jadi jika Anda ingin mengganti beberapa fungsi yang bekerja pada deskriptor file, Anda harus mengganti semuanya , atau kedua jenis deskriptor file tersebut akan tercampur. Ini sedang dalam proses ; saat ini, hanya argumen integer dan nilai kembalian yang didukung (dan tidak, pointer/integer yang digunakan untuk mengatasi batasan ini tidak akan berfungsi; mereka akan gagal total). Ini juga hanya berfungsi pada host Unix untuk saat ini.-Zmiri-measureme=<name>
mengaktifkan pembuatan profil measureme
untuk program yang ditafsirkan. Ini dapat digunakan untuk mengetahui bagian mana dari program Anda yang dijalankan dengan lambat di bawah Miri. Profil ditulis ke file di dalam direktori bernama <name>
, dan dapat diproses menggunakan alat di repositori https://github.com/rust-lang/measureme.-Zmiri-mute-stdout-stderr
secara diam-diam mengabaikan semua penulisan ke stdout dan stderr, tetapi melaporkan ke program bahwa ia benar-benar menulis. Ini berguna ketika Anda tidak tertarik dengan keluaran program sebenarnya, namun hanya ingin melihat kesalahan dan peringatan Miri.-Zmiri-recursive-validation
adalah tanda yang sangat eksperimental yang membuat pemeriksaan validitas berulang di bawah referensi.-Zmiri-retag-fields[=<all|none|scalar>]
mengontrol kapan pemberian tag ulang Stacked Borrows berulang ke dalam kolom. all
berarti selalu berulang (default, dan setara dengan -Zmiri-retag-fields
tanpa nilai eksplisit), none
berarti tidak pernah berulang, scalar
berarti hanya berulang untuk tipe di mana kita juga akan mengeluarkan anotasi noalias
di LLVM IR yang dihasilkan ( jenis diteruskan sebagai skalar individu atau pasangan skalar). Menyetel ini ke none
tidak masuk akal .-Zmiri-provenance-gc=<blocks>
mengonfigurasi seberapa sering pengumpul sampah asal penunjuk berjalan. Standarnya adalah mencari dan menghapus sumber yang tidak dapat dijangkau setiap 10000
blok dasar. Menyetelnya ke 0
akan menonaktifkan pengumpul sampah, yang menyebabkan beberapa program memiliki penggunaan memori yang eksplosif dan/atau waktu proses super-linear.-Zmiri-track-alloc-accesses
tidak hanya menunjukkan alokasi dan peristiwa gratis untuk alokasi yang dilacak, tetapi juga membaca dan menulis.-Zmiri-track-alloc-id=<id1>,<id2>,...
menunjukkan penelusuran balik ketika alokasi tertentu dialokasikan atau dibebaskan. Ini membantu dalam men-debug kebocoran memori dan penggunaan setelah bug gratis. Menetapkan argumen ini beberapa kali tidak akan menimpa nilai sebelumnya, melainkan menambahkan nilainya ke daftar. Mencantumkan id beberapa kali tidak berpengaruh.-Zmiri-track-pointer-tag=<tag1>,<tag2>,...
menampilkan penelusuran balik saat tag penunjuk tertentu dibuat dan saat (jika ada) tag tersebut dikeluarkan dari tumpukan pinjaman (di situlah tag tersebut menjadi tidak valid dan penggunaannya di masa mendatang akan menyebabkan kesalahan). Ini membantu Anda mencari tahu mengapa UB terjadi dan di mana dalam kode Anda tempat yang baik untuk mencarinya. Menetapkan argumen ini beberapa kali tidak akan menimpa nilai sebelumnya, melainkan menambahkan nilainya ke daftar. Mencantumkan tag beberapa kali tidak berpengaruh.-Zmiri-track-weak-memory-loads
menunjukkan penelusuran balik ketika emulasi memori yang lemah mengembalikan nilai usang dari suatu beban. Ini dapat membantu mendiagnosis masalah yang hilang di bawah -Zmiri-disable-weak-memory-emulation
.-Zmiri-tree-borrows
menggantikan Stacked Borrows dengan aturan Tree Borrows. Tree Borrows bahkan lebih eksperimental daripada Stacked Borrows. Meskipun Tree Borrows masih bagus dalam arti menangkap semua pelanggaran aliasing yang mungkin dieksploitasi oleh kompiler versi saat ini, kemungkinan besar model aliasing akhir dari Rust akan lebih ketat daripada Tree Borrows. Dengan kata lain, jika Anda menggunakan Tree Borrows, meskipun kode Anda diterima hari ini, mungkin di masa mendatang kode tersebut akan dinyatakan sebagai UB. Hal ini jauh lebih kecil kemungkinannya dengan Pinjaman Bertumpuk.-Zmiri-force-page-size=<num>
mengganti ukuran halaman default untuk suatu arsitektur, dalam kelipatan 1k. 4
adalah default untuk sebagian besar target. Nilai ini harus selalu berupa pangkat 2 dan bukan nol.-Zmiri-unique-is-unique
melakukan pemeriksaan aliasing tambahan untuk core::ptr::Unique
untuk memastikan bahwa secara teoritis dapat dianggap noalias
. Bendera ini bersifat eksperimental dan hanya berpengaruh bila digunakan dengan -Zmiri-tree-borrows
. Beberapa flag Rustc -Z
asli juga sangat relevan untuk Miri:
-Zmir-opt-level
mengontrol berapa banyak optimasi MIR yang dilakukan. Miri mengganti defaultnya menjadi 0
; perlu diperhatikan bahwa menggunakan level yang lebih tinggi dapat membuat Miri kehilangan bug di program Anda karena bug tersebut telah dioptimalkan.-Zalways-encode-mir
membuat rustic dump MIR bahkan untuk fungsi yang sepenuhnya monomorfik. Ini diperlukan agar Miri dapat menjalankan fungsi tersebut, jadi Miri menyetel tanda ini secara default.-Zmir-emit-retag
mengontrol apakah pernyataan Retag
dikeluarkan. Miri mengaktifkan ini secara default karena diperlukan untuk Pinjaman Bertumpuk dan Pinjaman Pohon.Selain itu, Miri mengenali beberapa variabel lingkungan:
MIRIFLAGS
mendefinisikan bendera tambahan untuk diteruskan ke Miri.MIRI_LIB_SRC
mendefinisikan direktori tempat Miri mengharapkan sumber perpustakaan standar yang akan dibuat dan digunakan untuk interpretasi. Direktori ini harus mengarah ke subdirektori library
dari checkout repositori rust-lang/rust
.MIRI_SYSROOT
menunjukkan sysroot yang akan digunakan. Saat menggunakan cargo miri test
/ cargo miri run
, pengaturan otomatis akan dilewati -- hanya atur ini jika Anda tidak ingin menggunakan sysroot yang dibuat secara otomatis. Saat menjalankan cargo miri setup
, ini menunjukkan di mana sysroot akan ditempatkan.MIRI_NO_STD
memastikan bahwa sysroot target dibuat tanpa libstd. Hal ini memungkinkan pengujian dan menjalankan program no_std. Ini biasanya tidak digunakan ; Miri memiliki heuristik untuk mendeteksi target no-std berdasarkan nama target. Menetapkan ini pada target yang mendukung libstd dapat menyebabkan hasil yang membingungkan. extern
Miri Miri menyediakan beberapa fungsi extern
yang dapat diimpor oleh program untuk mengakses fungsionalitas khusus Miri. Mereka dideklarasikan di /tests/utils/miri_extern.rs.
Biner yang tidak menggunakan pustaka standar diharapkan mendeklarasikan fungsi seperti ini sehingga Miri mengetahui di mana ia harus memulai eksekusi:
# [ cfg ( miri ) ]
# [ no_mangle ]
fn miri_start ( argc : isize , argv : * const * const u8 ) -> isize {
// Call the actual start function that your project implements, based on your target's conventions.
}
Jika Anda ingin berkontribusi pada Miri, bagus! Silakan lihat panduan kontribusi kami.
Untuk bantuan dalam menjalankan Miri, Anda dapat membuka masalah di sini di GitHub atau menggunakan aliran Miri di Rust Zulip.
Proyek ini dimulai sebagai bagian dari kursus penelitian sarjana pada tahun 2015 oleh @solson di Universitas Saskatchewan. Ada slide dan laporan yang tersedia dari proyek itu. Pada tahun 2016, @oli-obk bergabung untuk mempersiapkan Miri agar nantinya digunakan sebagai const evaluator di kompiler Rust itu sendiri (pada dasarnya, untuk const
dan hal-hal static
), menggantikan evaluator lama yang bekerja langsung pada AST. Pada tahun 2017, @RalfJung magang dengan Mozilla dan mulai mengembangkan Miri menjadi alat untuk mendeteksi perilaku tidak terdefinisi, dan juga menggunakan Miri sebagai cara untuk mengeksplorasi konsekuensi dari berbagai kemungkinan definisi untuk perilaku tidak terdefinisi di Rust. Perpindahan mesin Miri ke dalam kompiler @oli-obk akhirnya selesai pada awal tahun 2018. Sementara itu, pada akhir tahun itu, @RalfJung melakukan magang kedua, mengembangkan Miri lebih lanjut dengan dukungan untuk memeriksa invarian tipe dasar dan memverifikasi bahwa referensi digunakan sesuai untuk pembatasan aliasing mereka.
Miri telah menemukan sejumlah bug di perpustakaan standar Rust dan seterusnya, beberapa di antaranya kami kumpulkan di sini. Jika Miri membantu Anda menemukan bug UB halus dalam kode Anda, kami akan menghargai PR yang menambahkannya ke daftar!
Bug yang pasti ditemukan:
Debug for vec_deque::Iter
mengakses memori yang tidak diinisialisasiVec::into_iter
melakukan pembacaan ZST yang tidak selarasFrom<&[T]> for Rc
membuat referensi yang tidak cukup selarasBTreeMap
membuat referensi bersama yang menunjukkan alokasi yang terlalu kecilVec::append
membuat referensi yang menjuntaistr
mengubah referensi bersama menjadi referensi yang bisa berubahrand
melakukan pembacaan yang tidak selarasposix_memalign
dengan cara yang tidak validgetrandom
memanggil syscall getrandom
dengan cara yang tidak validVec
dan BTreeMap
membocorkan memori dalam beberapa kondisi (panik).beef
EbrCell
salah menggunakan memori yang tidak diinisialisasiservo_arc
membuat referensi bersama yang menjuntaiencoding_rs
melakukan aritmatika penunjuk di luar batasVec::from_raw_parts
AtomicPtr
dan Box::from_raw_in
ThinVec
crossbeam-epoch
memanggil assume_init
pada MaybeUninit
yang diinisialisasi sebagianinteger-encoding
mendereferensikan penunjuk yang tidak selarasrkyv
membuat Box<[u8]>
dari alokasi yang selarasarc-swap
thread::scope
regex
salah menangani buffer Vec<u8>
yang tidak selarascompare_exchange_weak
yang salah di once_cell
vec::IntoIter
Iterator::collect
di tempatportable-atomic-util
std::mpsc
(kode asli di crossbeam)Pelanggaran terhadap Pinjaman Bertumpuk yang ditemukan kemungkinan besar merupakan bug (tetapi Pinjaman Bertumpuk saat ini hanyalah sebuah eksperimen):
VecDeque::drain
membuat referensi yang bisa berubah dan tumpang tindihBTreeMap
BTreeMap
membuat referensi yang bisa berubah yang tumpang tindih dengan referensi bersamaBTreeMap::iter_mut
membuat referensi yang bisa diubah dan tumpang tindihBTreeMap
menggunakan pointer mentah di luar area memori yang validLinkedList
membuat referensi yang bisa berubah dan tumpang tindihVec::push
referensi yang ada ke dalam vektor tidak validalign_to_mut
melanggar keunikan referensi yang bisa diubahsized-chunks
membuat aliasing referensi yang bisa berubahString::push_str
membuat referensi yang ada ke dalam string tidak validryu
menggunakan pointer mentah di luar area memori validnyaEnv
menggunakan penunjuk mentah di luar area memori yang validVecDeque::iter_mut
membuat referensi bisa berubah yang tumpang tindih<[T]>::copy_within
menggunakan pinjaman setelah membatalkannya Berlisensi di bawah salah satu dari
sesuai pilihan Anda.
Kecuali jika Anda secara eksplisit menyatakan sebaliknya, setiap kontribusi yang dengan sengaja Anda kirimkan untuk dimasukkan ke dalam karya Anda akan memiliki lisensi ganda seperti di atas, tanpa syarat atau ketentuan tambahan apa pun.