【问题标题】:Unable to set a breakpoint on main while debugging a program compiled with Rust 1.10 with GDB使用 GDB 调试使用 Rust 1.10 编译的程序时无法在 main 上设置断点
【发布时间】:2016-07-16 22:57:50
【问题描述】:

我正在尝试解决这个问题:

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.)。

中断 (Breakpoint 1, 0x0000555555559610 in main ()) 后,如果我尝试运行 list,我得到:

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)

两年前有人问过similar question,但我无法使那里提供的解决方案发挥作用。

【问题讨论】:

  • 在 gdb 中,如果你使用 start 命令,它将在 Rust 主程序的第一行停止,而不是 Rust 提供的“bootstrap main”。

标签: gdb rust


【解决方案1】:

注意:我似乎没有安装 GDB,只安装了 LLDB,但是对于这个问题,答案是一样的。

您在 Rust 中看到的 main 与编译后的二进制文件中存在的 main 不同。具体来说,两者之间有许多垫片方法。 Rust main 实际上包括箱子名称(在我的示例中为 buggin)和哈希(在我的示例中为 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

在这里,您可以看到main 在堆栈中的几帧之外。

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

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

rbreak 应该是 GDB 中的等价物。

一旦程序停止,您应该能够看到源代码。您可能还对 Rust 附带的 rust-lldbrust-gdb 包装器感兴趣并稍微改进了体验。

这和this answer基本一样,只是提到了哈希。

(gdb) rbreak 'rust-gdb-test::main.*'(lldb) br set -r 'rust-gdb-test::main.*' 都没有为我设置任何断点。

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

我原来的方法实际上是这样的:

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

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

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

(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 调用具有非常独特名称的函数并在其上设置断点:

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

【讨论】:

  • (gdb) rbreak 'rust-gdb-test::main.*'(lldb) br set -r 'rust-gdb-test::main.*' 都没有为我设置任何断点。
猜你喜欢
  • 2018-01-19
  • 1970-01-01
  • 2023-04-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多