筆記各種除錯的方式,如斷言、反向除錯等
斷言
斷言(Assertions),在C中assert為macro不是function,使用時需要#include <assert.h>
,
程式出現非預期的數值時則結束程式用於除錯。
以下程式原本square()
預期為i * i
,但返回卻是i * i + 1
,
因此斷言則會在下行判斷並且中斷程式。
#include <stdio.h>
#include <assert.h>
int square(int i) {
return i * i + 1; // assert working
}
int main() {
int i = square(4);
assert(i == 16);
return 0;
}
禁用assert
在#include <assert.h>
之前加上#define NDEBUG
#define NDEBUG
#include <assert.h>
使用時機
- 編寫函數之前
- 程式有錯誤,並且沒有測試項目
參考
反向除錯
回溯記憶體
Effective Debugging 建議熟悉反向除錯的技巧,可以節省除錯步驟增加效率1
而反向除錯實踐技術有重放、反向執行、檢查點等相關2
方式
- 反向執行
- 檢查點、快照
工具
gdb
: record, checkpoint- Qiling Debugger 的
p
指令 - qira debugger
Mozilla rr
: github 用於錄製 執行錯誤的過程。
pacaur -S rr
參見
核心傾印
Core Dump,核心轉儲內容為崩潰程式的記憶體影像1。
coredumpctl
可以查詢相關紀錄
小黃鴨除錯法
透過對小黃鴉代表完全不理解技術的人,解釋程式碼行為而找出錯誤。
相關概念
- 費曼技巧
監視點
監視程式在特定情況時除錯器進行特定行為
- 監視(watch): 特定數值被更改之後暫停
- gdb 的 watch syscall 指令
- 中斷點(breakpoint): 執行到特定指令時暫停
- catch: signal, throw觸發暫停
記憶體檢測工具
- valgrind
自動化除錯腳本
參見 自動化 gdb 腳本
延伸
Debug