2012-04-18 40 views
7

我正在分析使用linux perf的C++應用程序,並且我使用GProf2dot獲得了一個很好的控制流圖。但是,C庫(libc6-2.13.so)中的一些符號佔用了總時間的大部分時間,但沒有內部邊緣。如何使用linux perf獲取libc6符號的呼叫父母(例如_int_malloc)?

例如:

  • _int_malloc花費的時間爲8%,但沒有通話的父母。
  • __strcmp_sse42__cxxabiv1::__si_class_type_info::__do_dyncast一起走的時候大約10%,並有來電者的名字是0,其中有來電2d6935c2cc748c6,它們沒有來電。

因此,我找不到哪些例程負責所有這些使用perf的mallocing和dynamic casting。然而,看起來其他符號(例如malloc但不是_int_malloc)確實有呼叫父母。

爲什麼不顯示呼叫父母_int_malloc?爲什麼我找不到__do_dyn_cast的最終來電者?而且,有沒有辦法讓我修改我的設置,以便我可以獲取這些信息?我在x86-64上,所以我想知道是否需要帶幀指針的(非標準)libc6。

+0

對MCMC +1,歡迎來到SO。 – 2012-04-20 17:09:37

回答

5

更新:由於3.7.0內核,可以使用perf record -gdwarf <command>確定符號的通話父母在系統庫。

使用-gdwarf,不需要用-fno-omit-frame-pointer進行編譯。

原來的答覆: 是的,有可能會需要使用幀指針(-fno-omit-framepointer)在x86_64,此刻編制了libc6的(2012年5月24日)。

但是,開發人員目前正致力於允許perf工具使用DWARF展開信息。這意味着幀指針不再需要在x86_64上獲取回溯信息。但是,Linus不希望在內核中使用DWARF解卷器。因此,perf工具將在系統運行時保存寄存器,並使用libunwind庫在用戶空間perf工具中執行DWARF展開。

此技術已經過測試,可成功確定(例如)mallocdynamic_cast的呼叫者。但是,補丁集尚未集成到Linux內核中,需要在準備就緒之前進行進一步修訂。

+0

謝謝。在我的機器上需要'--call-graph dwarf'而不是'-gdwarf' – Lack 2017-11-30 01:55:56

1

_int_malloc__do_dyn_cast正在從分析器無法識別的例程中調用,因爲它沒有它們的符號表信息。

更重要的是,它看起來像你顯示自我(獨家)時間。 這隻適用於尋找a)有很多自我時間的例程中的熱點,並且b)您可以修復。

原始unix profil後面的配置文件已創建。真正的軟件由幾乎全部時間用於調用其他功能的函數組成,並且您需要能夠在大部分時間內找到堆棧中的代碼,而不是程序反覆執行。

所以你需要配置perf採取堆棧樣本,並告訴你在你的例程堆棧上的每個的時間百分比。 如果它報告的不僅僅是例程,而且還包含Zoom中的代碼行,它會更好。 最好在掛鐘時間取樣,所以你不會對IO失明。

There's more to say on all this.

+0

謝謝邁克。我有自己的時間和來電時間(我用perf記錄-g來獲取調用堆棧)。我對執行動態強制轉換所花費的時間沒有太多的瞭解(g ++是否將typeinfo與strcmp進行比較),但我打算確保動態強制轉換(以及內存分配)完成。要做到這一點,很高興知道什麼是動態轉換和malloc函數。 – BenRI 2012-04-20 21:48:03

+0

謝謝邁克。我有自己的時間和來電時間(我用perf記錄-g)。顯然,我不能讓malloc或dynamic_cast更快,所以我試圖找到哪些例程調用它們並首先修復最糟糕的犯罪者。我認爲問題在於內核在某些情況下可能無法解開堆棧幀(請注意,並非所有情況下),我很好奇爲什麼內核無法解開堆棧並找到(比如說)__strcmp_sse_42的調用者。我**懷疑**這是用來比較typeinfo對象,但不知道調用者,它很難確定。 – BenRI 2012-04-20 21:56:00

+1

@BenRI:該鏈接討論了我是如何做到這一點的,* [這個鏈接](http://sourceforge.net/projects/randompausedemo/files/)*有一個簡短的幻燈片顯示,獲得大約700x的整體加速比發現並解決了這類問題。 – 2012-04-21 01:28:15