我希望能夠統計函數在庫中被調用的次數。我有可用庫的C++源,但我沒有使用它的可執行文件的來源。 Gprof接縫是一個流行的工具,但它僅適用於可執行文件。我發現sprof的信息非常有限,在編譯庫並使用「-g」選項鍊接時,它應該解析執行期間收集的配置文件數據。不幸的是sprof無法打開生成的配置文件。我已經幾乎放棄嘗試sprof,因爲它接縫它已經被寫了很久以前,並沒有上演。使用GCC進行分析:獲取共享庫中的函數調用計數
五月的問題是,如果你知道任何工具,與GCC一起,可以計算出呼叫計數?
我希望能夠統計函數在庫中被調用的次數。我有可用庫的C++源,但我沒有使用它的可執行文件的來源。 Gprof接縫是一個流行的工具,但它僅適用於可執行文件。我發現sprof的信息非常有限,在編譯庫並使用「-g」選項鍊接時,它應該解析執行期間收集的配置文件數據。不幸的是sprof無法打開生成的配置文件。我已經幾乎放棄嘗試sprof,因爲它接縫它已經被寫了很久以前,並沒有上演。使用GCC進行分析:獲取共享庫中的函數調用計數
五月的問題是,如果你知道任何工具,與GCC一起,可以計算出呼叫計數?
GCC在最近的版本中有一個編譯器開關-finstrument-functions
,它可以用來讓它自動生成編譯代碼中的跟蹤點鉤子。請參閱手冊中的GCC Code Generation Options。就這樣,你甚至不需要一個完全成熟的攔截,只有一小兩個函數:
__cyg_profile_func_enter()
__cyg_profile_func_exit()
是在進入/退出時自動調用每件使用-finstrument-functions
選項編譯的代碼。
如果你想實際記錄這些調用,你可以簡單地鏈接一個存根庫,它在這種情況下不會做任何事情(只是返回),在普通情況下使用,另一個跟蹤器庫通過LD_PRELOAD
。
請注意,傳遞給這些跟蹤站點鉤子的參數是被調用函數的地址和調用者;給名字,你必須通過符號表查找,這是最好的跟蹤本身。
您可以通過LD_PRELOAD庫很容易地做到這一點。你編寫一個庫來捕獲你正在測試的函數的調用,增加一個計數器,然後調用原始實現(通過隱藏共享對象並調用它)。然後在啓動可執行文件時,LD_PRELOAD攔截器庫,並讓它在_exit(或SIGUSR1或任何時候)發出它的計數。
除了動態庫加載程序之外,此工作方式沒有任何軟件支持,並且是即使在源不可用的情況下也可以間接調用庫調用的常用技術。
您應該可以使用ltrace執行此操作,使用ltrace -c -l yourlibrary
運行程序,或者刪除-l
以獲取所有動態庫調用的計數。
如果它是一個動態鏈接庫(DLL),你只需重新編譯它,這樣它計算並打印出一個數字,遞增每當函數被調用像一個文件或通過網絡
您可以使用systemtap來獲取函數調用計數。它是一個功能強大的工具,它允許您在運行時測試任何應用程序而無需重新編譯它,只需調試所需的符號。
這裏是一個腳本,在納秒計算的呼叫數量的功能,其執行時間沿:
# call-counts.stp
global calls, times
probe process(@1).function(@2) {
times[probefunc()] = gettimeofday_ns()
}
probe process(@1).function(@2).return {
now = gettimeofday_ns()
delta = now - times[probefunc()]
calls[probefunc()] <<< delta
}
這裏是如何用它來調用/lib64/libc-2.12指望getenv()
.2.so運行ls -1
時:
$ sudo stap -c "ls -1" ~/tmp/count-calls.stp /lib64/libc-2.12.2.so getenv
binned_market_data
count-calls.stp
count-calls.stp~
Makefile
md
nohup.out
calls["getenv"] @count=23 @min=4841 @max=19257 @sum=142529 @avg=6196
又如看來電 「海峽*」 功能:
$ sudo stap -c "ls -1" ~/tmp/count-calls.stp /lib64/libc-2.12.2.so "str*"
binned_market_data
count-calls.stp
count-calls.stp~
Makefile
md
nohup.out
calls["__strdup"] @count=14 @min=5035 @max=10664 @sum=80479 @avg=5748
calls["strcoll"] @count=11 @min=11626 @max=20018 @sum=140851 @avg=12804
calls["__strcoll_l"] @count=11 @min=4992 @max=9393 @sum=63179 @avg=5743
calls["strstr_ifunc"] @count=2 @min=4902 @max=7429 @sum=12331 @avg=6165