2013-06-21 64 views
5

我很困惑。我不知道oprofile是否可以從分析報告中提供堆棧跟蹤。我一直在閱讀oprofile手冊,它只是通過說they can be logged來引用堆棧跟蹤,但它沒有給出如何這樣做的例子。如何從oprofile輸出獲取callstack?

這裏是我的TEST.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腳本(在虛擬機上的RHEL 6.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    [email protected]@GLIBC_2.2.5   
    5  15.6250 libc-2.12.so    [email protected]@GLIBC_2.2.5 [self] 
------------------------------------------------------------------------------- 
2   6.2500 libc-2.12.so    __strlen_sse42       
    2   6.2500 libc-2.12.so    __strlen_sse42 [self]     
------------------------------------------------------------------------------- 

而且,我的問題:如何獲取堆棧跟蹤以顯示在性能分析報告中?

+1

好問題。這一點文件不是很清楚。這是道歉沒有顯示呼叫計數,這是抽樣不相關。你應該看到100%分爲兩部分。一個是'main:12 - > test:7 - > sleep - >',另一個是'main:12 - > test:8 - > cout :: endl - ><系統IO例程>'' 。我懷疑大部分會在睡夢中。除非你輸出到'stderr',否則我懷疑在'cout <<「。」'中很少。無論如何,這就是GDB中的幾個stackshots會顯示給你的。 –

+0

是的。 GDB比oprofile更有幫助,但我需要在多線程應用程序中使用oprofile,這比我上面編寫的測試腳本大得多。所以,使用GDB不會真的爲我工作。在與他人交談之後,我覺得使用日誌記錄+定時器進行儀表可能會更有意義。 – bitcycle

+0

嗯,這是我會做的:在多線程的情況下,當我打斷它時,每個線程都會暫停,所以我在每個線程上都會得到一個'bt'。那些無所事事的人,比如等待輸入,我忽略了。其他人很有價值。我假設我們的目標是想辦法讓代碼更快,而不是僅僅進行測量。也許這不是你的目標。你可以和其他人交談,但這種技術並不像它應該那樣廣爲人知,所以你知道你可以期望聽到什麼。 –

回答

1

(這是有點晚了,但是這可能幫助別人)

因爲你在定時器模式分析(這是對某些CPU的默認行爲)時,回溯可能被禁用在你的內核中(哪個版本看起來是2.6.32,因爲你在RHEL 6.2上)。

你可以嘗試:

  1. 使用硬件計數器
  2. 在OProfile的內核部分的the history看看,如果確實是你的內核版本的限制,這可能是固定
  3. 更新內核

我面臨着同樣的內核版本相同的問題,但由於我對ARM,我魁ck-fix將不起作用 (this是在這種情況下應用的補丁)。