Miri は、Rust 用の未定義動作検出ツールです。バイナリを実行して貨物プロジェクトのスイートをテストし、安全要件を満たしていない安全でないコードを検出できます。例えば:
unreachable_unchecked
に到達している、重複する範囲でcopy_nonoverlapping
呼び出しているなど)bool
、または無効な enum 判別式)それに加えて、Miri はメモリ リークについても通知します。実行の終了時にメモリがまだ割り当てられており、そのメモリがグローバルstatic
から到達できない場合、Miri はエラーを発生させます。
Miri を使用すると、他のターゲットでプログラムをエミュレートすることができます。たとえば、バイト レベルのデータ操作がリトル エンディアン システムとビッグ エンディアン システムの両方で正しく動作することを確認できます。以下の相互解釈を参照してください。
ミリはすでに多くの現実世界のバグを発見しています。 Miri のバグを見つけた場合は、お知らせいただければリストに追加します。
デフォルトでは、Miri は完全に決定的な実行を保証し、プログラムをホスト システムから分離します。乱数ジェネレーター、環境変数、クロックのエントロピーの収集など、通常はホストにアクセスする一部の API は、決定論的な「偽の」実装に置き換えられます。代わりに実際のシステム API にアクセスするにはMIRIFLAGS="-Zmiri-disable-isolation"
を設定します。 (特に、「偽」システム RNG API により、Miri は暗号化用途に適さないようになります。Miri を使用してキーを生成しないでください。)
そうは言っても、特にそのような仕様が存在しないため、Miri はプログラム内のRust 仕様の違反をすべて検出するわけではないことに注意してください。 Miri は、Rust の未定義動作と未定義動作について独自の近似値を使用します。私たちの知る限り、プログラムの正しさに影響を与える可能性のあるすべての未定義動作は Miri によって検出されています(モジュロ バグ)。ただし、未定義動作の正式な定義についてはリファレンスを参照する必要があります。 Miri は、現在のコンパイラで理解されている UB から保護するために Rust コンパイラで更新される予定ですが、rustc の将来のバージョンについては保証されません。
Miri ユーザーが知っておくべきさらなる注意事項:
-Zrandomize-layout
使用すると、これらのケースの一部を検出できます。)-Zmiri-seed
に異なる値を指定して Miri を実行することで、この問題をある程度軽減できますが、それでもすべての可能な実行を調査することはできません。--target x86_64-unknown-linux-gnu
使用することをお勧めします。SeqCst
フェンスが使用されている場合、弱いメモリ エミュレーションは、Rust メモリ モデルで実際には許可されていない弱い動作を生成する可能性があり、実際のハードウェアで観察可能なすべての動作を生成することはできません。さらに、Miri は基本的にコードが健全であることを保証できません。健全性とは、他のサウンド コードと組み合わせた場合でも、任意の安全なコードから呼び出された場合に、未定義の動作が発生しないという特性です。対照的に、Miri は、コードと対話する特定の方法(テスト スイートなど) が特定の実行で未定義の動作を引き起こすかどうか (同時実行や他の形式の非決定性の場合など、多数の動作が発生する可能性があります) を通知するだけです。が関与している)。 Miri が UB を見つけた場合、コードは明らかに問題がありますが、Miri が UB を見つけられなかった場合は、より多くの入力またはより多くの可能性のある非決定的な選択肢をテストする必要があるかもしれません。
rustup
経由で毎晩 Miri を Rust にインストールします。
rustup +nightly component add miri
以下のすべてのコマンドは、夜間ツールチェーンrustup override set nightly
によって固定されていることを前提としています。あるいは、次の各コマンドでcargo +nightly
を使用します。
これで、Miri でプロジェクトを実行できるようになりました。
cargo miri test
を使用します。cargo miri run
使用して Miri を通じて実行できます。Miri を初めて実行すると、追加のセットアップが実行され、依存関係がいくつかインストールされます。何かをインストールする前に確認を求められます。
cargo miri run/test
cargo run/test
とまったく同じフラグをサポートします。たとえば、 cargo miri test filter
名前にfilter
含むテストのみを実行します。
MIRIFLAGS
を介して Miri にフラグを渡すことができます。たとえば、 MIRIFLAGS="-Zmiri-disable-stacked-borrows" cargo miri run
参照のエイリアスをチェックせずにプログラムを実行します。
cargo miri
経由でコードをコンパイルする場合、Miri で解釈されるコードに対してcfg(miri)
構成フラグが設定されます。これを使用すると、Miri がサポートしていないことを実行するために Miri の下で失敗するテスト ケースを無視できます。
# [ test ]
# [ cfg_attr ( miri , ignore ) ]
fn does_not_work_on_miri ( ) {
tokio :: run ( futures :: future :: ok :: < _ , ( ) > ( ( ) ) ) ;
}
Miri が実行できない無限のことをすべてリストする方法はありませんが、サポートされていないものを見つけた場合、インタプリタは明示的に通知します。
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 は、ホスト ターゲットのバイナリまたはテスト スイートを実行できるだけでなく、任意の外部ターゲットの相互解釈も実行できます。cargo cargo miri run --target x86_64-unknown-linux-gnu
プログラムを Linux であるかのように実行します。ホスト OS に関係なく、プログラムを実行できます。 Linux ターゲットは Windows ターゲットよりもはるかに適切にサポートされているため、これは Windows を使用している場合に特に便利です。
これを使用して、ホスト プラットフォームとは異なるプロパティを持つプラットフォームをテストすることもできます。たとえば、 cargo miri test --target s390x-unknown-linux-gnu
ビッグ エンディアン ターゲットでテスト スイートを実行します。これは、エンディアンに依存するコードをテストするのに役立ちます。
正確なベース アドレス割り当ての保存や、同時実行スレッドのインターリーブなど、実行の特定の部分が Miri によってランダムに選択されます。場合によっては、コードが新しい割り当ての偶発的な「スーパーアライメント」に依存していないことを確認したり、異なるスレッドのインターリーブをテストしたりするなど、複数の異なる実行を検討すると便利な場合があります。これは--many-seeds
フラグを使用して実行できます。
cargo miri test --many-seeds # tries the seeds in 0..64
cargo miri test --many-seeds=0..16
デフォルトの 64 種類のシードは非常に遅いため、より狭い範囲を指定することをお勧めします。
CI で Miri を実行する場合は、次のスニペットを使用して、Miri コンポーネントを含む夜間ツールチェーンをインストールします。
rustup toolchain install nightly --component miri
rustup override set nightly
cargo miri test
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
実際のテストステップの出力をクリーンに保つのに役立ちます。
Miri は、Rust がサポートするすべてのターゲットをサポートしているわけではありません。ただし、良いニュースは、ホスト OS/プラットフォームに関係なく、 --target
使用して任意のターゲットのコードを簡単に実行できることです。
次のターゲットは CI でテストされているため、常に動作するはずです (以下に記載されている程度まで)。
s390x-unknown-linux-gnu
「選択したビッグエンディアン ターゲット」としてサポートされています。linux
、 macos
、またはwindows
使用する他のすべてのターゲットについては、Miri は通常動作するはずですが、そのようなターゲットに対しては保証はなく、テストも実行しません。solaris
/ illumos
: @devnexen によって維持されます。 std::{env, thread, sync}
サポートされますが、 std::fs
サポートされません。freebsd
:メンテナ募集中。 std::env
とstd::{thread, fs}
の一部はサポートされますが、 std::sync
サポートされません。android
:メンテナ募集中。サポートは非常に不完全ですが、基本的な「hello world」は機能します。wasi
:メンテナ募集中。サポートは非常に不完全で、標準出力さえ機能しませんが、空のmain
関数は機能します。main
機能に到達する前に失敗する可能性があります。ただし、サポートしているターゲットであっても、プラットフォーム API (ファイル システムなど) へのアクセスのサポートの程度はターゲットによって異なります。一般に、Linux ターゲットのサポートが最も優れており、macOS ターゲットは通常同等です。 Windows のサポートはあまり充実していません。
Miri は Rust スレッドを実装していますが、Miri 自体はシングルスレッド インタプリタです。これは、 cargo miri test
実行すると、インタプリタ固有の速度低下と並列処理の損失により、テスト スイート全体の実行にかかる時間が大幅に増加する可能性があることを意味します。
テスト スイートの並列性を取り戻すには、 cargo miri nextest run -jN
を実行します ( cargo-nextest
がインストールされている必要があることに注意してください)。これが機能するのは、 cargo-nextest
すべてのテストのリストを収集し、テストごとに個別のcargo miri run
開始するためです。 -j
または--test-threads
を指定する必要があります。デフォルトでは、 cargo miri nextest run
一度に 1 つのテストを実行します。詳細については、 cargo-nextest
Miri のドキュメントを参照してください。
注: このプロセスごとに 1 つのテスト モデルは、 cargo miri test
共有リソース上で 2 つのテストが競合するデータ競合を検出できるが、 cargo miri nextest run
そのような競合を検出できないことを意味します。
注: cargo-nextest
doctest をサポートしていません。nextest-rs/nextest#16 を参照してください。
上記の手順を使用すると、混乱を招く多数のコンパイラ エラーが発生する可能性があります。
RUST_BACKTRACE=1
環境変数を指定して実行します。」 Miri にバックトレースを表示させようとすると、これが表示されることがあります。デフォルトでは、Miri はプログラムにいかなる環境も公開しないため、 RUST_BACKTRACE=1 cargo miri test
実行しても期待どおりの動作はしません。
バックトレースを取得するには、 -Zmiri-disable-isolation
使用して分離を無効にする必要があります。
RUST_BACKTRACE=1 MIRIFLAGS= " -Zmiri-disable-isolation " cargo miri test
std
が見つかりました」 Miri が使用するカスタム libstd のビルドに使用されたものとは異なるコンパイラ バージョンでcargo miri
実行している可能性がありますが、Miri はそれを検出できませんでした。 cargo miri clean
を実行してみてください。
-Z
フラグと環境変数Miri は、独自の-Z
フラグのセットを追加します。これらのフラグは通常、 MIRIFLAGS
環境変数を介して設定されます。まず、最も関連性が高く、最も一般的に使用されるフラグを文書化します。
-Zmiri-address-reuse-rate=
解放された非スタック割り当てがアドレス再利用のためにプールに追加される確率と、新しい非スタック割り当てがプールから取得される確率を変更します。スタック割り当てがプールに追加されたり、プールから取得されたりすることはありません。デフォルトは0.5
です。-Zmiri-address-reuse-cross-thread-rate=
以前に解放されたメモリ ブロックを再利用しようとする割り当てが、他のスレッドによって解放されたブロックも考慮する確率を変更します。デフォルトは0.1
です。これは、デフォルトでは、アドレスの再利用が試行されるケースの 90% で、同じスレッドのアドレスのみが考慮されることを意味します。別のスレッドのアドレスを再利用すると、それらのスレッド間の同期が発生し、データ競合やメモリ不足のバグが隠蔽される可能性があります。-Zmiri-compare-exchange-weak-failure-rate=
compare_exchange_weak
操作の失敗率を変更します。デフォルトは0.8
です (つまり、5 つの弱い操作のうち 4 つが失敗します)。これは0.0
から1.0
までの任意の値に変更できます。1.0 1.0
常に失敗することを意味し、 0.0
失敗しないことを意味します。 1.0
に設定すると、 compare_exchange_weak
使用するプログラムが進行できなくなるため、ハングが発生する可能性があることに注意してください。-Zmiri-disable-isolation
ホストの分離を無効にします。その結果、プログラムは環境変数、ファイル システム、ランダム性などのホスト リソースにアクセスできるようになります。-Zmiri-disable-leak-backtraces
メモリ リークのバックトレース レポートを無効にします。デフォルトでは、バックトレースがリークした場合に備えて、作成時にすべての割り当てに対してバックトレースがキャプチャされます。これにより、ほとんど使用されないデータを保存するためのメモリ オーバーヘッドが発生します。このフラグは-Zmiri-ignore-leaks
によって暗示されます。-Zmiri-env-forward=
var
環境変数を解釈されたプログラムに転送します。複数回使用して、複数の変数を転送できます。転送された変数の値が同じままであれば、実行は依然として決定的です。 -Zmiri-disable-isolation
が設定されている場合は効果がありません。-Zmiri-env-set==
var
環境変数を解釈されたプログラムのvalue
に設定します。これを使用すると、ホスト環境を変更せずに環境変数を渡すことができます。複数回使用して複数の変数を設定できます。 -Zmiri-disable-isolation
または-Zmiri-env-forward
が設定されている場合、このオプションで設定された値がホスト環境の値より優先されます。-Zmiri-ignore-leaks
メモリ リーク チェッカーを無効にし、メイン スレッドの終了時にいくつかの残りのスレッドが存在できるようにします。-Zmiri-isolation-error=
分離が有効になっているときにホスト アクセスを必要とする操作に対する Miri の応答を構成します。 abort
、 hide
、 warn
、およびwarn-nobacktrace
がサポートされているアクションです。デフォルトはabort
で、マシンが停止します。一部の (すべてではない) 操作では、プログラムに「アクセス許可が拒否されました」エラーが返されても実行を継続することができます。 warn
それが発生するたびに完全なバックトレースを出力します。 warn-nobacktrace
はそれほど冗長ではなく、操作ごとに最大 1 回表示されます。 hide
警告を完全に非表示にします。-Zmiri-num-cpus
miri によって報告される使用可能な CPU の数を示します。デフォルトでは、使用可能な CPU の数は1
です。このフラグは、miri がスレッドを処理する方法にはまったく影響を与えないことに注意してください。-Zmiri-permissive-provenance
整数からポインターへのキャストとptr::with_exposed_provenance
の警告を無効にします。これらの操作はサニタイザーで効率的かつ正確に実装できないため、これにより必然的にいくつかのバグが見逃されますが、これらの操作の対象となるメモリ/ポインターに関するバグのみが見逃されます。-Zmiri-preemption-rate
基本ブロックの終了時にアクティブなスレッドがプリエンプトされる確率を設定します。デフォルトは0.01
(つまり 1%) です。これを0
に設定すると、プリエンプションが無効になります。-Zmiri-report-progress
使用すると、Miri が現在のスタックトレースを時々出力するため、プログラムが実行され続けているときに何が行われているかを知ることができます。 -Zmiri-report-progress=
を使用してレポートを印刷する頻度をカスタマイズできます。これにより、N 基本ブロックごとにレポートが印刷されます。-Zmiri-seed=
Miri が非決定性を解決するために使用する RNG のシードを構成します。この RNG は、割り当てのベース アドレスを選択し、 compare_exchange_weak
のプリエンプションと失敗を判断し、弱いメモリ エミュレーションのストア バッファリングを制御するために使用されます。分離が有効になっている場合 (デフォルト)、これはシステム エントロピーをエミュレートするためにも使用されます。デフォルトのシードは 0 です。異なるシードで Miri を複数回実行すると、テスト カバレッジを増やすことができます。-Zmiri-strict-provenance
、Miri での厳密な出所チェックが可能になります。これは、整数をポインターにキャストすると、「無効な」出所、つまり、メモリ アクセスに使用できない出所を持つ結果が得られることを意味します。-Zmiri-symbolic-alignment-check
アライメントチェックをより厳密にします。デフォルトでは、ポインタを整数にキャストし、それが整列の倍数であることを確認することによって、整列がチェックされます。このため、プログラムがまったくの偶然でアライメント チェックに合格するケースが発生する可能性があります。これは、物事が「たまたま」十分にアライメントされていたためです。この実行には UB はありませんが、他の実行には UB があるはずです。このようなケースを回避するために、シンボリック アライメント チェックでは、関連する割り当ての要求されたアライメントと、その割り当てへのオフセットのみが考慮されます。これにより、このようなバグの見逃しは回避されますが、コードが整列を確実にするために手動で整数演算を行う場合、誤検知も発生します。 (標準ライブラリのalign_to
メソッドはどちらのモードでも正常に動作します。シンボリック アライメントでは、割り当てによって十分なアライメントが保証されている場合にのみ、中央のスライスが埋められます。)残りのフラグは高度な使用のみを目的としており、変更または削除される可能性が高くなります。これらの一部は不健全であり、Miri がプログラム内の未定義の動作のケースを検出できない可能性があることを意味します。
-Zmiri-disable-alignment-check
ポインターの位置合わせのチェックを無効にするため、他の失敗に集中できますが、Miri がプログラム内のバグを見逃す可能性があることを意味します。このフラグを使用するのは不適切です。-Zmiri-disable-data-race-detector
データ競合のチェックを無効にします。このフラグを使用するのは不適切です。これは-Zmiri-disable-weak-memory-emulation
を意味します。-Zmiri-disable-stacked-borrows
ボロー (スタックボローとツリーボロー) を追跡するための実験的なエイリアシング ルールのチェックを無効にします。これにより Miri の実行速度が向上しますが、エイリアシング違反が検出されなくなることも意味します。このフラグを使用することは健全ではありません(ただし、影響を受ける健全性ルールは実験的なものです)。後のフラグが優先されます。借用追跡は-Zmiri-tree-borrows
によって再アクティブ化できます。-Zmiri-disable-validation
デフォルトで強制される妥当性不変条件の強制を無効にします。これは、他の障害 (境界外アクセスなど) に最初に焦点を当てる場合に主に役立ちます。このフラグを設定すると、Miri がプログラム内のバグを見逃す可能性があることを意味します。ただし、これはミリの動作を速くするのにも役立ちます。このフラグを使用するのは不適切です。-Zmiri-disable-weak-memory-emulation
一部の C++11 弱いメモリ効果のエミュレーションを無効にします。-Zmiri-native-lib=
は、FFI を介してインタープリター内からネイティブ関数を呼び出すためのサポートを提供するための実験的なフラグです。そのファイルによって提供されていない関数は、通常の Miri shim を介して実行されます。警告: 無効または間違った.so
ファイルが指定された場合、Miri 自体で未定義の動作が発生する可能性があります。そしてもちろん、Miri はネイティブ コードによって実行されるアクションをチェックすることはできません。 Miri は独自のファイル記述子処理を行っているため、ファイル記述子で動作する一部の関数を置き換える場合は、それらをすべて置き換える必要があり、そうしないと 2 種類のファイル記述子が混同されることに注意してください。これは進行中の作業です。現在、整数の引数と戻り値のみがサポートされています (いいえ、この制限を回避するためのポインタ/整数キャストは機能しません。ひどく失敗します)。また、現時点では Unix ホストでのみ動作します。-Zmiri-measureme=
解釈されたプログラムのmeasureme
プロファイリングを有効にします。これを使用して、プログラムのどの部分が Miri の下で実行が遅いかを見つけることができます。プロファイルは
というディレクトリ内のファイルに書き出され、リポジトリ https://github.com/rust-lang/measureme 内のツールを使用して処理できます。-Zmiri-mute-stdout-stderr
stdout および stderr へのすべての書き込みを黙って無視しますが、実際に書き込んだことをプログラムに報告します。これは、実際のプログラムの出力には興味がなく、Miri のエラーと警告だけを見たい場合に便利です。-Zmiri-recursive-validation
は、参照の下で有効性チェックを再帰させる非常に実験的なフラグです。-Zmiri-retag-fields[=]
は、Stacked Borrows の再タグ付けがフィールドに再帰されるタイミングを制御します。 all
常に再帰することを意味し (デフォルトで、明示的な値のない-Zmiri-retag-fields
と同等)、 none
決して再帰しないことを意味し、 scalar
、生成された LLVM IR でnoalias
アノテーションも出力する型に対してのみ再帰することを意味します (型は個別のスカラーまたはスカラーのペアとして渡されます)。これをnone
に設定するのは不健全です。-Zmiri-provenance-gc=
ポインター来歴ガベージ コレクターを実行する頻度を構成します。デフォルトでは、 10000
基本ブロックごとに 1 回、到達不能な来歴を検索して削除します。これを0
に設定するとガベージ コレクターが無効になり、一部のプログラムでメモリ使用量が爆発的に増加したり、ランタイムが超線形になったりします。-Zmiri-track-alloc-accesses
追跡された割り当ての割り当てイベントと解放イベントだけでなく、読み取りと書き込みも表示します。-Zmiri-track-alloc-id=,,...
指定された割り当てが割り当てられるか解放されるときのバックトレースを示します。これは、メモリ リークのデバッグや解放後のバグの使用に役立ちます。この引数を複数回指定しても、以前の値は上書きされず、その値がリストに追加されます。 ID を複数回リストしても効果はありません。-Zmiri-track-pointer-tag=,,...
指定されたポインタ タグが作成されたとき、および (もしあれば) ボロー スタックからポップされたときのバックトレースを表示します (ここでタグが作成されます)無効であり、今後使用するとエラーになります)。これは、UB が発生している理由と、コード内のどこを探すのが適切かを知るのに役立ちます。この引数を複数回指定しても、以前の値は上書きされず、その値がリストに追加されます。タグを複数回リストしても効果はありません。-Zmiri-track-weak-memory-loads
弱いメモリ エミュレーションがロードから古い値を返した場合のバックトレースを表示します。これは-Zmiri-disable-weak-memory-emulation
で消える問題の診断に役立ちます。-Zmiri-tree-borrows
Stacked Borrows を Tree Borrows ルールに置き換えます。 Tree Borrows は Stacked Borrows よりもさらに実験的です。 Tree Borrows は、現在のバージョンのコンパイラが悪用する可能性のあるすべてのエイリアス違反を捕捉するという意味ではまだ健全ですが、Rust の最終的な最終エイリアス モデルは Tree Borrows よりも厳格になる可能性があります。言い換えれば、Tree Borrows を使用すると、コードが現在受け入れられたとしても、将来的には UB と宣言される可能性があります。 Stacked Borrows では、この可能性ははるかに低くなります。-Zmiri-force-page-size=
、アーキテクチャのデフォルトのページ サイズを 1k の倍数でオーバーライドします。ほとんどのターゲットのデフォルトは4
です。この値は常に 2 のべき乗であり、ゼロ以外である必要があります。-Zmiri-unique-is-unique
core::ptr::Unique
に対して追加のエイリアシング チェックを実行し、理論的にnoalias
とみなされることを確認します。このフラグは実験的なもので、 -Zmiri-tree-borrows
と一緒に使用した場合にのみ効果があります。いくつかのネイティブのrusc -Z
フラグもMiriに非常に関連しています:
-Zmir-opt-level
MIR 最適化を実行する回数を制御します。 Miri はデフォルトを0
にオーバーライドします。より高いレベルを使用すると、プログラム内のバグが最適化されて取り除かれたため、Miri がバグを見逃す可能性があることに注意してください。-Zalways-encode-mir
完全に単相的な関数に対しても Rustc ダンプ MIR を作成します。これは Miri がそのような機能を実行できるようにするために必要なため、Miri はデフォルトでこのフラグを設定します。-Zmir-emit-retag
Retag
ステートメントを発行するかどうかを制御します。 Miri は、Stacked Borrows と Tree Borrows に必要なため、デフォルトでこれを有効にします。さらに、Miri はいくつかの環境変数を認識します。
MIRIFLAGS
Miri に渡される追加のフラグを定義します。MIRI_LIB_SRC
Miri が構築して解釈に使用する標準ライブラリのソースを予期するディレクトリを定義します。このディレクトリは、 rust-lang/rust
リポジトリ チェックアウトのlibrary
サブディレクトリを指している必要があります。MIRI_SYSROOT
使用する sysroot を示します。 cargo miri test
/ cargo miri run
を使用する場合、これは自動セットアップをスキップします。これは、自動的に作成された sysroot を使用したくない場合にのみ設定してください。 cargo miri setup
呼び出すとき、これは sysroot が配置される場所を示します。MIRI_NO_STD
、ターゲットの sysroot が libstd なしで構築されていることを確認します。これにより、no_std プログラムのテストと実行が可能になります。これは通常は使用しないでください。 Miri には、ターゲット名に基づいて非標準ターゲットを検出するヒューリスティックがあります。 libstd をサポートするターゲットにこれを設定すると、混乱を招く結果が生じる可能性があります。 extern
関数Miri は、プログラムが Miri 固有の機能にアクセスするためにインポートできるいくつかのextern
関数を提供します。これらは /tests/utils/miri_extern.rs で宣言されています。
標準ライブラリを使用しないバイナリは、Miri が実行を開始する場所を認識できるように、次のような関数を宣言する必要があります。
# [ 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.
}
Miri に貢献したいのであれば、それは素晴らしいことです。寄付ガイドをご覧ください。
Miri の実行に関するヘルプが必要な場合は、GitHub で問題をオープンするか、Rust Zulip の Miri ストリームを使用してください。
このプロジェクトは、サスカチュワン大学の @solson によって 2015 年に学部研究コースの一環として始まりました。そのプロジェクトから利用できるスライドとレポートがあります。 2016 年に @oli-obk が加わり、最終的に Rust コンパイラ自体の const エバリュエーター (基本的にconst
およびstatic
要素用) として Miri が使用されるように準備し、AST で直接動作していた古いエバリュエーターを置き換えました。 2017 年、@RalfJung は Mozilla でインターンシップを行い、未定義の動作を検出するツールを目指して Miri の開発を開始しました。また、Rust での未定義の動作について考えられるさまざまな定義の結果を調査する方法として Miri を使用しました。 @oli-obk による Miri エンジンのコンパイラへの移行は、2018 年初めにようやく完了しました。一方、その年の後半、@RalfJung は 2 回目のインターンシップを行い、基本的な型不変条件のチェックと、参照が規則に従って使用されることの検証をサポートして Miri をさらに開発しました。エイリアシングの制限に従う必要があります。
Miri はすでに Rust 標準ライブラリおよびその他のバグを多数発見しており、その一部をここに収集します。コード内の微妙な UB バグの発見を Miri が手伝ってくれた場合は、PR がそれをリストに追加していただければ幸いです。
明らかなバグが見つかりました:
Debug for vec_deque::Iter
Vec::into_iter
アライメントされていない ZST 読み取りを実行していますFrom<&[T]> for Rc
十分に位置合わせされていない参照を作成していますBTreeMap
小さすぎる割り当てを指す共有参照を作成していますVec::append
ダングリング参照の作成str
rand
非整列読み取りを実行しますposix_memalign
呼び出すgetrandom
無効な方法でgetrandom
システムコールを呼び出していますVec
とBTreeMap
一部の (パニック的な) 状況下でメモリ リークを起こすbeef
記憶漏れEbrCell
初期化されていないメモリを誤って使用するservo_arc
ダングリング共有参照の作成encoding_rs
範囲外のポインタ演算を実行していますVec::from_raw_parts
誤って使用するAtomicPtr
およびBox::from_raw_in
の不適切な doctestThinVec
のアライメントが不十分ですMaybeUninit
でassume_init
呼び出すcrossbeam-epoch
integer-encoding
整列されていないポインタの逆参照rkyv
オーバーアライメントされた割り当てからBox<[u8]>
を構築していますarc-swap
でのデータ競合thread::scope
でのデータ競合regex
整列されていないVec
バッファを誤って処理するonce_cell
でのcompare_exchange_weak
の誤った使用vec::IntoIter
での位置合わせされていないポインターによるドロップIterator::collect
の新しい特殊化で間違ったレイアウトの割り当てを解除するportable-atomic-util
の高度にアライメントされた型のオフセット計算が正しくないstd::mpsc
チャネルで時折メモリ リークが発生する (クロスビームの元のコード)バグである可能性が高い Stacked Borrows の違反が見つかりました (ただし、Stacked Borrows は現在単なる実験です)。
VecDeque::drain
重複する可変参照の作成BTreeMap
さまざまな問題BTreeMap
イテレータBTreeMap::iter_mut
重複する可変参照の作成BTreeMap
ノードの挿入LinkedList
カーソルの挿入により重複する変更可能な参照が作成されるVec::push
ベクトルへの既存の参照を無効にするalign_to_mut
可変参照の一意性に違反していますsized-chunks
別名変更可能参照の作成String::push_str
文字列への既存の参照を無効にしますryu
有効なメモリ領域外で生のポインタを使用しているEnv
イテレーターVecDeque::iter_mut
重複する可変参照を作成する<[T]>::copy_within
ローンを無効にした後にローンを使用する次のいずれかに基づいてライセンスが付与されている
あなたのオプションで。
あなたが明示的に別段の定めをしない限り、あなたが作品に含めるために意図的に提出した投稿は、追加の条項や条件なしで、上記のように二重ライセンスを受けるものとします。