RustRoverのMemory ViewでRustのメモリを確認する

Posted by rhoboro on 2025-03-16

RustRoverのMemory ViewでRustのメモリを確認

最近よくRustを書いていて、IDEには慣れているJetBrainsのRustRoverを利用している。1 RustRoverにはMemory view機能があるため、これを利用してRustのオブジェクトのメモリ構造を確認してみた。

実行するコード

use std::mem::size_of_val;
use std::slice::from_raw_parts;

fn main() {
    let words = vec!["spam", "ham", "egg"];
    let p = words.as_ptr();
    unsafe {
        println!("p = {:?}", p);
        println!("*p = {:?}", *p);
    }
    println!("words = {:?}", as_raw_bytes(&words));
    println!("break here");  // ここにブレークポイントを設定してデバッグ実行
}

// https://qnighy.hatenablog.com/entry/2017/03/04/131311
// https://cipepser.hatenablog.com/entry/rust-memory
fn as_raw_bytes<T: ?Sized>(x: &T) -> &[u8] {
    unsafe { from_raw_parts(x as *const T as *const u8, size_of_val(x)) }
}

コード中にもコメントしていますが、関数as_raw_bytes()は下記を見て知ったものです。

実行

ブレークポイントで停止したら、println!()の結果がConsoleタブに出力されている。

rust_memoryview_01.png

Memory View機能で確認

Threads & Variablesタブ。

rust_memoryview_02.png

Threads & Variablesタブで各変数を右クリックすると、「Show in Memory View」からMemory Viewの該当アドレスにジャンプできる。

rust_memoryview_03.png

Vecのメモリの内容はConsoleに出力されていた words = の値と一致。

Vecはbufとlenから構成されており、bufはptrとcapから構成されている。 つまりVecは3つのusizeから構成されている。 また、ptr部分の値0x00006000012500c0はConsoleに出ていた p = の値と一致。

rust_memoryview_04.png

このアドレスに入っている値は0x0000000100c429ac 0x0000000000000004。 この値はstrを参照している&str型。つまりこれもアドレスと文字列長len。

rust_memoryview_05.png

アドレス0x0000000100c429acに入っている値を確認すると、spam の文字列 = 73 70 61 6dを発見。

rust_memoryview_06.png

おまけ。

メモリビュー見るときはいつもPythonのREPLを使っている気がする。 サクッと変換できるのはやはり便利。ASCIIの範囲くらいは覚えておきたいけど。

$ python3 -q
>>> for c in 'spam':
...     print(f"{ord(c):02x} ", end="")
...
73 70 61 6d

感想

Memory View上の値を選択して、アドレスとしてジャンプできる機能が欲しい。 いつか実装されることを望んでいる。


  1. PyCharmは10年くらい課金している気がする。ここ数年はAll Products Packユーザー。 

tags: Rust, RustRover