什麼是 Reverse Debugging#
現代電腦豐富的 RAM 和快速的 CPU 使得反向執行程式成為可能。其原理是讓每條指令記錄它所做的變更,在反向執行時撤銷這些變更。
解決的痛點#
在傳統除錯中,當你到達某個執行點才發現 bug 已經發生了,你只能:
- 從頭重跑程式
- 在更早的地方設 breakpoint
- 期望這次能抓到問題
- 一個不小心 step over 就又錯過了
有了 reverse debugging,你只需要反向執行程式(再往前走)直到找到問題點。
支援 Reverse Debugging 的工具#
- Visual Studio IntelliTrace
- Rogue Wave TotalView ReplayEngine
- Undo Software UndoDB
- gdb — 獨立使用或透過 Eclipse CDT
使用 gdb 的實際操作#
以一個簡單的加總程式為例,gdb 的 reverse debugging 流程:
(gdb) break main
(gdb) run
# 程式停在 main 入口
(gdb) display i
(gdb) display sum
(gdb) break 10 # 在函式最後一行設 breakpoint
(gdb) record # 關鍵:啟動執行記錄
(gdb) cont # 繼續執行到結束此時可以用 reverse 指令回溯:
(gdb) reverse-next # 反向 step over
(gdb) reverse-step # 反向 step into
(gdb) reverse-continue # 反向執行到前一個 breakpoint每執行一次 reverse-next,程式就回退一步,變數值也隨之還原,讓你能觀察 bug 是從哪一步開始出現的。
限制#
Reverse debugging 有以下限制:
- 效能大幅下降 — debugger 在背後做了大量記錄工作
- 記憶體需求高 — 需要儲存每步的變更
- 回溯距離有限 — gdb 預設限制 200,000 條指令
- 副作用無法撤銷 — 已輸出到終端機的字元、已從資料庫刪除的資料不會復原
- 異步事件難以重現 — signal、網路封包等難以在重播時精確複製
儘管有這些限制,reverse debugging 在某些場景下能為你省下數小時的痛苦重複工作。
重點回顧#
- 熟悉你的 debugger 的 reverse debugging 功能,在需要時能派上用場
- 用
record啟動記錄後,就能使用reverse-next、reverse-step、reverse-continue等指令 - 注意其效能與功能限制,將它視為工具箱中的一項特殊武器