GNU Profiler,用於分析程序函數調用次數、執行時間佔比、調用關係圖,定位性能熱點。源碼級、無需修改代碼、編譯器集成。
-pg:GCC 在每個函數入口插桩調用 mcount/_mcount/__mcount。ITIMER_PROF 間隔中斷採樣 PC 指針)。atexit 註冊的寫入函數生成 gmon.out。gprof executable gmon.out 生成報告。
# 1. 編譯鏈接加 -pg (編譯和鏈接都要加)
gcc -pg -o myapp main.c utils.c -lm
# 2. 運行程序 (必須正常退出)
./myapp
# 3. 生成 gmon.out 後分析
gprof myapp gmon.out > profile.txt
# 或交互查看
gprof myapp gmon.out | less
| 選項 | 含義 |
|---|---|
-b | 簡潔模式,不輸出字段詳細說明 |
-p | 僅輸出調用圖 |
-q | 僅輸出平坦分析 (函數耗時列表) |
-e func | 排除 func 及其子樹的調用圖 |
-E func | 同 -e,且總時間百分比計算中排除 func 時間 |
-f func | 僅輸出 func 及其子樹的調用圖 |
-F func | 同 -f,且總時間百分比僅計算 func 子樹時間 |
-z | 顯示零調用函數 |
% cumulative self self total
time seconds seconds calls ms/call ms/call name
50.00 0.50 0.50 10000 0.05 0.05 func_a
30.00 0.80 0.30 5000 0.06 0.12 func_b
...
index % time self children called name
0.50 0.00 1/1 main [1]
[2] 50.0 0.50 0.00 1 func_a [2]
0.00 0.00 1/1 func_c [3]
...
[n] 對應索引。
gcc -pg -lc_p -o myapp main.c # 鏈接 libc_p (profiling 版 libc)
#include
#include
void sig_handler(int sig) {
exit(0); // 正常退出觸發 atexit 寫入 gmon.out
}
int main() {
signal(SIGUSR1, sig_handler); // kill -USR1 pid 觸發
signal(SIGINT, sig_handler); // Ctrl+C 觸發
// ... 主循環
}
# 安裝
pip install gprof2dot
apt install graphviz
# 生成調用圖圖片
gprof myapp gmon.out | gprof2dot | dot -Tpng -o callgraph.png
# 生成火焰圖風格
gprof myapp gmon.out | gprof2dot -f prof -n 0.5 | dot -Tpng -o flame.png
gprof 是經典、輕量、標準工具鏈一體的性能分析器,適合快速定位 CPU 熱點函數、調用關係。現代 Linux 開發推薦優先使用 perf (功能更強、無需重編譯、支持硬件計數器),gprof 作為補充或嵌入式無 perf 環境時的備選。