使用GDB调试用Rust 1.10编译的程序时,无法在main上设置断点

Unable to set a breakpoint on main while debugging a program compiled with Rust 1.10 with GDB

我正在尝试通过以下步骤:

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

我尝试使用cargo buildrustc -g -L src/main.rs

进行编译

然后运行gdb target/debug/rust-gdb-test(或gdb main),并尝试使用break mainmain上设置断点。

(break ::rust-gdb-test::main返回Function"::rust-gdb-test" not defined.)。

如果尝试运行list,则在打破(Breakpoint 1, 0x0000555555559610 in main ())后,我得到:

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

我正在运行Rust 1.10.0 (cfcb716cf 2016-07-03)和GDB 7.7.1 (Debian 7.7.1+dfsg-5)

2年前曾问过类似的问题,但我无法使此处提出的解决方案起作用。


注意:我似乎不再安装GDB,只安装了LLDB,但是对于这个问题,答案是相同的。

在Rust中看到的main与已编译二进制文件中存在的main不同。具体而言,两者之间有多种填充方法。 Rust main实际上包括板条箱名称(在我的示例中为buggin)和哈希(在我的情况中为hfe08615ed561bb88):

1
2
3
4
5
6
7
8
  * 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

在这里,您可以看到main在堆栈中距离几帧。

我倾向于使用通配符断点来不处理哈希:

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

rbreak在GDB中应该是等效的。

程序一旦停止,您就应该能够看到源代码。您可能还对Rust附带的rust-lldbrust-gdbpackage器感兴趣,并可以改善使用体验。

这基本上与此答案相同,但提到了哈希。

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

连字符(-)不是有效的符号字符。编译后,将转换为下划线。

我最初的方法实际上是这样的:

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

然后可以运行该程序并继续几次,直到找到正确的位置。不要害怕到那里去探索一下;它只是一个调试器!

您可以尝试各种版本的正则表达式,以查看是否有任何有趣的匹配项:

1
2
3
4
(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,

您还可以从main调用一个具有非常独特名称的函数,并在该函数上设置断点:

1
(lldb) br set -r '.*a_really_unique_name.*'