Search code examples
rustlldb

rust-lldb pretty-printing arrays


I noticed that rust-lldb pretty-prints arrays differently depending on context:

   1    fn init(array: &mut[i32; 9]) {
   2      array[4] = 333;
-> 3    }
   4    
   5    fn main() {
   6      let mut array: [i32; 9] = [18; 9];
   7      init(&mut array);
(lldb) p array[0]
(int[9]) {
  [0] = 18
  [1] = 18
  [2] = 18
  [3] = 18
  [4] = 333
  [5] = 18
  [6] = 18
  [7] = 18
  [8] = 18
}

When I step out of init I get a different print format:

   4    
   5    fn main() {
   6      let mut array: [i32; 9] = [18; 9];
-> 7      init(&mut array);
   8      println!("{}", array[4]);
   9    }
Target 0: (main) stopped.
(lldb) p array[0]
(int) 18
(lldb) ### x/9u &array <--- this works fine

How come the print format changes between those contexts?

// main.rs

fn init(array: &mut[i32; 9]) {
  array[4] = 333;
}

fn main() {
  let mut array: [i32; 9] = [18; 9];
  init(&mut array);
  println!("{}", array[4]);
}

Compiled and run with:

$ rustc -g main.rs
$ rust-lldb --source ./commands.dbg ./main

and here are the exact commands:

# commands.dbg

b main.rs:3
run
p array[0]
next
p array[0]
### x/9u &array <--- this works fine

Solution

  • LLDB sees things in a C-centric way.

    The difference between these cases are the types array is a &mut [i32; 9] at your breakpoint in init, but its [i32; 9] in at the next step in main(). Under the hood a &mut reference is just a pointer and LLDB says as such when just looking at p array:

    // in init()
    (lldb) p array
    (int (*)[9]) $2 = 0x00007fffffffdba4
    
    // in main()
    (lldb) p array
    (int [9]) $5 = {
      [0] = 18
      [1] = 18
      [2] = 18
      [3] = 18
      [4] = 333
      ...
    

    Note the difference between int (*)[9] (a pointer to int array) and int [9] (an int array).

    So when you are printing array[0], they do different things. In init() you are simply dereferencing the reference and thus printing the array itself (since that is how [0] works in C), whereas in main() you are simply accessing the first element of the array:

    // in init()
    (lldb) p array[0]
    (int [9]) $0 = {
      [0] = 18
      [1] = 18
      [2] = 18
      [3] = 18
      [4] = 333
      ...
    
    // in main()
    (lldb) p array[0]
    (int) $6 = 18
    

    Your x/9u &array in main() is essentially giving you the same as the simple p array just with a lot more verbosity.


    So if you want to display the array and the variable is a reference use * to dereference it:

    (lldb) p *array
    (int [9]) $10 = {
      [0] = 18
      [1] = 18
      [2] = 18
      [3] = 18
      [4] = 333