除錯
在寫出更多程式碼之前,當程式出錯時,我們會需要一些除錯工具放在手邊。請花點時間查看 列出可供除錯 Rust 產生的 WebAssembly 的工具和作法的參考頁面。
為 Panic 啟用日誌記錄
若我們的程式發生 Panic,我們希望具資訊性的錯誤訊息出現在開發人員主控台中。
我們的 wasm-pack-template
附帶一個在預設情況下已啟用且相依於 console_error_panic_hook
crate 的選用相依項,其設定在 wasm-game-of-life/src/utils.rs
中。我們只需要在初始化函式或常見程式碼路徑中安裝這個 hook 即可。我們可以在 wasm-game-of-life/src/lib.rs
中的 Universe::new
建構函式內呼叫。
# #![allow(unused_variables)] #fn main() { pub fn new() -> Universe { utils::set_panic_hook(); // ... } #}
為我們的生命遊戲加入日誌記錄
讓我們 使用 web-sys
crate 中的 console.log
函式,為 Universe::tick
函式中的每個單元格加入一些日誌記錄。
首先,將 web-sys
加為相依項,並在 wasm-game-of-life/Cargo.toml
中啟用其 "console"
功能
[dependencies.web-sys]
version = "0.3"
features = [
"console",
]
有關程式人體工學,我們將把 console.log
函式包裝到 println!
類型的巨集中
# #![allow(unused_variables)] #fn main() { extern crate web_sys; // A macro to provide `println!(..)`-style syntax for `console.log` logging. macro_rules! log { ( $( $t:tt )* ) => { web_sys::console::log_1(&format!( $( $t )* ).into()); } } #}
現在,我們可以透過在 Rust 程式碼中插入對 log
的呼叫來開始記錄訊息到主控台,例如,修改 wasm-game-of-life/src/lib.rs
以下載記錄每個單元的狀態、鄰居存活計數,以及下一個狀態
diff --git a/src/lib.rs b/src/lib.rs
index f757641..a30e107 100755
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -123,6 +122,14 @@ impl Universe {
let cell = self.cells[idx];
let live_neighbors = self.live_neighbor_count(row, col);
+ log!(
+ "cell[{}, {}] is initially {:?} and has {} live neighbors",
+ row,
+ col,
+ cell,
+ live_neighbors
+ );
+
let next_cell = match (cell, live_neighbors) {
// Rule 1: Any live cell with fewer than two live neighbours
// dies, as if caused by underpopulation.
@@ -140,6 +147,8 @@ impl Universe {
(otherwise, _) => otherwise,
};
+ log!(" it becomes {:?}", next_cell);
+
next[idx] = next_cell;
}
}
使用偵錯器暫停在每一刻點
瀏覽器的逐步偵錯功能有助於檢查 Rust 產生的 WebAssembly 所互動的 JavaScript
例如,我們可以使用偵錯器在 renderLoop
函式的每個反覆運算上暫停,請將 一個 JavaScript debugger;
陳述式 放在呼叫 universe.tick()
的上方
const renderLoop = () => {
debugger;
universe.tick();
drawGrid();
drawCells();
requestAnimationFrame(renderLoop);
};
這為我們提供了一個用來檢查記錄的訊息的檢查點,並將目前呈現的畫面與前一個畫面做比較
練習
-
加入記錄到
tick
函式,用來記錄每個單元從存活轉換到死亡或反之的列和欄 -
在
Universe::new
方法中引入一個panic!()
,在你的網頁瀏覽器的 JavaScript 偵錯器中檢查 panic 的回溯,停用偵錯符號,在沒有選用的相依項目console_error_panic_hook
下重新建立,然後再次檢查堆疊追蹤,它沒有這麼有用不是嗎?