You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Linux下perf栈回溯跳过函数/显示调用_init的问题求助

perf采样栈回溯错误的排查与解决咨询

环境与测试设置

我编写了一个简单C++程序,使用编译参数-O0 -g -fno-omit-frame-pointer -fno-inline编译,运行环境为Ubuntu系统+Intel 9900K处理器。

全系统采样录制命令如下:

timeout 3 perf record -a -g -F 99 -- ./program
perf script > out.perf && ../FlameGraph/stackcollapse-perf.pl out.perf > out.folded

测试程序代码:

#include <cmath>
#include <cstdlib>
#include <iostream>
#include <cstdint>

double a(double aa) {
  return sqrt(aa);
}

int main() {
  double aa = drand48();
  for (size_t i = 0; i < UINT64_MAX; i++) {
    if (a(aa) == 0) {
      std::cout << std::endl; // 带副作用的操作
    }
  }
  return 0;
}

不同unwind策略下的错误栈回溯

DWARF策略

a_39391_[003]__3819.799248:;__libc_start_call_main;main;__sqrt 91016627
a_39391_[003]__3819.817492:;__libc_start_call_main;main;a 71222327
a_39391_[003]__3819.831741:;__libc_start_call_main;main;__ieee754_sqrt 62644598
a_39391_[003]__3819.844274:;__libc_start_call_main;main;a 58633093

问题:第1、3行显示main直接调用__sqrt/__ieee754_sqrt,跳过了中间的a函数。

LBR策略

a_40294_[000]__4306.958241:;_start;__libc_start_main@@GLIBC_2.34;__libc_start_call_main;main;a;_init 69630243
a_40294_[000]__4306.972230:;_start;__libc_start_main@@GLIBC_2.34;__libc_start_call_main;main 63241775
a_40294_[000]__4306.984884:;_start;__libc_start_main@@GLIBC_2.34;__libc_start_call_main;main;a;_init 59031331
a_40294_[000]__4306.996696:;_start;__libc_start_main@@GLIBC_2.34;__libc_start_call_main;main;a 56209420

问题:倒数第2行显示main调用a后指向_init,而非预期的sqrt。

FP(帧指针)策略

a_40380_[001]__4360.292014:;__libc_start_call_main;a 84184457
a_40380_[001]__4360.308855:;__libc_start_call_main;a 70243465
a_40380_[001]__4360.322906:;__libc_start_call_main;main;__sqrt 63725332

问题:最后一行显示__sqrt,缺失了a函数的调用层级。

代码调用关系验证

反汇编片段证明main确实调用a,a再调用sqrt:

00000000000011c0 <_Z1ad>:
...
    11d2:   e8 59 fe ff ff          call   1030 <sqrt@plt>
...

00000000000011e0 <main>:
...
    1211:   e8 aa ff ff ff          call   11c0 <_Z1ad>

确认函数未被内联或优化为jmp尾调用。

疑问

  1. 如何配置才能获取正确的栈回溯?
  2. 是否是因为perf异步采样时栈正在被修改,导致unwind错误?
  3. Linux下有没有工具能在采样时暂停目标线程,避免栈状态不一致?

内容的提问来源于stack exchange,提问作者meisel

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 09:26:03