Improve processor error messages
- 主要语言
- Rust
- 星标
- 772
- 派生
- 352
- 平均合并
- 1 天 12 小时
- 30 天内合并 PR
- 93
描述
This is a tracking issue for how to improve errors emitted from the VM. The proposed changes come out of the DevEx meeting we had last week (cc @phklive), ideas from #1289, and discussions with @bitwalker.
Currently, `ExecutionError` outputs very simple errors, with very little context, and thus are very hard to use when debugging. For example, if the processor tries to read a word from an unaligned memory address, we output `word memory access at address {addr} in context {ctx} is unaligned at clock cycle {clk}`. A much better error would provide the source code location (MASM or Rust) where this occured, and a helpful message explaining what "unaligned" means in this case (i.e. divisible by 4). An even better error message would contain a stack trace, as mentioned [here](https://github.com/0xPolygonMiden/miden-vm/issues/1289#issuecomment-2468123236) by @PhilippGackstatter.
As I understand it, there are two main steps on the path to great error messages:
1. Modify `ExecutionError` to use `miette` diagnostics properly, similar to `AssemblyError`
- specifically, in the processor at the error construction site, we'll need to look into the node's decorators for an `AssemblyOp` decorator to properly construct the `ExecutionError` variant
2. Add stack traces
Step 1 is a low-hanging fruit that we can do in a single PR, and would already be a great improvement over the current situation. As discussed with @bitwalker, step 2 is quite a bit more involved. The remaining of this issue will discuss how that could look like.
## Stack traces discussion
`midenc-debug` currently tracks the state of the stack by inserting `trace` events on entry & exit of each procedures. Then, [in the `Host::on_trace()`](https://github.com/0xPolygonMiden/compiler/blob/ae28c9b36cf4842915270c7d70167d149fd09273/midenc-debug/src/exec/host.rs#L66-L73), it tries to infer the procedure being entered/exited. I'm not too familiar with the details - but the TLDR is that using trace events is imprecise (maybe @bitwalker you could add to this thread the specific difficulties you encountered). A better approach would be to tag (at assembly time), for each procedure (internal and external), the entry & exit procedure hashes (where procedure hashes are preferred over node IDs - more on that later). This information could then be used to keep track of stack traces in a precise way.
It would be cleaner as well to have this debug information separately, instead of stored in decorators in the `MastForest`. For example, this struct could look like
```rs
struct DebugInfo {
// Maps node_hash -> procedure_name
proc_entrypoints: BTreeMap,
proc_exits: BTreeMap,
// some map "location -> assembly op" (the source mapping information"
// some map "location -> debug option" (the debug decorator)
}
```
which could be passed as an `Option` to `Process:execute()`.
This also has the benefit that we could implement the ability to provide an `ExecutionTrace` along with a `DebugInfo` to a debugger, and debug the `ExecutionTrace` with nice source mapping. This could be particularly useful to debug traces that occurred in production, where debug info is not available. This is why we said earlier that we prefer to use procedure hashes instead of `MastNodeId`s in `DebugInfo` - the execution trace doesn't contain node IDs, but it contains all the hashes (in the decoder).
贡献指南
评估
这个 Issue 还没有评估数据。