调试 Rust 生成的WebAssembly

本节包含 Rust 调试生成的 WebAssembly 的提示。

带调试符号的构建

⚡ 调试时,请务必确保,是使用调试符号构建的!

如果没有启用调试符号,那么自定义 "name" 部分不会出现在已编译二进制 .wasm 文件中,还有堆栈跟踪的是像 wasm-function[42] 这样的函数名称,而不是函数的 Rust 名称,如 wasm_game_of_life::Universe::live_neighbor_count

使用调试版本时(就是 wasm-pack build --debugcargo build),当然默认情况下启用调试符号。

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

  1. [profile.release]
  2. debug = true

使用 console API 记录日志

日志记录是我们拥有的最有效的工具之一,可以用来证明和反驳关于为什么我们的程序有缺陷的假设。 在 Web 上,console.log函数 用于将消息记录到浏览器的开发人员工具控制台。

我们可以使用 web-sys crate 获取 console.log 函数。

  1. extern crate web_sys;
  2. web_sys::console::log_1(&"Hello, world!".into());

或者,函数 console.error 与 console.log 具有相同的签名,不同的是,使用 console.error 在日志消息旁边会捕获和显示堆栈跟踪。

参考

记录 Panics

console_error_panic_hook crate 会将控制台意外的 panics 记录到 console.error 。 而不是变得晦涩难懂,难以调试的 RuntimeError: unreachable executed 错误消息,这会给你 Rust 格式化的 panic 消息。

你只需要在初始化函数或公共代码路径中通过调用 console_error_panic_hook::set_once()

  1. #[wasm_bindgen]
  2. pub fn init_panic_hook() {
  3. console_error_panic_hook::set_once();
  4. }

使用调试器

不幸的是,WebAssembly的调试还不成熟。在大多数 Unix 系统上 DWARF 用于对调试器提供运行程序的源代码级检查所需的信息进行编码。 在 Windows 上有一种编码类似信息的替代格式。 目前,WebAssembly 的类似的东西。 因此,调试器目前提供的实用程序有限,我们最终将逐步执行编译器发出的原始 WebAssembly 指令,而不是编写的源代码文本。

有一个用于调试 W3C Webassembly 组的子章节 ,所以希望这个在将来得到改进!

尽管如此,调试器对于检查与我们的 WebAssembly 交互的 JavaScript 和检查原始 wasm 状态仍然很有用。

参考

首先避免调试WebAssembly

如果该错误来自与 JavaScript 或 Web API 的交互,那么先用 wasm-bindgen-test 写测试吧。

如果 bug 不涉及与 JavaScript 或 webapi 的交互,那么尝试将其复制为一个普通的 Rust #[test] 函数,在调试时可以利用本地成熟的工具。 使用像 quickcheck 这样的测试 crate 和它的测试用例 shrinkers 来机械地减少测试用例。 最终,如果你可以将 bug 隔离在一个不需要与 JavaScript 交互的较小的测试用例中,那么你将更容易找到和修复 bug。

请注意,为了在没有编译器和链接器错误的情况下运行本机 #[test],你需要确保 Cargo.toml 文件的 [lib.cratet type] 数组中包含 “rlib”

  1. [lib]
  2. crate-type ["cdylib", "rlib"]