本日リリースの Rust 1.60.0 の目玉機能の一つであるSource-based Code Coverage(バイナリ実行時に行レベルでの実行回数を記録する機能)を動かしてみました。 手順を覚えておくと手元で簡単に実行時のカバレッジ計測ができてデバッグに役立ちそうだと感じました。
必要なモジュールのインストール
必要なツール群をインストールします。
# Rust 1.60.0 へのアップデート rustup update # カバレッジ表示用のツールをインストール rustup component add llvm-tools-preview # デマングラー(demangler)をインストール cargo install rustfilt
サンプルプログラム
行ごとの実行回数を見やすいようにゴテゴテとしたFizzBuzzを書いてみます。cargo new fizzbuzz
から main.rs
に実装していきます。
fn fizz(n: usize) -> &'static str { if n == 0 { unreachable!("I don't expect n == 0.") } if n % 3 == 0 { return "Fizz"; } else { return ""; } } fn buzz(n: usize) -> &'static str { if n % 5 == 0 { return "Buzz"; } else { return ""; } } fn fizz_buzz(n: usize) -> String { let mut tmp = vec![]; tmp.push(fizz(n)); tmp.push(buzz(n)); let ret = tmp.join(""); if ret.len() > 0 { return ret; } n.to_string() } fn main() { const N: usize = 20; for i in 1..N { println!("{}: {}", i, fizz_buzz(i)); } }
カバレッジの計測
コンパイル
コンパイル時にフラグを付けます。
RUSTFLAGS="-C instrument-coverage" cargo build
バイナリ実行
作られたバイナリを実行します。
./target/debug/fizzbuzz
今回はFizzBuzzの結果が標準出力に表示されます。
また今いるディレクトリに default.profraw
というファイルが作られます。(手順通りに行っていればプロジェクトルートに作られるので ls ./
で確認できるはず。)
カバレッジの表示
default.profraw
は各行の実行回数が保存されていますが、人間が見れる形になっていないので、見れる形にする処理を行います。
# ※先頭の `$` から入力が必要です。 $(rustc --print sysroot)/lib/rustlib/x86_64-unknown-linux-gnu/bin/llvm-profdata merge -sparse default.profraw -o default.profdata $(rustc --print sysroot)/lib/rustlib/x86_64-unknown-linux-gnu/bin/llvm-cov show -Xdemangler=rustfilt target/debug/fizzbuzz \ -instr-profile=default.profdata \ -show-line-counts-or-regions \ -show-instantiations
各行の実行回数が正しく表示されており、実行されていない箇所や最も実行されている箇所も分かりやすく表示されています。
ちなみに今回はdebugビルドで行いましたが、releaseビルドでも llvm-cov
の引数にとる実行バイナリを変えてやると同じように結果が表示されました。