Skip to content

rust-lldb loses variable definition after printing myvar.inner if breaking on function name #120553

Closed
@n8henrie

Description

@n8henrie

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-debuginfoArea: Debugging information in compiled programs (DWARF, PDB, etc.)C-bugCategory: This is a bug.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions