# Profiling
取自:Brendan Gregg

先概覽一下,右側有顏色的方塊代表在 Linux 的硬體或軟體 Component ,黑字分別是可以用的 tool 去 trace 相關的效能議題。
- 有哪些 tool ?
- perf
- ...
- page faults
- major
- minor
## 視覺化理解
```mermaid
flowchart LR
CPU[🧠 CPU] --> TLB["📘 TLB (快取頁面對應)"]
TLB -->|✔ 命中| Cache["⚡ Cache (L1/L2/L3)"]
Cache -->|✔ 命中| Data[✅ 成功讀資料]
Cache -->|❌ Cache Miss| RAM[🧠 RAM]
RAM -->|→ 更新 Cache| Cache
TLB -->|❌ TLB Miss| PageTable["📄 Page Table (在 RAM)"]
PageTable -->|✔ 有對應頁面| TLBUpdate[📥 更新 TLB]
TLBUpdate --> Cache
PageTable -->|❌ 沒有記錄| PageFault[🚨 Page Fault]
PageFault --> Disk[(💽 Disk / Swap)]
Disk -->|→ 載入頁面至 RAM| RAM
RAM -->|→ 更新頁表 + TLB| TLBUpdate
```
## 虛擬記憶體存取流程圖
```
CPU 存取虛擬地址 VA
│
▼
查 TLB 有無映射(VA → PA)
│
├─✔ 有映射 → 取出實體位址 PA
│ │
│ ▼
│ 查 CPU Cache(L1 → L2 → L3)
│ │
│ ├─✔ 有資料 → Cache Hit ✅(最快)
│ │
│ └─✘ 無資料 → Cache Miss 🚫
│ │
│ ▼
│ 從 RAM 載入資料 → 更新 Cache → 使用
│
└─✘ 無映射 → TLB Miss
│
▼
查頁表有無該頁面資訊
│
├─✔ 有:更新 TLB → 回到查 Cache
│
└─✘ 無:**Page Fault** ⚠
│
通知 OS → 從 Disk/SWAP 載入頁面至 RAM
▼
更新頁表、TLB → 重啟指令 → 查 Cache
```
## Page Fault

- 程式在執行時,嘗試存取一塊目前不在實體記憶體中的虛擬記憶體頁面,導致處理器產生例外中斷,由作業系統處理。
- backgound
- Linux 使用 虛擬記憶體(Virtual Memory):每個進程看到的是獨立的虛擬地址空間
- 作業系統會將虛擬記憶體分割為 一頁一頁(Page),通常是 4KB/頁
- 只有程式實際存取頁面時,才會把它從磁碟載入實體記憶體(lazy loading)
| 類型 | 描述 | 是否正常 |
| ---------------------- | ------------------------------------------------------ | ---------------------- |
| **Minor page fault** | 頁面不在 process 的 page table 中,但已在實體記憶體中(如 shared memory) | ✅ 正常,快速處理 |
| **Major page fault** | 該頁尚未載入,必須從磁碟或 swap 中讀取 | ⚠️ 成本高,會造成延遲 |
| **Invalid (segfault)** | 試圖存取不存在的頁面,或權限錯誤(如寫入唯讀區) | ❌ 系統會發出 `SIGSEGV`,程式當掉 |
## page fault
```
┌────────────────────────────┐
│ User Program │
│ ─────────────────────── │
│ int *p = malloc(4096); │
│ p[0] = 123; ← 觸發頁錯誤│
└────────────┬───────────────┘
│
▼
┌────────────────────────────┐
│ CPU 檢查 Page Table │
│ → 發現該頁不存在(invalid)│
└────────────┬───────────────┘
│
▼
┌────────────────────────────┐
│ 發出 Page Fault 中斷 │
│ → 進入 kernel 模式 │
└────────────┬───────────────┘
│
▼
┌────────────────────────────┐
│ Linux Kernel Page Fault Handler │
│ 檢查: │
│ ─ 這個地址合法嗎? │
│ ─ 有權限存取嗎? │
│ ─ 是否是映射檔案? │
└────────────┬───────────────┘
│
合法 │ 非法(非法記憶體)
│ │
▼ ▼
┌────────────────────────────┐ ┌────────────────────────────┐
│ 從磁碟 / swap 載入該頁面 │ │ 傳送 SIGSEGV,程式崩潰 │
│ 或從 shared memory 拷貝 │ │ Segmentation Fault 錯誤訊息│
└────────────┬───────────────┘ └────────────────────────────┘
│
▼
┌────────────────────────────┐
│ 更新 Page Table(將虛擬頁→實體頁) │
└────────────┬───────────────┘
│
▼
┌────────────────────────────┐
│ 程式重新執行剛才那一行 │
│ 成功寫入 p[0] = 123 │
└────────────────────────────┘
```
- major vs minor
```
┌────────────┐
│ Page Fault │
└────┬───────┘
▼
┌────────────┐
│ 該頁是否已載入? │
└──┬───────────┘
│Yes(在記憶體)
▼
┌──────────────┐
│ Minor Page Fault │
│ → 建立對應 page table│
└──────────────┘
│No(需從磁碟讀取)
▼
┌──────────────┐
│ Major Page Fault │
│ → 讀磁碟 → 分配頁面│
└──────────────┘
```
## page fault vs cache miss
| 項目 | **Page Fault(分頁錯誤)** | **Cache Miss(快取未命中)** |
| ----------- | ------------------------ | --------------------------- |
| **發生時機** | 存取的虛擬頁面尚未載入至主記憶體(RAM) | 存取的資料不在 L1/L2/L3 cache 中 |
| **處理方式** | 由 OS 介入處理,可能從磁碟載入資料至 RAM | 由硬體自動從主記憶體(RAM)載入資料到快取中 |
| **成本(延遲)** | 非常高,若需從磁碟(或 swap)載入頁面 | 中等偏低,取決於從哪層 cache 到 RAM 的距離 |
| **是否中斷程式** | 是,會觸發 exception,由作業系統處理 | 否,通常程式繼續執行,只是稍慢 |
| **發生原因** | 虛擬頁尚未對應至有效的實體記憶體 | 欲讀取的資料未被 cache 命中 |
| **與記憶體的關係** | 涉及虛擬記憶體管理與頁面交換 | 涉及 CPU cache 系統與資料區域性 |
- 直覺理解:
- Cache Miss:像你打開冰箱找牛奶,沒看到 → 去儲藏室(RAM)找到了 → 下次記得先放冰箱。
- Page Fault:你打開冰箱找牛奶,發現牛奶根本沒買 → 出門去超商買回來 → 下次記得先放家裡冰箱。
發生路徑上的關聯:
CPU 想要讀某個位址 → 查 TLB 是否有對應實體頁(若無則 TLB miss)
若頁面尚未載入 RAM → Page Fault
若頁面已在 RAM,接下來查 cache → 若不在 cache → Cache Miss
如果在 cache → Cache Hit(最快)
總結一句話:
Cache Miss 是 CPU 找資料時,快取裡沒命中,需要去 RAM。
Page Fault 是 CPU 找資料時,那頁根本還不在 RAM,需要作業系統把它從磁碟讀進 RAM。
## TLB miss

## TLB



[Introduction to Memory Management in Linux](https://youtu.be/7aONIVSXiJ8)
```mermaid
flowchart TD
subgraph CPU Core
ALU[ALU / AGU<br>產生虛擬位址] --> VA[Virtual Addr]
VA --> TLB{{TLB<br>快取查詢}}
end
TLB -- 命中 --> MEM[👉 實體記憶體存取]
TLB -- 未命中 --> MMU[MMU<br>分頁表走訪]
MMU -- 合法 PTE --> FILL[回填 TLB] --> MEM
MMU -- 不存在 / 權限錯誤 --> PF[⚡ Page Fault]
PF --> OS["OS Page-Fault Handler<br>(核心模式)"]
OS -->|換頁 / 配頁| PTU[更新分頁表<br>+ 刷新 TLB]
PTU --> RET[返回使用者態,重新執行指令]
```
| 項目名稱 | 中文名稱 | 說明 | 常見用途 |
| ------------------ | --------- | --------------------------------------------- | ------------------------ |
| `cycles` | CPU 週期數 | 處理器執行的總時鐘週期數 | 評估程式執行時間(與 CPU 頻率相關) |
| `instructions` | 指令數 | 已執行的 CPU 指令總數 | 搭配 cycles 計算 IPC(每週期指令數) |
| `minor-faults` | 次級缺頁 | 記憶體頁已存在但尚未映射進行處理(無需 I/O) | 分析虛擬記憶體效能 |
| `major-faults` | 重大缺頁 | 缺頁時需從磁碟讀取資料(需進行 I/O) | 檢查是否頻繁觸發記憶體分頁 |
| `dTLB-loads` | 資料 TLB 載入 | 嘗試載入資料的 TLB(Translation Lookaside Buffer)記錄次數 | 檢查記憶體虛實轉換快取的使用狀況 |
| `dTLB-load-misses` | 資料 TLB 失敗 | 資料存取時未命中 TLB,需查詢頁表 | 觀察 TLB 效率,失敗率高表示轉換緩慢 |
| `iTLB-loads` | 指令 TLB 載入 | 嘗試載入指令的 TLB 次數 | 評估程式碼虛擬位址快取命中率 |
| `iTLB-load-misses` | 指令 TLB 失敗 | 指令存取時未命中 TLB,需查詢頁表 | 指令分頁效率分析,常見於大型 binary |
| `page-faults` | 頁面錯誤總數 | 包含 minor 與 major fault 的總數 | 觀察程式在記憶體管理上的負擔 |
| `cache-references` | 快取存取次數 | CPU 對 L1/L2/LLC 等快取的總存取次數 | 衡量快取使用頻繁程度 |
| `cache-misses` | 快取未命中次數 | CPU 存取快取時未命中的次數 | 評估資料/指令是否常被 cache 命中 |
- perf
- sudo perf stat
- sudo perf record -g
-
- TODO
- gprof
| 階段 | 目的 | 常用指令 / 工具 |
| -------------- | ------------------------------ | ------------------------------------------------------------------------------------------------------------------ |
| **快速量化 (粗粒度)** | 先確認 CPU/記憶體/IO 是否飽和,判斷是哪一類瓶頸 | `top`、`htop`、`vmstat`、`iostat`、`dstat` |
| **抽樣分析 (中粒度)** | 找出「最耗時的函式/路徑」 | `perf stat / top / record + report`、`BPFtrace`、`FlameGraph` |
| **精細診斷 (細粒度)** | 深入微架構(Cache、分支、TLB 等)、鎖競爭、系統呼叫 | `perf stat -e ...`、`perf annotate`、`perf c2c / lock`、`ftrace`、`eBPF + BCC/BPFtrace`、`valgrind` (massif/cachegrind) |
perf、ftrace、eBPF、kgdb、kprobes
### Links
- [A Beginner's Guide to Linux Performance Profiling: From First Principles to Flamegraphs](https://hackmd.io/@alanhc/profiling-101)
- gui
- [Profiling CPU and Memory on Linux, with Opensource Graphical Tools - David Faure, KDAB - linux foundation](https://youtu.be/HOR4LiS4uMI)
- [Inspecting and Optimizing Memory Usage in Linux - João Marcos Costa, Bootlin](https://youtu.be/pIR1H7ZyWe4)
- ["Tracing, Profiling & Debugging in Production (eBPF)" - Trent Lloyd (PyCon AU 2019)](https://youtu.be/jXzEzmz-oag)
- [Linux Performance Tools, Brendan Gregg, part 1 of 2](https://youtu.be/FJW8nGV4jxY)
- [Velocity 2017: Performance Analysis Superpowers with Linux eBPF](https://youtu.be/bj3qdEDbCD4?si=bt9DVyikG1jHfmXt)
效能分析的本質是:
> 🔑 效能(Performance)= 有用的工作(Useful Work)÷ 所花的時間(Time)
換句話說:
- 我們的程式到底做了多少有意義的工作?
- 做這些工作的過程中花掉的時間在哪裡?
- 如果慢,到底慢在什麼資源?如何確認?
## 什麼是效能?
效能可以被分解為最根本的三個資源維度:
| 資源類型 | 代表指標 | 第一性原理的根本限制 |
|----------------|-------------------------------|-------------------------------------------|
| **CPU** | 指令數量、IPC、使用率 | CPU 是有限的時脈驅動狀態機,只能每 cycle 做有限工作 |
| **Memory** | cache miss、TLB、page fault | 記憶體存取受到階層結構與時延限制(memory wall) |
| **I/O** | IO wait、latency | 裝置響應時間、佇列設計、吞吐量有限 |
| 資源類型 | 第一性限制(根本物理限制) | 常見瓶頸現象 |
| ------- | ---------------------- | ------------------------------- |
| 🖥️ CPU | 每個 cycle 執行固定數量的指令 | CPU 飽和、IPC 太低 |
| 💾 記憶體 | 存取速度受到階層結構與 latency 限制 | Cache miss、Memory wall、TLB miss |
| 🔄 I/O | 外部裝置存取速度受限於硬體 | I/O wait、device latency |
## 為何要進行效能分析?
在資源限制的前提下,盡可能提升有用工作的比例,減少無效等待或浪費。
## 效能劣化的基本來源有哪些?(來自物理與系統設計限制)
| 基本現象 | 第一性原因解釋 |
|---------------------|----------------------------------------------------------|
| CPU 飽和 | 指令數量過多、無法並行處理、等待其他資源(如記憶體) |
| Cache Miss | 資料位置分散、不符合 spatial/temporal locality |
| Page Fault | 虛擬記憶體機制導致非預期 I/O(memory access latency) |
| Context Switch | 多任務切換導致保存/還原狀態、TLB/cache flush 等 overhead |
| Lock Contention | 多執行緒同時搶奪資源,造成序列化 |
| I/O Bottleneck | 磁碟、網路等裝置 throughput 無法滿足需求 |
## 效能分析的工具選擇與使用時機
| 階段 | 你在問的問題 | 常見工具 | 工具特性 |
| ----------- | ----------------------- | ------------------------------------------- | --------------- |
| ① 基本時間量測 | 程式整體到底花多少時間? | `time`, `hyperfine` | 快速簡單,取得初步效能數據 |
| ② 系統資源使用 | CPU/Memory/I/O 哪個資源是瓶頸? | `top`, `htop`, `vmstat`, `iotop` | 快速定位整體瓶頸資源 |
| ③ CPU 細部分析 | IPC 高嗎?Cycles 浪費在哪? | `perf stat`, `ocperf`, `pmu-tools` | 提供細緻的 CPU 硬體指標 |
| ④ 熱點函式定位 | 哪個函式或程式段落最耗時? | `perf record/report`, `gprof`, `FlameGraph` | 提供函式級別精確定位 |
| ⑤ 函式呼叫關係 | 函式呼叫誰、多少次、每次多久? | `uftrace`, `ltrace` | 清楚展示 call graph |
| ⑥ 記憶體耗用 | 記憶體用多少?峰值在哪裡? | `valgrind massif`, `heaptrack` | 檢查記憶體峰值、leak |
| ⑦ Cache行為分析 | L1/L2 cache有效使用嗎? | `cachegrind`, `callgrind`, `perf c2c` | 展示 Cache 細部效能 |
| ⑧ 低負擔線上追蹤 | Production 可用的長期低成本追蹤? | `eBPF` (`bcc`, `bpftrace`) | 長期觀測,幾乎不影響效能 |
## 整體分析流程(效能分析 Roadmap)
```mermaid
graph LR
A[① 量化整體時間 time/hyperfine] --> B[② 觀察資源使用 top/iotop]
B --> C[③ 深入 CPU 指標 perf stat]
C --> D[④ 熱點函式 perf record + FlameGraph]
D --> E[⑤ 函式呼叫關係 uftrace]
E --> F[⑥ 記憶體峰值 massif]
F --> G[⑦ Cache 行為 cachegrind]
G --> H[⑧ 長期追蹤 eBPF/bpftrace]
```
## 分析流程
1. **觀察輸出行為**
- 為什麼慢?延遲在哪?
- 常用指標:wall-clock time、throughput、latency
2. **建立模型**
- T = CPU Time + Wait Time + I/O Time
- CPU Time = Instructions / IPC × Cycle Time
3. **找出資源瓶頸**
- 工具:perf、uftrace、ftrace、top、iotop、vmstat 等
4. **回推到根本原因**
- 是不是 cache miss?是不是鎖?是不是 syscall?是不是 scheduler 不公平?是不是 memory bandwidth 被佔用?
5. **優化策略根據本質制定**
- 減少 I/O 次數(避免 page fault)
- 減少 thread 間 contention(使用 lock-free 結構)
- 利用資料 locality(避免 cache miss)
- 改寫演算法使得計算時間減少(例如 FFT vs naive DFT)
### perf
#### 用途
`perf` 是 Linux 下用於分析效能瓶頸的核心工具,適用於從系統層級到函式層級的 CPU profiling、cache miss 分析與系統事件統計。
#### 使用時機
- 想知道「哪裡跑得最久」:找出 CPU 熱點與 call graph
- 想知道「整體是否有效率」:透過 `perf stat` 觀察 IPC、cache miss、cycles
- 需要生成火焰圖以視覺化熱點區段時
- 觀察 kernel 與 userspace 混合行為
#### 常見用法
```bash
# 統計整體效能指標(IPC、cache miss 等)
perf stat ./your_program
# 收集 call graph 與 hot spot 分析
perf record -g ./your_program
perf report
# 火焰圖:輸出資料並產生視覺圖形
perf record -F 99 -a -g -- ./your_program
perf script > out.perf
stackcollapse-perf.pl out.perf > out.folded
flamegraph.pl out.folded > flamegraph.svg
```
#### 優點
- 不需修改程式即可進行 profiling
- 支援多種硬體事件(如 instructions、cycles、cache miss)
- 可深入分析 kernel 與 user 空間行為
- 可輸出火焰圖等視覺化工具
#### 缺點
- 有些功能需 root 權限執行
- 精確分析需符號表與 debugging symbols
- 在 container 或 restricted 環境下可能受限
#### 實務建議
- 進行任何優化前,先用 `perf stat` 量化基本效能
- 用 `perf top` 即時觀察熱點,再進行 `perf record` 深入分析
- 建議搭配火焰圖視覺化觀察瓶頸集中區域
- 生產環境建議短時取樣,避免過多 overhead
### ftrace
#### 用途
`ftrace` 是 Linux kernel 內建的 tracing framework,用於追蹤核心行為(context switch、IRQ latency、function call、syscall 等),可幫助系統工程師深入分析排程延遲、系統抖動(jitter)與低階效能問題。
#### 使用時機
- 排查系統異常抖動、長時間卡住的 root cause
- 驅動程式與 kernel module 的效能瓶頸分析
- 觀察 scheduler 運作、task 切換行為
- 和 `perf` 搭配進行全系統觀察
#### 常見用法
```bash
# 啟用 function tracer
sudo echo function > /sys/kernel/debug/tracing/current_tracer
# 過濾特定函式,例如 do_sys_open
sudo echo do_sys_open > /sys/kernel/debug/tracing/set_ftrace_filter
# 啟動與觀察 trace
sudo cat /sys/kernel/debug/tracing/trace
# 清除 trace buffer
sudo echo > /sys/kernel/debug/tracing/trace
```
也可透過 wrapper 工具如 `trace-cmd`、`kernelshark` 提供更佳的使用體驗與 GUI 支援。
#### 優點
- 原生支援於 kernel,無需額外安裝
- 能夠精確觀察 scheduler 與 interrupt 層級活動
- 適合分析 low-latency 系統與 driver
- 支援多種 tracer(function、irqsoff、sched_switch 等)
#### 缺點
- 操作複雜,需要熟悉 debugfs 與 kernel trace 環境
- 輸出資訊可能過於繁雜,需搭配過濾條件使用
- 僅適用於 kernel space,不適合使用者空間 profiling
#### 實務建議
- 若觀察 jitter 或 latency spike,先從 `sched_switch` 分析上下文切換時間
- 可搭配 `trace-cmd report` 彙整更清晰的事件序列
- 驅動或 kernel module 最佳化常需搭配 `ftrace` 佐證
### 火焰圖分析(Flamegraph)
#### 用途
火焰圖是一種視覺化工具,用於顯示 CPU 使用的函式堆疊與時間分佈。它可以幫助你一眼看出哪些函式佔用最多執行時間,適合用於分析 hot path 與瓶頸函式。
#### 使用時機
- 程式效能下降但原因不明
- 想快速定位執行時間集中在哪些函式
- 與團隊溝通效能瓶頸時需要可視化證據
- 對函式調用深度與寬度有整體認知需求
#### 建立流程(以 perf 為例)
##### 安裝工具(以 Ubuntu 為例)
```bash
sudo apt install linux-tools-common linux-tools-$(uname -r) \
git build-essential -y
# 安裝 flamegraph 腳本集
git clone https://github.com/brendangregg/Flamegraph.git
cd Flamegraph
```
##### 收集資料並產出圖表
```bash
# 收集 profile 資料(建議搭配 -F 控制取樣頻率)
perf record -F 99 -a -g -- ./your_program
# 轉換成 stack trace 格式
perf script > out.perf
# 產出 flamegraph 所需格式
./stackcollapse-perf.pl out.perf > out.folded
# 繪製火焰圖
./flamegraph.pl out.folded > flamegraph.svg
```
#### 火焰圖說明
- **橫向長度**:表示總執行時間佔比(越長越慢)
- **縱向堆疊**:表示函式呼叫鏈深度
- **每一條方塊**:表示一個函式,可滑鼠懸停看名稱與時間
#### 優點
- 非常直觀、便於發現效能熱點(hot path)
- 不需修改原始碼,可在已編譯程式上取樣
- 適合大規模應用程式的全域視角效能分析
#### 缺點
- 須搭配 `perf` 或其他 trace 工具收集資料
- 多執行緒與 async 程式容易堆疊混亂,需清理堆疊資料
- 需花時間學習解讀技巧
#### 實務建議
- 可定期在開發週期進行一次火焰圖分析做為基準比較
- 遇到 CPU 使用異常高時優先繪製火焰圖定位
- 可搭配分支、cache miss 事件產生不同維度火焰圖
### valgrind
#### 用途
`valgrind` 是一套動態分析工具,最常用於記憶體錯誤偵測、資源洩漏分析與 cache 效能模擬。
核心工具包含:
- `memcheck`: 偵測未初始化記憶體讀取、非法存取、記憶體洩漏等問題
- `cachegrind`: 分析 cache miss、分支預測命中率
- `callgrind`: 分析函式呼叫次數與執行時間(可搭配 KCachegrind 視覺化)
#### 使用時機
- 開發早期測試記憶體正確性與釋放邏輯
- 找出 segmentation fault 原因
- 想量化不同演算法對 cache 行為的影響(例如排序)
- 搭配 `callgrind` 作為簡易函式 profiling 工具
#### 常見用法
```bash
# 偵測記憶體使用錯誤與洩漏
valgrind --leak-check=full ./your_program
# 偵測未初始化記憶體、越界存取
valgrind --track-origins=yes ./your_program
# 分析 cache 行為
valgrind --tool=cachegrind ./your_program
cg_annotate cachegrind.out.*
# 函式呼叫分析
valgrind --tool=callgrind ./your_program
callgrind_annotate callgrind.out.*
```
#### 優點
- 偵錯能力強,可定位難以重現的記憶體問題
- 可模擬硬體 cache 行為,便於調整資料結構或演算法
- callgrind 與 cachegrind 支援詳細報告與視覺化工具(如 KCachegrind)
#### 缺點
- 執行非常慢,通常為原始速度的 10~50 倍
- 不支援多執行緒間同步錯誤偵測
- 僅支援 x86/x86_64 架構,其他平台相容性差
#### 實務建議
- 開發初期強烈建議整合至測試流程中,提早發現潛藏 bug
- 對效能敏感邏輯(如排序、數值計算)可搭配 `cachegrind` 模擬最佳化潛力
- 呼叫行為分析可導出 callgrind 檔並使用 KCachegrind 互動視覺化分析
### gdb + core dump 分析流程
#### 為何需要?
在生產環境中,程式可能會因為 segmentation fault、abort、assertion fail 等異常崩潰。當你無法重現這些錯誤時,**core dump 是唯一可以還原當下狀態的線索來源**。
使用 `gdb` 搭配 core dump 可以:
- 查看崩潰當下是哪一行程式碼造成的錯誤
- 還原呼叫堆疊(stack trace)與變數內容
- 檢查記憶體狀態與指標有效性
- 協助判斷邏輯錯誤、資源釋放順序等問題
#### 使用時機
- 程式 crash 且無法用 valgrind 或 log 重現時
- 使用者回報錯誤但無法完整還原操作流程時
- CI/CD 環境中需自動收集失敗樣本進行事後分析
#### 如何啟用 core dump?
```bash
# 設定 core dump 開啟與檔案大小(ulimit 預設為 0)
ulimit -c unlimited
# 指定 core 檔儲存路徑(Linux)
echo "/tmp/core.%e.%p" | sudo tee /proc/sys/kernel/core_pattern
```
#### 撰寫可除錯的程式(加上 debug symbol)
```bash
g++ -g -o myprog main.cpp
```
#### 使用 gdb 分析 core dump
```bash
# 假設 myprog 是執行檔,core.12345 是 dump 檔
gdb ./myprog core.12345
# 在 gdb 內常用指令:
(gdb) bt # 顯示 backtrace(函式呼叫堆疊)
(gdb) frame 0 # 切到崩潰當下的堆疊框架
(gdb) info locals # 查看區域變數
(gdb) list # 顯示錯誤行附近原始碼
```
#### 優點
- 還原問題現場,不必重現也能追蹤 root cause
- 可搭配 CI/CD 自動收集並分類 crash case
- 支援多種架構與平台(cross-debug 也可)
#### 缺點
- 需事先保留 core 檔與 debug symbol
- 無法分析邏輯錯誤(只能抓 runtime 異常)
- 不適合即時效能 profiling(但可作為後續定位工具)
#### 實務建議
- 開發階段加入 `-g` 編譯選項與 `INHIBIT_PACKAGE_STRIP = "1"`(如 Yocto)
- 保留執行檔與 core dump,並統一命名便於自動分析
- 可撰寫腳本自動用 gdb 對 core dump 執行 `bt` 並儲存堆疊
## TODO
- vmstat 1
- iostat 1
- network
- netstat -a
- sar
- mpstat 1
- pidstat