DTrace `pid` 提供程序不会触发一些 `return` 探测

Posted

技术标签:

【中文标题】DTrace `pid` 提供程序不会触发一些 `return` 探测【英文标题】:DTrace `pid` provider does not trigger some `return` probes 【发布时间】:2018-04-01 19:18:59 【问题描述】:

我使用的是 OS X Yosemite 10.10.5。我有一个用 Rust 编写的库,我需要测量在库中花费的运行时间。我设置了一些像这样的pid 探针(不是实际的脚本):

pid$target::*parse*:entry



pid$target::*parse*:return



pid$target::*re_match*:entry



pid$target::*re_match*:return


对应的测试代码如下:

let xxx = xxx_of_len(10);
let m = re_match(RE_XXX, &xxx).unwrap();
println!(":?", m);

我的库中re_match函数的实现是:

pub fn re_match(re: &str, s: &str) -> Result<MatchResult, Error> 
    let prog = Compiler::compile(&Parser::parse(re)?)?;
    let mut vm = Vm::new(&prog);
    if vm.run(&s.chars().collect()) 
        return Ok(MatchResult::Match(vm.groups.clone()));
    
    Ok(MatchResult::NotMatch)

问题是,两个return 探针无法触发,而entry 探针正常工作。另外,如果我以同样的方式为Compile::compile 函数设置entryreturn 探针,那么这两个探针都可以工作。

那么这个问题的原因可能是什么,我应该如何解决它?

【问题讨论】:

【参考方案1】:

根据Brendan Gregg's blog post,该问题可能是由编译器优化引起的,其中DTrace 被优化代码混淆,因此无法创建某些return 探针。关闭优化,我们可以在测试程序的Cargo.toml添加如下内容:

[profile.release]
opt-level = 0

完成此操作后,我可以使用命令找到所需的return 探针:

sudo dtrace -l -n 'pid$target:::return' -c './path/to/test/binary'

【讨论】:

以上是关于DTrace `pid` 提供程序不会触发一些 `return` 探测的主要内容,如果未能解决你的问题,请参考以下文章

与命令行相比,来自 C 的 Dtrace 不会产生相同的分析结果

利用DTrace实时检测MySQl

dtrace 将在将来运行的用户进程

DTrace END 探针从不触发

MySQL Query Latency with the DTrace pid Provider

使用单个提供程序名称为插件创建 dtrace 探针