这是使用 Rust 和 WebAssembly 的**未发布**文档,已发布的文档可在Rust 和 WebAssembly 主文档网站上找到。此处记录的功能可能在 Rust 和 WebAssembly 工具的已发布版本中不可用。

调试 Rust 生成的 WebAssembly

本节包含调试 Rust 生成的 WebAssembly 的技巧。

使用调试符号构建

⚡ 调试时,请确保始终使用调试符号构建!

如果你没有启用调试符号,那么编译后的 .wasm 二进制文件中将不会出现 "name" 自定义部分,并且堆栈跟踪将显示类似 wasm-function[42] 的函数名称,而不是函数的 Rust 名称,例如 wasm_game_of_life::Universe::live_neighbor_count

使用“调试”构建(即 wasm-pack build --debugcargo build)时,默认情况下会启用调试符号。

对于“发布”构建,默认情况下不会启用调试符号。要启用调试符号,请确保在 Cargo.toml 文件的 [profile.release] 部分中 debug = true

[profile.release]
debug = true

使用 console API 进行日志记录

日志记录是我们用来证明和反驳程序出现错误的假设的最有效工具之一。在 Web 上,console.log 函数 是将消息记录到浏览器开发者工具控制台的方法。

我们可以使用web-sys 箱子来访问 console 日志记录函数。


# #![allow(unused_variables)]
#fn main() {
extern crate web_sys;

web_sys::console::log_1(&"Hello, world!".into());
#}

或者,console.error 函数console.log 具有相同的签名,但开发者工具往往还会在使用 console.error 时捕获并显示与记录消息一起的堆栈跟踪。

参考

记录恐慌

console_error_panic_hook 箱子通过 console.error 将意外恐慌记录到开发者控制台。 这将提供 Rust 的格式化恐慌消息,而不是获得难以理解的 RuntimeError: unreachable executed 错误消息。

你只需要在初始化函数或通用代码路径中调用 console_error_panic_hook::set_once() 来安装钩子。


# #![allow(unused_variables)]
#fn main() {
#[wasm_bindgen]
pub fn init_panic_hook() {
    console_error_panic_hook::set_once();
}
#}

使用调试器

不幸的是,WebAssembly 的调试故事仍然不成熟。在大多数 Unix 系统上,DWARF 用于编码调试器需要提供运行程序的源代码级检查的信息。Windows 上有一个用于编码类似信息的替代格式。目前,WebAssembly 没有等效的格式。因此,调试器目前提供的功能有限,我们最终会逐步执行编译器发出的原始 WebAssembly 指令,而不是我们编写的 Rust 源代码。

有一个W3C WebAssembly 小组的调试子章程,因此预计这种情况在将来会得到改善!

尽管如此,调试器仍然可以用来检查与我们的 WebAssembly 交互的 JavaScript,以及检查原始 wasm 状态。

参考

避免需要调试 WebAssembly

如果错误是特定于与 JavaScript 或 Web API 的交互,那么使用 wasm-bindgen-test 编写测试。

如果错误涉及与 JavaScript 或 Web API 的交互,那么尝试将其作为普通的 Rust #[test] 函数重现,这样你就可以在调试时利用操作系统的成熟本机工具。使用测试箱子,例如quickcheck 及其测试用例缩减器来机械地减少测试用例。最终,如果你能够将错误隔离在不需要与 JavaScript 交互的较小的测试用例中,你将更容易找到和修复错误。

请注意,为了运行本机 #[test] 而不出现编译器和链接器错误,你需要确保 "rlib" 包含在 Cargo.toml 文件的 [lib.crate-type] 数组中。

[lib]
crate-type ["cdylib", "rlib"]