首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

Linux 系統調試技巧大全:strace、objdump、valgrind、kprobe、oprofile 實戰

     編輯:關於C語言

Linux 系統調試技巧大全:strace、objdump、valgrind、kprobe、oprofile 實戰

本文整理自《Debug Hacks》高手調試技術章節,涵蓋用戶態與內核態主流調試工具的核心用法與進階技巧。

1. strace:系統調用跟蹤神器

strace ./prog              # 跟蹤所有系統調用
strace -i ./prog           # 顯示指令指針地址(配合 gdb 斷點)
strace -p PID              # attach 到運行中進程
strace -o trace.log ./prog # 輸出到文件
strace -tt -T ./prog       # 微秒級時間戳 + 耗時統計

核心價值:快速定位「卡在哪個系統調用」、「參數是什麼」、「返回什麼錯誤碼」。

2. objdump:反匯編與源碼對照

objdump -S -l ./prog > asm.txt
# -S: 交織源碼(需 -g 編譯,建議 -O0)
# -l: 顯示源文件行號

注意:優化後指令重排導致行號對應不精確,僅作參考。

3. valgrind:內存錯誤檢測標杆

valgrind --tool=memcheck ./prog  # 默認工具
# 檢測:內存洩漏、非法訪問、未初始化讀取、use-after-free、雙重釋放、棧越界
# 缺點:棧內存檢測弱;運行速度降低 10-50x

4. kprobe / jprobe:內核動態探針

  • kprobe:可插桿任意內核指令地址(函數入口、中間、返回),不重編內核。支持打印棧回溯(dump_stack())。
  • jprobe:僅函數入口,優勢是參數結構與被探測函數完全一致,直接訪問參數無需寄存器/棧推導。
  • kretprobe:函數返回探針,捕獲返回值。

典型用法:內核模塊中註冊 register_kprobe(),處理函數中 printk 關鍵數據。

5. KAHO:用戶態函數熱替換

類似 kprobe 但作用於用戶空間進程,無需重編應用即可替換函數實現,調試大型應用極其強大。

6. SystemTap:腳本化內核追蹤

基於 kprobe 構建,類 DTrace 腳本語言:

probe kernel.function("sys_open") {
    printf("%s(%d) open %s\n", execname(), pid(), filename)
}

功能:棧回溯、內部變量檢測、統計聚合。相當於內核態的 gdb。

7. /proc 文件系統實時洞察

  • /proc/meminfo:實時內存佔用,對比 valgrind 只在結束輸出
  • /proc/<pid>/mem:直接讀取進程內存(需 ptrace 權限),比 gdb 快
  • /proc/<pid>/maps、smaps:虛擬地址空間佈局、各段 RSS/PSS

8. OOM Killer 機制

內存耗盡時,內核對進程評分(oom_score),最高分進程被殺死。可調整 /proc/<pid>/oom_score_adj 保護關鍵進程。

9. 錯誤注入:failmalloc 測試分配失敗路徑

git clone https://github.com/.../failmalloc
make install
LD_PRELOAD=/path/libfailmalloc.so FAILMALLOC_PROBABILITY=0.1 ./prog
# 環境變量控制:
# FAILMALLOC_PROBABILITY=0.5   # 50% 失敗率
# FAILMALLOC_INTERVAL=100      # 每 100 次失敗 1 次
# FAILMALLOC_TIMES=10          # 最多失敗 10 次
# FAILMALLOC_SPACE=1048576     # 1MB 以下分配才可能失敗

10. oprofile:系統級性能分析器

# 初始化
opcontrol --init
# 設置事件:CPU 時鐘采樣,每 10000 周期采樣,不記錄內核
opcontrol --event=CPU_CLK_UNHALTED:10000:0:0:1
opcontrol --start
# 運行程序
./prog
opcontrol --stop
# 查看函數級熱點
opreport --merge=cpu -d ./prog
# 查看源碼級熱點(需 -g 編譯)
opannotate --merge=cpu -s ./prog

實戰輸出示例

vma      samples  %    symbol name
004004c4  226     61.9%  fun
004004f7  139     38.1%  main

# 源碼級註釋
 16  4.3%  : int fun(int s,int i) { /* fun total: 61.9% */ 
 153 41.9%  :     s = s+i;        // 熱點行
  32  8.8%  :     return s;
 126 34.5%  : for(;i<0x10000;i++)  // main 熱點
  13  3.6%  :     sum = fun(sum,i);

虛擬機注意:虛擬機不支持硬件性能計數器事件,需 modprobe oprofile timer=1 使用定時器模式(精度低)。

11. vprobe(未廣泛採用,略)

12. 判斷 x86 CPU 是否支持 64 位

cat /proc/cpuinfo | grep -E 'lm|flags.* lm '
# flags 包含 lm (Long Mode) → 支持 64 位
# 或檢查 CPUID 指令(需內聯彙編)

工具選型速查表

場景首選工具備選
程序崩潰/掛起,定位系統調用stracegdb + core dump
內存洩漏/越界/用後釋放valgrind memcheckAddressSanitizer (ASan)
性能熱點分析(用戶態)perf / oprofilegprof (需 -pg 編譯)
內核函數行為/參數檢測kprobe / SystemTapftrace / bpftrace
實時內存監控/proc/meminfo / smapsvalgrind massif
分配失敗路徑測試failmalloc (LD_PRELOAD)手動注入
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved