如何从opfile输出中获取调用堆栈

How to get a callstack from oprofile output?

本文关键字:获取 调用 堆栈 输出 opfile      更新时间:2023-10-16

我很困惑。我不知道oprofile是否可以从分析报告中提供堆栈跟踪。我一直在复习oprofile手册,它只提到堆叠种族,说它们可以被记录,但它没有给出如何做到这一点的例子。

这是我的测试.cpp

#include <iostream>                              
#include <unistd.h>                              
using namespace std;                             
void test(){                                     
    for (int x = 0; x < 100000; x++) cout << ".";
    sleep(1);                                    
    cout << endl;                                
};                                               
int main(int argv, char** argc){                 
    for (int x = 0; x < 120; x++) test();        
    return 0;                                    
}                                                

这是我用来编译它的命令:

g++ -g -Wall test.cpp -o test

下面是我的perf.sh脚本(在虚拟机中的RHEL6.2上运行):

#!/bin/bash -x
sudo opcontrol --no-vmlinux                                                 
sudo opcontrol --reset                                                      
sudo opcontrol --start --separate=library,thread --image=$HOME/test
sudo opcontrol --callgraph=10                                               
sudo opcontrol --status                                                     
read -p "Press [Enter] key to stop profiling"                                                                       
sudo opcontrol --dump || exit 1                                             
sudo opreport --demangle=smart                                             
              --merge=all                                                  
              --symbols                                                    
              --callgraph                                                  
              --global-percent                                             
              --output-file=perf.out                                        
sudo opcontrol --shutdown                                                   
sudo opcontrol --reset                                                      

这是我现在收到的报告:

CPU: CPU with timer interrupt, speed 0 MHz (estimated)                            
Profiling through timer interrupt                                                 
samples  %        app name                 symbol name                            
-------------------------------------------------------------------------------   
14       43.7500  libstdc++.so.6.0.13      /usr/lib64/libstdc++.so.6.0.13         
  14       43.7500  libstdc++.so.6.0.13      /usr/lib64/libstdc++.so.6.0.13 [self]
-------------------------------------------------------------------------------   
11       34.3750  libc-2.12.so             fwrite                                 
  11       34.3750  libc-2.12.so             fwrite [self]                        
-------------------------------------------------------------------------------   
5        15.6250  libc-2.12.so             _IO_file_xsputn@@GLIBC_2.2.5           
  5        15.6250  libc-2.12.so             _IO_file_xsputn@@GLIBC_2.2.5 [self]  
-------------------------------------------------------------------------------   
2         6.2500  libc-2.12.so             __strlen_sse42                         
  2         6.2500  libc-2.12.so             __strlen_sse42 [self]                
-------------------------------------------------------------------------------   

还有,我的问题是:如何让堆栈跟踪显示在分析报告中?

(这有点晚,但这可能会帮助其他人)

因为您是在定时器模式下进行评测(这是某些CPU上的默认行为),所以在您的内核中可能会禁用回溯(该版本似乎是2.6.32,因为您使用的是RHEL 6.2)。

您可以尝试:

  1. 使用硬件计数器
  2. 看看oprofile内核部分的历史,如果你的内核版本确实有限制,这可能已经解决了
  3. 更新内核

在相同的内核版本中,我也遇到了同样的问题,但由于我使用的是ARM,我的快速修复程序不起作用(这是在这种情况下要应用的修补程序)。