verilog書く人

自称ASIC設計者です。どなたかkaggle一緒に出ましょう。

Rustのデバッグ体験を上げるには

結論をいうと、

  1. rust-gdbを使う
  2. rustのバージョンを上げる
  3. gdbのバージョンを上げる。

の3つを行うとよい。

rust-gdbを使う。

rustは普通のgdbでもある程度戦える。これはrustがデバッグ情報をDWARF形式で出力しているからである。

が、しかしrustに同梱されている、rust-gdbを使ったほうがより便利である。

rust-gdbがなにをやってくれているかというと、GDBPythonを使って、
VectorやBTreeMapのpretty printingをやってくれる。

fn main() {
    let v = vec![5, 6, 7];
    println!("{:?}", v);
}

上記のソースコードをmain.rsというファイル名で保存し、

rustc -g ./main.rs
rust-gdb ./main

コンパイルし、rust-gdbを起動する。

(gdb) b 3
Breakpoint 1 at 0x85b8: file ./main.rs, line 3.
(gdb) run
Starting program: /home/ryo/workspace/study/rust/main
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".

Breakpoint 1, main::main::h1ac0d5de9b16ce1a () at ./main.rs:3
3       println!("{:?}", v);
(gdb) print v
$1 = Vec<i32>(len: 3, cap: 3) = {5, 6, 7}

のようにして、ベクトルvの中身を表示できる。

rust-gdbではなく、普通のgdbを使うと、

(gdb) print v
$1 = {buf = {ptr = {pointer = {__0 = 0x7ffff6c29000}, _marker = {<No data fields>}}, cap = 3, a = {<No data fields>}}, 
  len = 3}

こんな感じで、あまり参考にならない情報が表示される。

gdbでもがんばれば中身を見ることは可能だが、非常に手間である。

(gdb) print v.buf.ptr.pointer.__0[0]
$11 = 5
(gdb) print v.buf.ptr.pointer.__0[1]
$12 = 6
(gdb) print v.buf.ptr.pointer.__0[2]
$13 = 7

 

rust-lldbもある。が私が使ってないのでここでは触れない。

rustのバージョンを上げる。

rustのデバッグ機能はまだまだ開発中であり、新しいバージョンほどやれることが増えている。
例えば、BTreeMapのpretty printingのサポートは最近サポートされた。

gdbのバージョンを上げる。

gdb側でもRustの対応機能は開発中であり、新しいバージョンほどやれることが増えている。
例えば、GDB Newsによると8.1ではtrait objectを表示する機能が追加された。

 

おまけ:GUIでのデバッグ

Visual Studio CodeやCLionでできる。

競プロ向けのrustテスト/デバッグ環境を作った - verilog書く人

↑私も自作している。

このようなGUIでのデバッガを起動するときも、背面ではrust-gdb(あるいはrust-lldb)が動いているので、rustやgdbのバージョンはあげておこう。