使用 GDB 调试使用 Rust 1.10 编译的程序时无法在 main 上设置断点 [英] Unable to set a breakpoint on main while debugging a program compiled with Rust 1.10 with GDB
问题描述
我正在尝试解决这个问题:
fn main() {println!("你好{}", 0);}
我尝试过同时编译:cargo build
和 rustc -g -L src/main.rs
然后我运行 gdb target/debug/rust-gdb-test
(或 gdb main
),并尝试在 main
使用 break main
.
(break ::rust-gdb-test::main
返回 Function "::rust-gdb-test" not defined.
).
如果我尝试运行 list
中断(Breakpoint 1, 0x0000555555559610 in main ()
),我得到:
1 dl-debug.c:没有这样的文件或目录.
我正在运行 Rust 1.10.0 (cfcb716cf 2016-07-03)
和 GDB 7.7.1 (Debian 7.7.1+dfsg-5)
.p>
2 年前有人问过 类似问题,但我无法给出解决方案在那里工作.
注意:我好像没有安装GDB了,只有LLDB,不过这个问题的答案是一样的.
你在 Rust 中看到的 main
与编译后的二进制文件中存在的 main
不同.具体来说,两者之间有许多垫片方法.Rust main
实际上包括 crate 名称(在我的示例中为 buggin
)和哈希(在我的示例中为 hfe08615ed561bb88
):
* frame #0: 0x000000010000126d buggin`buggin::main::hfe08615ed561bb88 + 29 at main.rs:2帧 #1: 0x000000010000810e buggin`std::panicking::try::call::hbbf4746cba890ca7 + 30帧 #2:0x000000010000aadc buggin`__rust_try + 12第 3 帧:0x000000010000aa76 错误`__rust_maybe_catch_panic + 38帧 #4: 0x0000000100007f32 buggin`std::rt::lang_start::hbcefdc316c2fbd45 + 562帧#5:0x00000001000013aa buggin`main + 42帧#6:0x00007fff910435ad libdyld.dylib`start + 1第 7 帧:0x00007fff910435ad libdyld.dylib`start + 1
在这里,您可以看到 main
在堆栈中的几帧之外.
我倾向于使用通配符断点来不处理哈希:
(lldb) br set -r 'buggin::main.*'断点 5: where = buggin`buggin::main::hfe08615ed561bb88 + 29,地址 = 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.*'断点 2:67 个位置.
然后您可以运行该程序并继续运行几次,直到找到正确的位置.不要害怕进入那里探索一下;它只是一个调试器!
您可以尝试各种版本的正则表达式,看看是否有任何有趣的匹配:
(lldb) br set -r '.*main::.*'断点 3: where = rust-gdb-test`rust_gdb_test::main::h97d2ac6fea75a245 + 29,(lldb) br set -r '.*::main.*'断点 4: where = rust-gdb-test`rust_gdb_test::main::h97d2ac6fea75a245 + 29,
您还可以从 main
调用一个具有非常独特名称的函数并在其上设置断点:
(lldb) br set -r '.*a_really_unique_name.*'
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.
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.*'
这篇关于使用 GDB 调试使用 Rust 1.10 编译的程序时无法在 main 上设置断点的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!