如何解决如何在异步函数中设置断点?
我有一个带有async
方法的结构,我想对其进行调试。我使用gdb通过调试版本设置了断点。这是停在async
方法Strct::async_method
处的代码的样子:
0x5555557f4a6a <bin::Strct::async_method+26> mov QWORD PTR [rsp+0x10],rsi
0x5555557f4a6f <bin::Strct::async_method+31> mov QWORD PTR [rsp+0x18],rdx
0x5555557f4a74 <bin::Strct::async_method+36> mov BYTE PTR [rsp+0x112],0x0
0x5555557f4a7c <bin::Strct::async_method+44> lea rsi,[rsp+0x10]
0x5555557f4a81 <bin::Strct::async_method+49> mov QWORD PTR [rsp+0x8],rax
0x5555557f4a86 <bin::Strct::async_method+54> call 0x5555557e6970 <core::future::from_generator>
代码调用core::future::from_generator
,这不是我想要调试的。暂停async
方法主体的执行的正确方法是什么?
解决方法
让我们将其用作我们的MRE
use futures::executor; // 0.3.5
pub fn exercise() {
executor::block_on(example());
}
#[inline(never)]
async fn example() {
canary()
}
#[inline(never)]
fn canary() {}
如果您为此查看程序集,则将看到编译器如何实现异步功能。 async
函数返回一个实现impl Future
的类型,该类型在后台由生成器提供动力:
playground::example:
subq $24,%rsp
movb $0,16(%rsp)
movzbl 16(%rsp),%edi
callq *core::future::from_generator@GOTPCREL(%rip)
movb %al,23(%rsp)
movb 23(%rsp),%al
movb %al,8(%rsp)
movb 8(%rsp),%al
addq $24,%rsp
retq
异步函数的实际主体移入了生成器,该生成器恰好使用了名称{{closure}}
:
playground::example::{{closure}}:
;; Lots of instructions removed
movq playground::canary@GOTPCREL(%rip),%rcx
callq *%rcx
jmp .LBB20_2
;; Even more removed
因此,您可以在该生成的函数上设置断点:
(lldb) br set -r '.*example.*closure.*'
(lldb) r
Process 28101 launched: '/tmp/f/target/debug/f' (x86_64)
Process 28101 stopped
* thread #1,queue = 'com.apple.main-thread',stop reason = breakpoint 1.1
frame #0: 0x0000000100000ab0 f`f::example::_$u7b$$u7b$closure$u7d$$u7d$::h2b30ad777e7395f3((null)=(pointer = 0x00007ffeefbff328),(null)=ResumeTy @ 0x00007ffeefbff070) at main.rs:8:20
5 }
6
7 #[inline(never)]
-> 8 async fn example() {
9 canary()
10 }
11
Target 0: (f) stopped.
您还可以在所需的行上设置断点:
(lldb) breakpoint set --file /private/tmp/f/src/main.rs --line 9
(lldb) r
Process 28113 launched: '/tmp/f/target/debug/f' (x86_64)
Process 28113 stopped
* thread #1,stop reason = breakpoint 1.1
frame #0: 0x0000000100000ad8 f`f::example::_$u7b$$u7b$closure$u7d$$u7d$::h2b30ad777e7395f3((null)=(pointer = 0x00007ffeefbff328),(null)=ResumeTy @ 0x00007ffeefbff070) at main.rs:9:5
6
7 #[inline(never)]
8 async fn example() {
-> 9 canary()
10 }
11
12 #[inline(never)]
Target 0: (f) stopped.
另请参阅:
- What is the concrete type of a future returned from `async fn`?
- What is the purpose of async/await in Rust?
- Unable to set a breakpoint on main while debugging a program compiled with Rust 1.10 with GDB
- How to use a debugger like GDB or LLDB to debug a crate in Rust?
- Can I set an LLDB breakpoint when multiple Rust source files share the same name?
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。