2011-02-28 31 views
1

我希望能夠統計函數在庫中被調用的次數。我有可用庫的C++源,但我沒有使用它的可執行文件的來源。 Gprof接縫是一個流行的工具,但它僅適用於可執行文件。我發現sprof的信息非常有限,在編譯庫並使用「-g」選項鍊接時,它應該解析執行期間收集的配置文件數據。不幸的是sprof無法打開生成的配置文件。我已經幾乎放棄嘗試sprof,因爲它接縫它已經被寫了很久以前,並沒有上演。使用GCC進行分析:獲取共享庫中的函數調用計數

五月的問題是,如果你知道任何工具,與GCC一起,可以計算出呼叫計數?

回答

3

GCC在最近的版本中有一個編譯器開關-finstrument-functions,它可以用來讓它自動生成編譯代碼中的跟蹤點鉤子。請參閱手冊中的GCC Code Generation Options。就這樣,你甚至不需要一個完全成熟的攔截,只有一小兩個函數:

  • __cyg_profile_func_enter()
  • __cyg_profile_func_exit()

是在進入/退出時自動調用每件使用-finstrument-functions選項編譯的代碼。
如果你想實際記錄這些調用,你可以簡單地鏈接一個存根庫,它在這種情況下不會做任何事情(只是返回),在普通情況下使用,另一個跟蹤器庫通過LD_PRELOAD

請注意,傳遞給這些跟蹤站點鉤子的參數是被調用函數的地址和調用者;給名字,你必須通過符號表查找,這是最好的跟蹤本身。

示例代碼(只是一個快速谷歌,真的):here,herehere

0

您可以通過LD_PRELOAD庫很容易地做到這一點。你編寫一個庫來捕獲你正在測試的函數的調用,增加一個計數器,然後調用原始實現(通過隱藏共享對象並調用它)。然後在啓動可執行文件時,LD_PRELOAD攔截器庫,並讓它在_exit(或SIGUSR1或任何時候)發出它的計數。

除了動態庫加載程序之外,此工作方式沒有任何軟件支持,並且是即使在源不可用的情況下也可以間接調用庫調用的常用技術。

1

您應該可以使用ltrace執行此操作,使用ltrace -c -l yourlibrary運行程序,或者刪除-l以獲取所有動態庫調用的計數。

0

如果它是一個動態鏈接庫(DLL),你只需重新編譯它,這樣它計算並打印出一個數字,遞增每當函數被調用像一個文件或通過網絡

0

您可以使用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