← レッスン一覧に戻る レッスン 10 / 28
初級 getting-started
Wasmのデバッグ
Wasmのデバッグが異なる理由
RustがWasm内でパニックすると、ブラウザのコンソールには役に立たないunreachableエラーが表示されます。スタックトレースもエラーメッセージもありません。このレッスンでは、その問題を解決する方法を紹介します。
ステップ1:より良いパニックメッセージ
console_error_panic_hookを追加して、読みやすいパニックメッセージを取得します:
[dependencies]
console_error_panic_hook = "0.1"
wasm-bindgen = "0.2"use wasm_bindgen::prelude::*;
#[wasm_bindgen(start)]
pub fn init() {
// 起動時に一度だけ呼び出す
console_error_panic_hook::set_once();
}
#[wasm_bindgen]
pub fn might_panic(x: i32) -> i32 {
// フックなし: "unreachable"
// フックあり: "panicked at 'index out of bounds: len is 3, index is 5'"
let v = vec![1, 2, 3];
v[x as usize]
}ステップ2:Rustからのコンソールログ
シンプルな方法:web_sys::consoleを使用
use web_sys::console;
// 文字列をログ出力
console::log_1(&"Hello from Rust!".into());
// フォーマット付きログ
console::log_2(&"Value:".into(), &JsValue::from(42));
// 警告とエラー
console::warn_1(&"This is a warning".into());
console::error_1(&"This is an error".into());よりクリーンな方法:ログマクロを作成
macro_rules! log {
($($t:tt)*) => {
web_sys::console::log_1(
&wasm_bindgen::JsValue::from_str(&format!($($t)*))
);
};
}
// 使用例:
log!("User {} logged in at {}", name, timestamp);
log!("Data: {:?}", my_vec);ステップ3:ブラウザDevTools
ソースマップ
デバッグ情報付きでビルドすると、DevToolsでRustのソースコードを確認できます:
# デバッグビルド(バイナリが大きくなるが、デバッグ情報あり)
wasm-pack build --dev --target web
# リリースビルド(デバッグ情報なし)
wasm-pack build --target webNetworkタブ
.wasmファイルが正しく読み込まれているか確認します:
- ステータスが200であること
- Content-Typeが
application/wasmであること - サイズで最適化が効いているか確認
Performanceタブ
Wasmの実行をプロファイリングします:
- DevTools → Performanceを開く
- Recordをクリック
- アプリを操作する
- 記録を停止
- フレームチャートで"wasm-function"エントリを探す
ステップ4:エラーハンドリングパターン
パニックの代わりにResultを返す
#[wasm_bindgen]
pub fn safe_divide(a: f64, b: f64) -> Result<f64, JsValue> {
if b == 0.0 {
Err(JsValue::from_str("Division by zero"))
} else {
Ok(a / b)
}
}JavaScript側では、try/catchになります:
try {
const result = safe_divide(10, 0);
} catch (e) {
console.error("Wasm error:", e); // "Division by zero"
}カスタムエラー型
use wasm_bindgen::prelude::*;
#[wasm_bindgen]
pub struct AppError {
message: String,
code: u32,
}
#[wasm_bindgen]
impl AppError {
pub fn message(&self) -> String { self.message.clone() }
pub fn code(&self) -> u32 { self.code }
}よくあるデバッグチェックリスト
| 問題 | 原因 | 解決方法 |
|---|---|---|
コンソールにunreachable |
フックなしのRustパニック | console_error_panic_hookを追加 |
.wasmファイルが読み込めない |
パスまたはMIMEタイプが間違い | Networkタブを確認し、正しいContent-Typeで配信 |
読み込み時にLinkError |
インポートが不足 | すべてのextern "C"インポートが満たされているか確認 |
RuntimeError: memory |
Wasmメモリ不足 | メモリを増やすかメモリリークを修正 |
| 関数が見つからない | エクスポートされていない | #[wasm_bindgen]とpubを追加 |
| 型が一致しない | wasm-bindgenのバージョン不一致 | JSグルーと.wasmが同じビルドのものか確認 |
試してみよう
Runをクリックして、デバッグ出力の例を確認しましょう。実際のWasmプロジェクトでは、println!をconsole::log_1に置き換えてください。
試してみる
チャプタークイズ
すべての問題に正解してレッスンを完了しましょう