注意:我似乎没有安装 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-lldb 和 rust-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.*'