How does one print elements of a rust vector in the llvm debugger?

If I compile the following cargo_test/src/main.rs:

fn main() {
   let v : Vec<u32> = vec![1, 2, 3];
   println!( "{:?}", v);
}

And then run the following commands in the cargo_test directory

lldb target/debug/cargo_test
b main.rs:4
run
p v

I get the output

(lldb) print v
(alloc::vec::Vec<unsigned int, alloc::alloc::Global>) {
  buf = {
    inner = {
      ptr = {
        pointer = (pointer = "\U00000001")
        _marker = {}
      }
      cap = (__0 = 3)
      alloc = {}
    }
    _marker = {}
  }
  len = 3
}

If I try to print the first element of v I get

(lldb) p v[0]
          ˄
          ╰─ error: type 'alloc::vec::Vec<unsigned int, alloc::alloc::Global>' does not provide a subscript operator
(lldb) 

I don't know if it will fix this specific issue, but at the very least you probably want to use the rust-lldb wrapper that ships with rust rather than plain lldb. This adds a bunch of pretty printers for rust types.

Maybe this:
https://stackoverflow.com/questions/79532038/how-to-get-an-individual-element-from-a-vec-in-rust-gdb

That answer isn't directly applicable to lldb as lldb doesn't support rust syntax. If you rewrite that code in C, it may work though.

You're right. This works for me in lldb:

p ((unsigned*) v.buf.inner.ptr.pointer.pointer)[0]

(corrected)

Thanks for the suggestion. The following works for me for small vectors (which is the cases for many of my tests):

rust-lldb target/debug/cargo_test -Q
b main.rs
run
p v

Here is the output that I get:

rust-lldb target/debug/cargo_test -Q
Current executable set to '/Users/bradbell/trash/rust/cargo_test/target/debug/cargo_test' (arm64).
(lldb) b main.rs:4
Breakpoint 1: where = cargo_test`cargo_test::main::h2670d8b4fb84495b + 148 at main.rs:4:4, address = 0x00000001000014a8
(lldb) run
Process 19485 launched: '/Users/bradbell/trash/rust/cargo_test/target/debug/cargo_test' (arm64)
Process 19485 stopped
* thread #1, name = 'main', queue = 'com.apple.main-thread', stop reason = breakpoint 1.1
    frame #0: 0x00000001000014a8 cargo_test`cargo_test::main::h2670d8b4fb84495b at main.rs:4:4
   1   	
   2   	fn main() {
   3   	   let v : Vec<u32> = vec![1, 2, 3];
-> 4   	   println!( "{:?}", v);
   5   	}
   6   	
Target 0: (cargo_test) stopped.
(lldb) p v
(alloc::vec::Vec<unsigned int, alloc::alloc::Global>) size=3 {
  [0] = 1
  [1] = 2
  [2] = 3
}
(lldb) 

Here are some of my attempts to access a single element of v:

(lldb) p v[0]
          ˄
          ╰─ error: type 'alloc::vec::Vec<unsigned int, alloc::alloc::Global>' does not provide a subscript operator

(lldb) p v.buf.inner.ptr.pointer.pointer[0]
(unsigned char) '\x01'

Did you try the C translation that I posted, in my last reply?

This works for me in lldb and rust-lldb.


You can make things simpler if you coerce the Vec to a slice in your program:

   let v : Vec<u32> = vec![1, 2, 3];
   let s = &v[..];

Then when running lldb or rust-lldb, if you break after s is initialized you can print the elements more easily:

(lldb) p s.data_ptr[0]
(unsigned int) $1 = 1
(lldb) p s.data_ptr[1]
(unsigned int) $2 = 2

This works because lldb has the correct type for the data_ptr of a slice:

(lldb) p s.data_ptr
(unsigned int *) $10 = 0x00005555555af940
1 Like

Thanks, the slice trick helps a lot.

With the change above that added the slice to the program, in rust-lldb I get

(lldb) run
Process 21760 launched: '/Users/bradbell/trash/rust/cargo_test/target/debug/cargo_test' (arm64)
Process 21760 stopped
* thread #1, name = 'main', queue = 'com.apple.main-thread', stop reason = breakpoint 1.1
    frame #0: 0x0000000100001554 cargo_test`cargo_test::main::h2670d8b4fb84495b at main.rs:5:4
   2   	fn main() {
   3   	   let v : Vec<u32> = vec![1, 2, 3];
   4   	   let s = &v[..];
-> 5   	   println!( "{:?}", s);
   6   	}
   7   	
Target 0: (cargo_test) stopped.
(lldb) p s
(&[u32]) size=3 {
  [0] = 1
  [1] = 2
  [2] = 3
}

There is no indication above that s.data_ptr exists. On the other hand in lldb I get

(lldb) p s
(&[u32]) {
  data_ptr = 0x00006000031c4020
  length = 3
}
(lldb) parray 3 s.data_ptr
(unsigned int *) $1 = 0x00006000031c4020 {
  [0] = 1
  [1] = 2
  [2] = 3
(lldb) p s.data_ptr[0]
(unsigned int) 1

We must be using different version of rust-lldb. It seems I'm not getting the pretty-printing of the slice as a whole, and instead I see its fields when I print it:

(lldb) p s
(&[u32]) $0 = {
  data_ptr = 0x00005555555af940
  length = 3
}

I'm using:

$ rust-lldb --version
lldb version 16.0.0

Looks like the latest version is 20.

Did you try just using p s[0]? Maybe in your version it will work.

I like to do version numbers by date; e.g. 2025.6.21 (so I know more about how old a version is). Anyway here are the numbers for my system:

I am running on macOS Sequoia version 15.5

cargo_test>rust-lldb --version
lldb-1700.0.9.502
Apple Swift version 6.1.2 (swiftlang-6.1.2.1.2 clang-1700.0.13.5)

(base) cargo_test>(base) cDarwin bradbell-YJ9MWG707F 24.5.0 Darwin Kernel Version 24.5.0: Tue Apr 22 19:54:49 PDT 2025; root:xnu-11417.121.6~2/RELEASE_ARM64_T6000 arm64
(base) cargo_test>

It depends a lot on the custom implementation of LLDB. For what it's worth, the current version of RustRover with LLDB-19 (they recent upgrade) shows the values as expected with p v and the individual values with p v[0] on Windows; I don't know what version they currently have on macOS.

Sometimes, the GNU toolchain / gdb gets better results, at least in the IDE, but not always, and it's slower to compile code and launch tests in that environment, so I'm using it only when I need to see variables in the debugger.

It's often easier to simply print them out than to rely on a debugger.