Priroda - MIR Debugger
运行示例
Priroda 的 Rust 工具链是四年前的 nightly-2021-03-13,虽然可以正常使用,但无法编译新的项目。
一个基本的 docker 运行 priroda 流程可以描述为:
FROM ubuntu:latest
RUN apt update \
&& apt install -y git curl build-essential pkg-config libgraphviz-dev
RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- --default-toolchain none -y && \
echo "export CARGO_TERM_COLOR=always" >> ~/.bashrc
# COPY . /priroda
RUN git clone https://github.com/oli-obk/priroda /priroda
WORKDIR /priroda
RUN bash -lc "\
rustup show \
&& rustup component add miri \
&& cargo install xargo --locked \
&& cargo miri setup \
"
ENV MIRI_SYSROOT=/root/.cache/miri/HOST
podman build -t priroda .
podman run -d --name priroda --replace --rm priroda sleep infinity
podman exec -it priroda bash
在 x86-64 上运行如下命令可得到
#![allow(unused)]
fn main() {
$ cargo run example.rs
Running `target/debug/priroda example.rs`
🔧 Configured for development.
=> address: localhost
=> port: 54321
=> log: normal
=> workers: 64
=> secret key: generated
=> limits: forms = 32KiB
=> keep-alive: 5s
=> read timeout: 5s
=> write timeout: 5s
=> tls: disabled
🛰 Mounting /:
=> GET /please_panic (please_panic)
=> GET /resources/<path..> (resources)
=> GET /step_count (step_count)
🛰 Mounting /:
=> GET / (index)
=> GET /frame/<frame> (frame)
=> GET /frame/<frame> [42] (frame_invalid)
=> GET /ptr/<alloc_id>/<offset> (ptr)
=> GET /reverse_ptr/<ptr> (reverse_ptr)
🛰 Mounting /breakpoints:
=> GET /breakpoints/add_here (add_here)
=> GET /breakpoints/add/<path..> (add)
=> GET /breakpoints/remove/<path..> (remove)
=> GET /breakpoints/remove_all (remove_all)
🛰 Mounting /step:
=> GET /step/restart (restart)
=> GET /step/single (single)
=> GET /step/single_back (single_back)
=> GET /step/next (next)
=> GET /step/return (return_)
=> GET /step/continue (continue_)
🛰 Mounting /watch:
=> GET /watch/show (show)
=> GET /watch/continue_and_show (continue_and_show)
=> GET /watch/add/<id> (add)
📡 Fairings:
=> 1 launch: Priroda, because code has no privacy rights
🚀 Rocket has launched from http://localhost:54321
warning: unused variable: `u`
--> example.rs:48:9
|
48 | let u = SomeUnion { a: true };
| ^ help: if this is intentional, prefix it with an underscore: `_u`
|
= note: `#[warn(unused_variables)]` on by default
error: internal compiler error: compiler/rustc_metadata/src/rmeta/decoder.rs:1157:17: get_optimized_mir: missing MIR for `DefId(1:6671 ~ std[e
5ee]::rt::lang_start_internal)`
thread 'rustc' panicked at 'Box<Any>', /rustc/b3e19a221e63dcffdef87e12eadf1f36a8b90295/library/std/src/panic.rs:59:5
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
error: aborting due to previous error; 1 warning emitted
============== Miri crashed - restart try 1 ==============
warning: unused variable: `u`
--> example.rs:48:9
|
48 | let u = SomeUnion { a: true };
| ^ help: if this is intentional, prefix it with an underscore: `_u`
|
= note: `#[warn(unused_variables)]` on by default
GET /step_count:
=> Matched: GET /step_count (step_count)
=> Outcome: Success
=> Response succeeded.
GET /step_count:
=> Matched: GET /step_count (step_count)
=> Outcome: Success
=> Response succeeded.
}
在 aarch64 机器上运行示例将得到如下错误:
#![allow(unused)]
fn main() {
$ cargo run example.rs
error[E0308]: mismatched types
--> /root/.cargo/git/checkouts/cgraph-7a547510dd5167be/5e6a6d4/src/lib.rs:90:67
|
90 | let res = gvRenderFilename(gvc, self.0, svg.as_ptr(), file_path.as_ptr() as *const i8);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `u8`, found `i8`
|
= note: expected raw pointer `*const u8`
found raw pointer `*const i8`
}
在指出的源码中修改指针类型,继续编译,就可以得到类似的终端输出结果。
然后打开 localhost:54321,浏览器中将看到 MIR 调试界面:
但点击 Step、Next 之类的按钮,并不能工作,可能因为后端 Miri 找不到 DefId 而 panic (见上面的输出)。