Unable to set a breakpoint on main while debugging

2019-07-03 23:18发布

I'm trying to step through this:

fn main() {
    println!("Hello {}", 0);
}

I've tried compiling with both: cargo build and rustc -g -L src/main.rs

I then run gdb target/debug/rust-gdb-test (or gdb main), and try to set a breakpoint on main with break main.

(break ::rust-gdb-test::main returns Function "::rust-gdb-test" not defined.).

After breaking (Breakpoint 1, 0x0000555555559610 in main ()) if I try to run list, I get:

1   dl-debug.c: No such file or directory.

I am running Rust 1.10.0 (cfcb716cf 2016-07-03) and GDB 7.7.1 (Debian 7.7.1+dfsg-5).

A similar question was asked 2 years ago, but I couldn't make the solutions presented there to work.

标签: gdb rust
1条回答
叼着烟拽天下
2楼-- · 2019-07-04 00:13

Note: I seem to not have GDB installed anymore, only LLDB, but for this question the answer is the same.

The main that you see in Rust is not the same main that exists in the compiled binary. Specifically, there are a number of shim methods between the two. The Rust main actually includes the crate name (in my example buggin) and a hash (in my case hfe08615ed561bb88):

  * frame #0: 0x000000010000126d buggin`buggin::main::hfe08615ed561bb88 + 29 at main.rs:2
    frame #1: 0x000000010000810e buggin`std::panicking::try::call::hbbf4746cba890ca7 + 30
    frame #2: 0x000000010000aadc buggin`__rust_try + 12
    frame #3: 0x000000010000aa76 buggin`__rust_maybe_catch_panic + 38
    frame #4: 0x0000000100007f32 buggin`std::rt::lang_start::hbcefdc316c2fbd45 + 562
    frame #5: 0x00000001000013aa buggin`main + 42
    frame #6: 0x00007fff910435ad libdyld.dylib`start + 1
    frame #7: 0x00007fff910435ad libdyld.dylib`start + 1

Here, you can see that main is a few frames away in the stack.

I tend to use a wildcard breakpoint to not deal with the hash:

(lldb) br set -r 'buggin::main.*'
Breakpoint 5: where = buggin`buggin::main::hfe08615ed561bb88 + 29, address = 0x000000010000126d

rbreak should be an equivalent in GDB.

Once the program is stopped, you should be able to see the source. You may also be interested in the rust-lldb and rust-gdb wrappers that ship with Rust and improve the experience a bit.

This is basically the same as this answer, but mentions the hash.

Neither (gdb) rbreak 'rust-gdb-test::main.*' nor (lldb) br set -r 'rust-gdb-test::main.*' set any breakpoints for me.

The hyphen (-) is not a valid symbol character. When compiled, it is converted to an underscore.

My original methodology was actually this:

(lldb) br set -r '.*main.*'
Breakpoint 2: 67 locations.

You can then run the program and continue a few times until you find the right place. Don't be afraid to get in there and explore a bit; it's just a debugger!

You could try various versions of the regex to see if anything interesting might match:

(lldb) br set -r '.*main::.*'
Breakpoint 3: where = rust-gdb-test`rust_gdb_test::main::h97d2ac6fea75a245 + 29,
(lldb) br set -r '.*::main.*'
Breakpoint 4: where = rust-gdb-test`rust_gdb_test::main::h97d2ac6fea75a245 + 29,

You could also call a function with a very unique name from main and set a breakpoint on that:

(lldb) br set -r '.*a_really_unique_name.*'
查看更多
登录 后发表回答