Closed
Description
I tried this code (as package foo
):
fn main() {
let my_string = String::from("Hello, world!");
let my_pathbuf = std::path::PathBuf::from("/arriving/somewhere/but/not/here");
let my_str = "Hello, world!";
let my_path = &std::path::PathBuf::from("/this/is/a/path");
println!("{my_string}");
println!("{}", my_pathbuf.display());
}
Run the following, which will break at main
, step the next 4 lines (n
) to define the variables, then print my_path.inner
twice -- the first time will succeed, the second time will fail:
$ rust-lldb -o 'break set --name foo::main' -o run target/debug/foo
(lldb) command script import "/Users/n8henrie/.rustup/toolchains/stable-aarch64-apple-darwin/lib/rustlib/etc/lldb_lookup.py"
(lldb) command source -s 0 '/Users/n8henrie/.rustup/toolchains/stable-aarch64-apple-darwin/lib/rustlib/etc/lldb_commands'
Executing commands in '/Users/n8henrie/.rustup/toolchains/stable-aarch64-apple-darwin/lib/rustlib/etc/lldb_commands'.
(lldb) type synthetic add -l lldb_lookup.synthetic_lookup -x ".*" --category Rust
(lldb) type summary add -F lldb_lookup.summary_lookup -e -x -h "^(alloc::([a-z_]+::)+)String$" --category Rust
(lldb) type summary add -F lldb_lookup.summary_lookup -e -x -h "^&(mut )?str$" --category Rust
(lldb) type summary add -F lldb_lookup.summary_lookup -e -x -h "^&(mut )?\\[.+\\]$" --category Rust
(lldb) type summary add -F lldb_lookup.summary_lookup -e -x -h "^(std::ffi::([a-z_]+::)+)OsString$" --category Rust
(lldb) type summary add -F lldb_lookup.summary_lookup -e -x -h "^(alloc::([a-z_]+::)+)Vec<.+>$" --category Rust
(lldb) type summary add -F lldb_lookup.summary_lookup -e -x -h "^(alloc::([a-z_]+::)+)VecDeque<.+>$" --category Rust
(lldb) type summary add -F lldb_lookup.summary_lookup -e -x -h "^(alloc::([a-z_]+::)+)BTreeSet<.+>$" --category Rust
(lldb) type summary add -F lldb_lookup.summary_lookup -e -x -h "^(alloc::([a-z_]+::)+)BTreeMap<.+>$" --category Rust
(lldb) type summary add -F lldb_lookup.summary_lookup -e -x -h "^(std::collections::([a-z_]+::)+)HashMap<.+>$" --category Rust
(lldb) type summary add -F lldb_lookup.summary_lookup -e -x -h "^(std::collections::([a-z_]+::)+)HashSet<.+>$" --category Rust
(lldb) type summary add -F lldb_lookup.summary_lookup -e -x -h "^(alloc::([a-z_]+::)+)Rc<.+>$" --category Rust
(lldb) type summary add -F lldb_lookup.summary_lookup -e -x -h "^(alloc::([a-z_]+::)+)Arc<.+>$" --category Rust
(lldb) type summary add -F lldb_lookup.summary_lookup -e -x -h "^(core::([a-z_]+::)+)Cell<.+>$" --category Rust
(lldb) type summary add -F lldb_lookup.summary_lookup -e -x -h "^(core::([a-z_]+::)+)Ref<.+>$" --category Rust
(lldb) type summary add -F lldb_lookup.summary_lookup -e -x -h "^(core::([a-z_]+::)+)RefMut<.+>$" --category Rust
(lldb) type summary add -F lldb_lookup.summary_lookup -e -x -h "^(core::([a-z_]+::)+)RefCell<.+>$" --category Rust
(lldb) type summary add -F lldb_lookup.summary_lookup -e -x -h "^core::num::([a-z_]+::)*NonZero.+$" --category Rust
(lldb) type category enable Rust
(lldb) target create "target/debug/foo"
Current executable set to '/var/folders/kb/tw_lp_xd2_bbv0hqk4m0bvt80000gn/T/tmp.hglxvts2wO/fo/target/debug/foo' (arm64).
(lldb) break set --name foo::main
Breakpoint 1: where = foo`foo::main::hac42d693f36ccfc8 + 24 at main.rs:4:9, address = 0x0000000100001730
(lldb) run
Process 48473 stopped
* thread #1, name = 'main', queue = 'com.apple.main-thread', stop reason = breakpoint 1.1
frame #0: 0x0000000100001730 foo`foo::main::hac42d693f36ccfc8 at main.rs:4:9
1 fn main() {
2 let my_string = String::from("Hello, world!");
3 let my_pathbuf = std::path::PathBuf::from("/arriving/somewhere/but/not/here");
-> 4 let my_str = "Hello, world!";
5 let my_path = &std::path::PathBuf::from("/this/is/a/path");
6 println!("{my_string}");
7 println!("{}", my_pathbuf.display());
Target 0: (foo) stopped.
Process 48473 launched: '/var/folders/kb/tw_lp_xd2_bbv0hqk4m0bvt80000gn/T/tmp.hglxvts2wO/fo/target/debug/foo' (arm64)
(lldb) n
Process 48473 stopped
* thread #1, name = 'main', queue = 'com.apple.main-thread', stop reason = step over
frame #0: 0x0000000100001744 foo`foo::main::hac42d693f36ccfc8 at main.rs:2:21
1 fn main() {
-> 2 let my_string = String::from("Hello, world!");
3 let my_pathbuf = std::path::PathBuf::from("/arriving/somewhere/but/not/here");
4 let my_str = "Hello, world!";
5 let my_path = &std::path::PathBuf::from("/this/is/a/path");
6 println!("{my_string}");
7 println!("{}", my_pathbuf.display());
Target 0: (foo) stopped.
(lldb) n
Process 48473 stopped
* thread #1, name = 'main', queue = 'com.apple.main-thread', stop reason = step over
frame #0: 0x000000010000174c foo`foo::main::hac42d693f36ccfc8 at main.rs:3:22
1 fn main() {
2 let my_string = String::from("Hello, world!");
-> 3 let my_pathbuf = std::path::PathBuf::from("/arriving/somewhere/but/not/here");
4 let my_str = "Hello, world!";
5 let my_path = &std::path::PathBuf::from("/this/is/a/path");
6 println!("{my_string}");
7 println!("{}", my_pathbuf.display());
Target 0: (foo) stopped.
(lldb) n
Process 48473 stopped
* thread #1, name = 'main', queue = 'com.apple.main-thread', stop reason = step over
frame #0: 0x0000000100001784 foo`foo::main::hac42d693f36ccfc8 at main.rs:5:20
2 let my_string = String::from("Hello, world!");
3 let my_pathbuf = std::path::PathBuf::from("/arriving/somewhere/but/not/here");
4 let my_str = "Hello, world!";
-> 5 let my_path = &std::path::PathBuf::from("/this/is/a/path");
6 println!("{my_string}");
7 println!("{}", my_pathbuf.display());
8 }
Target 0: (foo) stopped.
(lldb) n
Process 48473 stopped
* thread #1, name = 'main', queue = 'com.apple.main-thread', stop reason = step over
frame #0: 0x00000001000017d8 foo`foo::main::hac42d693f36ccfc8 at main.rs:6:5
3 let my_pathbuf = std::path::PathBuf::from("/arriving/somewhere/but/not/here");
4 let my_str = "Hello, world!";
5 let my_path = &std::path::PathBuf::from("/this/is/a/path");
-> 6 println!("{my_string}");
7 println!("{}", my_pathbuf.display());
8 }
Target 0: (foo) stopped.
(lldb) po my_path.inner
"/this/is/a/path"
(lldb) po my_path.inner
error: <user expression 2>:1:1: use of undeclared identifier 'my_path'
my_path.inner
^
I expected to see this happen: po my_path.inner
would work the same no matter how many times I called it, instead everything seems to be undefined after the first call. Below I show that frame var
seems to work (including multiple times), po my_str
works (including multiple times), but after a single call to po my_path.inner
, neither of these works anymore:
(lldb) frame var
(alloc::string::String) my_string = "Hello, world!" {
vec = size=13 {
[0] = 'H'
[1] = 'e'
[2] = 'l'
[3] = 'l'
[4] = 'o'
[5] = ','
[6] = ' '
[7] = 'w'
[8] = 'o'
[9] = 'r'
[10] = 'l'
[11] = 'd'
[12] = '!'
}
}
(std::path::PathBuf) my_pathbuf = {
inner = "/arriving/somewhere/but/not/here" {
inner = {
inner = size=32 {
[0] = '/'
[1] = 'a'
[2] = 'r'
[3] = 'r'
[4] = 'i'
[5] = 'v'
[6] = 'i'
[7] = 'n'
[8] = 'g'
[9] = '/'
[10] = 's'
[11] = 'o'
[12] = 'm'
[13] = 'e'
[14] = 'w'
[15] = 'h'
[16] = 'e'
[17] = 'r'
[18] = 'e'
[19] = '/'
[20] = 'b'
[21] = 'u'
[22] = 't'
[23] = '/'
[24] = 'n'
[25] = 'o'
[26] = 't'
[27] = '/'
[28] = 'h'
[29] = 'e'
[30] = 'r'
[31] = 'e'
}
}
}
}
(&str) my_str = "Hello, world!" {
data_ptr = 0x0000000100036a6c "Hello, world!/arriving/somewhere/but/not/here/this/is/a/path"
length = 13
}
(std::path::PathBuf *) my_path = 0x000000016fdfdd20
(lldb) frame var
(alloc::string::String) my_string = "Hello, world!" {
vec = size=13 {
[0] = 'H'
[1] = 'e'
[2] = 'l'
[3] = 'l'
[4] = 'o'
[5] = ','
[6] = ' '
[7] = 'w'
[8] = 'o'
[9] = 'r'
[10] = 'l'
[11] = 'd'
[12] = '!'
}
}
(std::path::PathBuf) my_pathbuf = {
inner = "/arriving/somewhere/but/not/here" {
inner = {
inner = size=32 {
[0] = '/'
[1] = 'a'
[2] = 'r'
[3] = 'r'
[4] = 'i'
[5] = 'v'
[6] = 'i'
[7] = 'n'
[8] = 'g'
[9] = '/'
[10] = 's'
[11] = 'o'
[12] = 'm'
[13] = 'e'
[14] = 'w'
[15] = 'h'
[16] = 'e'
[17] = 'r'
[18] = 'e'
[19] = '/'
[20] = 'b'
[21] = 'u'
[22] = 't'
[23] = '/'
[24] = 'n'
[25] = 'o'
[26] = 't'
[27] = '/'
[28] = 'h'
[29] = 'e'
[30] = 'r'
[31] = 'e'
}
}
}
}
(&str) my_str = "Hello, world!" {
data_ptr = 0x0000000100036a6c "Hello, world!/arriving/somewhere/but/not/here/this/is/a/path"
length = 13
}
(std::path::PathBuf *) my_path = 0x000000016fdfdd20
(lldb) po my_str
"Hello, world!"
(lldb) po my_str
"Hello, world!"
(lldb) po my_str
"Hello, world!"
(lldb) po my_path.inner
"/this/is/a/path"
(lldb) po my_str
error: <user expression 2>:1:1: use of undeclared identifier 'my_str'
my_str
^
(lldb) frame var
(alloc::string::String *) x = 0x000000016fdfdcf0
Oddly, if I break on filename / line number instead of function name, it seems to work as expected:
$ rust-lldb -o 'break set --file main.rs --line 6' -o run target/debug/foo
...
(lldb) po my_path.inner
"/this/is/a/path"
(lldb) po my_path.inner
"/this/is/a/path"
(lldb) po my_path.inner
"/this/is/a/path"
Meta
I'm using rust-lldb
from a git checkout from yesterday:
$ git rev-parse HEAD
11f32b73e0dc9287e305b5b9980d24aecdc8c17f