C
列印執行時呼叫的函式的工具?
我正在尋找可以在任一 Unix/Linux 平台上實現的此類工具:
- 我有源文件,我自己編譯了應用程序(原始碼在 C 中,雖然我真的不認為這在這裡很重要)
- 我想在每個函式呼叫都列印/記錄到標準輸出/文件時執行這個應用程序
例如:
#include <stdio.h> int square(int x) { return x*x; } int main(void) { square(2); }
當我執行這個程序時,它會列印出來
- 主要的
- 正方形
我知道
gdb
在某種程度上可以做到這一點,或者valgrind
但他們都沒有完全按照我的意願去做。我只是想知道這樣的工具是否存在?謝謝。
使用
gcov
:$ gcc -O0 --coverage square.c $ ./a.out $ gcov -i square.c $ awk -F '[,:]' '$1 == "function" && $3 > 0 {print $3, $4}' square.c.gcov 1 square 1 main
(其中數字是函式被呼叫的次數(我們跳過部分中從未呼叫過的函式
$3 > 0
)awk
)。這通常用於程式碼覆蓋率(正在測試多少程式碼)。您還可以使用
gprof
程式碼分析工具(通常用於計算在程式碼的各個區域花費了多少時間):$ gcc -O0 -pg square.c $ ./a.out $ gprof -b -P Call graph granularity: each sample hit covers 2 byte(s) no time propagated index % time self children called name 0.00 0.00 1/1 main [7] [1] 0.0 0.00 0.00 1 square [1] ----------------------------------------------- Index by function name [1] square
要讓執行檔在呼叫函式名時列印它們,在 GNU 系統上,您可以使用
gcc
’-finstrument-functions
選項並將dladdr()
地址轉換為函式名。創建一個
instrument.c
喜歡:#define _GNU_SOURCE #include <dlfcn.h> #include <stdlib.h> #include <stdio.h> #define TRACE_FD 3 void __cyg_profile_func_enter (void *, void *) __attribute__((no_instrument_function)); void __cyg_profile_func_enter (void *func, void *caller) { static FILE* trace = NULL; Dl_info info; if (trace == NULL) { trace = fdopen(TRACE_FD, "w"); if (trace == NULL) abort(); setbuf(trace, NULL); } if (dladdr(func, &info)) fprintf (trace, "%p [%s] %s\n", func, info.dli_fname ? info.dli_fname : "?", info.dli_sname ? info.dli_sname : "?"); }
然後將您的執行檔編譯為:
$ gcc -O0 -rdynamic -finstrument-functions square.c instrument.c -ldl $ ./a.out 3>&1 0x400a8f [./a.out] main 0x400a4f [./a.out] square
(這裡使用 fd 3 轉儲函式名稱以使其與 stdout 和 stderr 流分開)。
dli_sname
如果您只想要函式名稱,您可以調整程式碼以僅列印。