Debugging Principle 期中考考古題 - 解答整理
(依據 3 份 PDF:Debugging Principle、HW Debug、Firmware Debug Principle,並輔以課堂筆記)
========================================================================
Q1. 請建立一套您除錯的完整程序與步驟(PDF1 + PDF3)
------------------------------------------------------------------------
採用「科學方法 (The Scientific Method)」四步驟結合韌體除錯流程:
1. 觀察 (Observation / Reproduce):仔細觀察錯誤現象(輸出錯誤、效能下降),
並找出穩定的重現步驟。
2. 建立假設 (Hypothesis):根據程式碼理解,推論「為什麼會出錯」,假設不是
猜測,而是有根據的推論。
3. 實驗驗證 (Verification):設計最簡單的實驗來證明或推翻假設,使用
print/debug/unittest,一次只驗證一個變量。
4. 結論 (Conclusion):假設成立 → 修復;不成立 → 建立下一個假設。
5. 根除病灶:找到原因後問自己「為什麼這 Bug 會存在?系統設計有什麼漏洞?
其他地方是否有類似隱患?」→ 重構。
Q2. 用 IDE 調試器來觀察內部狀態以除錯,有哪些方法?(PDF1 p.9)
------------------------------------------------------------------------
- 斷點 (Breakpoint):在程式碼某一行插紅旗,執行到這裡會自動暫停。
- 單步執行 (Step Over / Step Into):一行一行執行,觀察邏輯如何跳轉。
- 變量監控 (Watch Variables):即時查看記憶體中變量數值,看在哪個時間點出錯。
- 堆疊追蹤 (Stack Trace):顯示函數調用路徑,知道程式從哪裡跳進這場災難。
關鍵:IDE 調試器是用來「觀察內部狀態」,而非「尋找答案」。
Q3. 小黃鴨除錯法 (Rubber Ducking) 為什麼可以輔助除錯?(PDF1 p.10)
------------------------------------------------------------------------
對著一隻小黃鴨「大聲解釋」程式邏輯,可以觸發大腦的自我糾錯機制:
- 被迫結構化:把想法轉化為語言,大腦會強迫自己重新組織邏輯。
- 打破慣性思維:平時看代碼會「自動略過」以為正確的部分;大聲說「這裡傳入
參數 A」時,可能突然意識到「等一下,傳入的其實是 B!」
- 發現假設錯誤:很多 Bug 源於「我以為程式會這樣跑」,對著鴨子解釋能發現
現實與幻想的差距。
流程:先用小黃鴨釐清邏輯形成假設 → 再用調試器設斷點驗證假設。
關鍵點:工具告訴你「發生了什麼」,大腦告訴你「為什麼」。
Q4. Synchronous and Asynchronous circuits/systems 有什麼不同?
------------------------------------------------------------------------
項目 Synchronous(同步) Asynchronous(非同步)
時脈 所有元件依共同 Clock 動作 無全域 Clock,靠 handshake / 事件驅動
設計難度 簡單、易驗證 複雜,須處理 Race / Hazard
(受 Setup/Hold 限制)
速度 受限於最慢路徑 (worst case) 可達到平均速度 (data-driven)
功耗 Clock 一直翻轉,較高 無事件時無切換,較低
例子 CPU pipeline、DDR、SPI UART、USB握手、Mutex/Semaphore 通訊
Q5. Meta-stability 怎麼會發生? 會造成什麼問題?(筆記 20260413)
------------------------------------------------------------------------
發生原因:
當輸入訊號違反 Setup time 或 Hold time(例如非同步訊號穿越時脈邊緣)時,
正反器 (Flip-Flop) 的輸出會卡在 0 與 1 之間的不確定電壓區,無法在規定時間
內穩定到合法邏輯位準。
造成問題:
- 下游邏輯讀到不確定值,導致狀態機跑飛、資料錯誤。
- 不同接收端可能解讀不同(一個讀 0、一個讀 1),破壞系統一致性。
- 連鎖反應 (propagation):亞穩態傳播至後級會造成系統當機 / 重啟。
- 解法:使用兩級或多級同步器 (synchronizer / double-flop)、加大 MTBF。
Q6. Setup time and Hold time 是指什麼的時間需求?
------------------------------------------------------------------------
對於正反器 (Flip-Flop) 而言,輸入資料 D 相對於 Clock 邊緣的穩定時間要求:
- Setup time(建立時間):在 Clock 上升緣「之前」,資料 D 必須維持穩定的
最短時間。違反 → 資料尚未穩定就被 latch → metastability。
- Hold time(保持時間):在 Clock 上升緣「之後」,資料 D 必須維持穩定的
最短時間。違反 → 資料剛被 latch 就被改寫 → 鎖到錯誤值。
兩者共同決定了同步電路的最高工作頻率與時序裕度 (timing margin)。
Q7. Race Conditions 是怎麼發生的?(PDF3 p.5、PDF1 p.18)
------------------------------------------------------------------------
當多個執行緒/中斷/硬體訊號同時存取共享資源(共用變數、暫存器、記憶體),
且最終結果取決於彼此執行的先後順序時,就會發生競爭條件。
典型場景:
- ISR 與 Main Loop 共用變數:主迴圈讀變數讀到一半被中斷搶走、ISR 改寫後
返回,主迴圈讀到混亂值。
- 多核 / Multi-thread:兩個 thread 同時對同一個 counter 做 read-modify-
write,導致漏加。
- HW Synchronization 不良:跨時脈域訊號未同步。
解法:Critical Section、Atomic Operation(XCHG/SWP/LDREX-STREX)、Mutex、
Semaphore、停中斷。
Q8. 請說明您的 Divide and Conquer 策略如何進行?(PDF3 p.3、PDF1 p.14)
------------------------------------------------------------------------
「分而治之」核心是將一個複雜問題切成獨立、可單獨驗證的小問題,避免多個
變因同時發生:
1. 拆分為獨立模組:把功能模組化(HW / FW / SW;Power / Clock / Reset /
Interface / Function),逐一驗證。
2. Binary Search(二分搜尋):把可疑範圍對半切,確認 Bug 在哪一半,重複
收斂。例如註解掉一半程式 / git bisect。
3. Compare & Swap(比對交換):拿已知 Good 與 Bad 的單元互換,定位故障件。
4. Stress Test(壓力測試):對隔離出的單一模組施加極限條件(高溫、低壓、
高頻),讓潛在 Bug 浮現。
5. HFS 三層切一刀:先判斷是 HW、FW 還是 SW 的鍋(Bottom-up:先看
Power/Clock,再看 Register/ISR,最後才看 Driver/App)。
Q9. Reliable / Accountable / Trustful 的意思?
生意夥伴、青梅竹馬、公司同仁各需哪一個?(筆記 20260316)
------------------------------------------------------------------------
- Reliable(可靠):說到做到、結果穩定可預期,是「能力」與「一致性」層面。
- Accountable(負責):勇於承擔自己職責內的成敗,出錯時不推諉,主動解決
並回報。
- Trustful / Trustworthy(值得信任):在價值觀、誠信上經得起考驗,不會
背後算計。
對應關係(依課堂分享):
- 生意夥伴 → Trustful:金錢利益往來,最怕被算計,誠信信任最重要。
- 青梅竹馬 → Reliable:長期相處的朋友/伴侶,要的是「靠得住、不變心」。
- 公司同仁 → Accountable:團隊合作中,每個人把自己的事做完並負責結果,
專案才能推進。
Q10. UART 是怎麼偵測有資料進來的? 8-bit 資料傳輸中,收發雙方震盪器的誤差
不能超過多少百分比?(PDF2 p.8、PDF3 p.10)
------------------------------------------------------------------------
偵測機制:
1. UART 平時 RxD 線維持 idle 高電位 (1)。
2. 偵測到 1→0 的下降緣 (start bit),啟動接收。
3. 內部 divide-by-16 counter 立刻 reset,以對齊取樣位置。
4. 在第 8 個 BCLK cycle(每個 bit 持續 16 個 BCLK,取中間)做 false start
bit detection;若仍為 0 才確認是 start bit,否則視為雜訊,回到 idle
等下次下降緣。
5. 之後每 16 個 BCLK 在中間取樣 D0~D7、Parity、Stop bit。
震盪器誤差容忍:
一個 frame 共 10 bits(1 Start + 8 Data + 1 Stop)。最後一個 bit 取樣點
累積偏移不能超過 ±0.5 bit(半個 bit 寬),所以誤差 ≤ 0.5 / 10 = 5%(總和),
實務上收發雙方各約 ±2.5%~3% 較安全。
Q11. 蘇格拉底因果論 +「羊毛出在狗身上,豬買單」在 debug 上說出了什麼現象?
(筆記 20260316)
------------------------------------------------------------------------
- 蘇格拉底因果論:「有果必有因」,所有現象皆有其原因。Bug 不會無緣無故
消失或出現,看似靈異現象都是尚未被找到的底層原因。
- 「羊毛出在狗身上,豬買單」:成本/原因與表象/受害者完全不在同一個地方,
看似無關卻環環相扣。
在 Debug 上揭示的現象:
1. 症狀發生處 ≠ Bug 根源處:軟體 crash 可能是底層 Power rail 不穩、看到
亂碼可能是 Clock jitter、SW Race Condition 可能是 HW synchronization
沒做好。
2. 不可只看表象修補(散彈槍式除錯),必須沿因果鏈往下追,否則只是壓制
症狀,下次以另一形式爆發。
3. 整個 HFS 系統是耦合的:HW 不穩 → FW 讀錯 → SW 邏輯崩潰,責任會一路
往上轉嫁;採 Bottom-up 才能找到真正「買單的豬」。
4. 結論:Debug 是一場由下而上的證明題,不是由上而下的猜測題。
Q12. 該如何區分 firmware 與 Software(筆記 20260427:computation vs I/O)
------------------------------------------------------------------------
項目 Firmware Software
執行位置 嵌入式 MCU/SoC,跑在裸機/RTOS 在 OS 之上(Windows/Linux/Android)
儲存 非揮發性記憶體(Flash/ROM), 硬碟/SSD,可隨時安裝、解除安裝、
與裝置綁定,不常更新 版本更新
主要工作 I/O 為主:暫存器讀寫、ISR、 Computation 為主:演算法、資料
控制 GPIO/I2C/SPI、時序控制 處理、UI、商業邏輯
資源 受限(KB 級 RAM、無 MMU、 資源豐富(GB 級 RAM、有 OS 服務)
有 Watchdog)
與 HW 距離 直接接觸硬體,需懂電路、 透過 Driver / API,硬體被抽象隔離
Datasheet、Spec
即時性 多為硬即時 (hard real-time) 一般無嚴格時序要求
例子 BIOS/UEFI、EC、BMC、Sensor Hub、 Office、Chrome、App、遊戲
馬達控制器
判斷簡則:「直接和暫存器、訊號打交道的是 Firmware;跑在 OS 上做
computation 的是 Software」。
Q13. 請舉三個在 debug 過程中常見的錯誤(原題已附答案)
------------------------------------------------------------------------
1. 設計錯誤:bug、腳位設計錯誤
2. 製造錯誤:short、cold solder、元件反向
3. 環境/訊號錯誤:雜訊、電源不穩、熱問題
Q14. 什麼是 Heisenbug?(原題已附答案)
------------------------------------------------------------------------
Heisenbug(海森堡蟲)是指一種在嘗試進行觀察、研究或除錯(Debug)時,會
改變其行為或直接消失的程式錯誤(Bug)。當工程師試圖找出錯誤發生的精確
條件時,它往往無法重現;或者有些 Bug 加上除錯器或加了 Print 就消失(改
變了 Timing)。
Q15. 系統除錯為什麼要用 Bottom-up 的除錯方式? 順序及三階層是哪三個?
(PDF1 p.13–18)
------------------------------------------------------------------------
為什麼要 Bottom-up:
- 建立信任 (Trust):硬體是所有邏輯的物理基礎;HW timing/voltage 不穩,
上面 FW/SW 再怎麼改都是徒勞。
- 隔離變因 (Isolation):訊號若是「不確定 (Indeterminate)」的,上層軟體
邏輯就是一場幻覺。在 Clock 與 Power 穩定之前,討論 FW 邏輯沒意義。
- 減少推諉:HW 怪 FW、FW 怪 SW、SW 怪 HW;逐層遞進的排除法可釐清責任。
- 黃金法則:「物理層未經檢驗,邏輯層皆為虛幻」、「Debug 是由下而上的證明
題,而非由上而下的猜測題」。
三階層(Hardware → Firmware → Software):
Level 1 - Hardware(硬體層)
核心原則:訊號不穩,邏輯必亂
關鍵檢查點:Power Rails 是否乾淨?Clock 是否穩定?Reset 是否確實釋放?
電壓 Min/Max、Rise/Fall time、Overshoot/Undershoot、Jitter/Skew
Level 2 - Firmware(韌體層)
核心原則:溝通橋樑必須暢通;反應必須及時且正確
關鍵檢查點:暫存器讀寫是否符合 Spec?I2C/SPI/PCIe 握手協定是否正確?
ISR 是否被觸發?State Machine 是否卡死?
Level 3 - Software(軟體層)
核心原則:數據解釋必須與底層同步
關鍵檢查點:Driver / API 回傳值是否正確?是否有 Memory Leak、Race
Condition?應用層邏輯是否正確?
口訣:「硬體不穩,軟體就沒有立足之地」、「地基穩了,才能往上蓋」。
========================================================================
(解答整理完畢)











