"Debugging"
- 診斷心法:讀權威狀態,不靠肉眼猜表象
Linux 上一個現象看起來像 A 卻可能是 B、想建立一套先讀權威狀態再下判斷的除錯紀律、避免看畫面就猜而猜錯時回來讀
- 遠端連線與終端機問題
SSH 連線斷掉後本機終端機卡住噴亂碼、遠端打字變亂碼、或想從 SSH 操控遠端圖形桌面卻起不來時,判斷是哪一層出問題並修復
- 機器連不到或起不來
遠端機器突然 SSH 連不上、虛擬機開不了機、或懷疑磁碟滿引發連鎖故障時,從主機側與網路層的權威狀態往下定位是哪一環斷了
- 程序、服務與狀態怎麼判
要判斷一個程式活著沒、某個系統服務現在由誰提供、桌面 session 有沒有被鎖、或終端機多工器的 session 還在不在時,用對的權威來源而不是靠畫面或猜的名字
- 假故障與靜默失效的診斷
自建的 Apps Script 流量統計看起來壞了、或看起來正常但數字不對時,分辨症狀出現的位置與問題所在的位置
- 服務掛了怎麼自動知道:從肉眼盯到主動告警
不想每次都手動 systemctl 檢查服務死活、想讓機器在 service 掛掉時主動推播通知、或擔心整台機器當掉沒人知道時回來讀
- Executions(執行項目)
Apps Script 平台記錄每一次函式執行的時間、耗時與狀態的頁面,用來判斷請求究竟有沒有抵達接收端
- AUR 建置失敗的分層判讀
paru / yay 裝 AUR 套件失敗——helper 自己載入不了、編譯叫不存在的編譯器、makepkg 說架構不符、或 build 跑一半停住時,定位是資源、二進位漂移、烤入路徑還是宣告缺失
- 同一個元件在三種互動狀態下顯示位置不同的 root cause
當元件「跟著狀態飄」、不同互動狀態下出現在不同位置 — 不是元件本身的問題,是它依賴的『定位錨點』本身在動。本文以 scope UI 三狀態飄移為例,展開錨點分析法。
- 從色塊 placeholder 開始的漸進式 UI 除錯
UI 除錯的最小可驗證單位是『一個有顏色的盒子』 — 版型先用色塊確認、內容後填。本文說明為什麼漸進式驗證比一次組裝完整 UI 容易 debug。
- 在開發循環裡早一點用 playwright 看真實結果
靜態 CSS 推理跟視覺截圖溝通有極限 — 當行為與預期不符 ≥ 2 次,stop 推理、改用 playwright browser_evaluate 直接讀 live DOM。本文說明工具引入時機。
- 同方向反覆失敗的轉折點
第 2 次同方向失敗就停下來回報「假設可能錯了、要不要換思路」、不要等第 4 次失敗才被使用者打斷。本文展開失敗計數與方向切換的判斷。
- 驗證方法的選擇時機
靜態 CSS 推理 ≥ 2 次失敗就主動提『啟個 server、用 playwright 看 live DOM 比較快』、不要繼續猜。本文展開驗證工具的引入時機。
- Log 時間真空是 silent hang 訊號、happy log 是 anti-signal
非互動 process(CI / cron / container init)的最後一行 log 是成功訊息、到被 cancel 之間有大段時間無輸出時回來。判讀靠訊息時序的真空、不是最後一行的成功訊息。
- 本機 DNS proxy 插在第一順位時,VPN 的短暫失聯會放大成全機解析故障
git / curl 回 Could not resolve host 而直連 IP 通、或同一個域名時好時壞時,用來定位是整條網路斷了、還是解析路徑上多了一個會單獨失效的本機 DNS proxy
- HMAC 簽章對接:對不上的是輸入定義、用確定性反推它落在哪一端
兩端 HMAC 算不出同一個值時要逐項核對的輸入定義,以及用簽章反推輸入、判斷問題落在哪一端的除錯手法。
- 加書後統計不刷新 — ref.watch 觀察的是 provider 圖、不是資料庫
頁面用了 Riverpod 卻在資料寫入後不更新、或發現自己在導航返回點補 loadData()、用 EventBus 事件觸發 reload 時使用。ref.watch 的 reactive 範圍是 provider 圖上的狀態變化;資料庫寫入不在圖上,補償刷新的出現就是這個缺口的訊號。
- 16 個失敗只有 2 個是缺口 — 大規模測試失敗先分診、再按 ROI 修
測試失敗數超過十個時逐個修是錯的順序:先全數分類根因、再按「單位工時救回的測試數」排修復順序。兩批實戰分類顯示半數失敗是斷言過時而非 bug、九個失敗共用一個 helper 修法;每類的症狀特徵字串可以建成索引讓下批失敗直接對號。
- App 永遠卡在載入畫面 — Riverpod 的 provider 是配方、容器才持有狀態
main() 自建 ProviderContainer 對它觸發初始化、UI 跑在 runApp 的 ProviderScope 裡——兩個容器各持一份 provider 狀態、互不相通,UI 監聽的那份永遠停在初始值。Riverpod 的全域 provider 宣告只是配方、狀態屬於容器實例;跨容器操作是靜默的無效操作。
- 同一個類別被判成兩個型別 — Dart import 的相對路徑與 package 路徑衝突
錯誤訊息出現 LibraryId/*1*/ 與 LibraryId/*2*/、兩行 from 一個指 lib/ 一個指 package:,就是同一個檔案被兩種 URI 匯入——Dart 的 library 身份由匯入 URI 決定、不由檔案決定,相對路徑跨進 lib/ 會製造出平行的型別宇宙。修法是全案統一 package 路徑並用 lint 規則封死。
- 紅燈在量什麼 — 測試訊號的三層失真:斷言、量測、環境
「全套件降至 0」有意義的前置條件是紅燈只反映程式缺陷。三層各自會失真:絕對計時斷言量的是機器負載、compact reporter 高並行下行覆寫產生假陰性、fresh checkout 缺 gitignored 生成產物讓整包結果不可信。含 flaky 判定的取樣門檻與對照實驗定歸因的做法。
- CI step silent hang:時間真空才是訊號、happy log 反而是 anti-signal
CI step 跑很久才 timeout、最後一行卻是「下載 100% / build succeeded」這種 happy log 時回來。判讀:別急著加 timeout,先算最後一行到 cancel 的時間真空、確認是 silent hang,再用症狀詞查 upstream issue。同方向修法連 fail 2 次就是停手回資料層的訊號。
- flutter devices 卡住的訊號:device 數從 N 變 N-1 與 emulator 半活
`flutter devices` / `flutter run` 卡住又印 `Error -2 retrieving device properties` 時回來看。根因是 Android emulator 半活狀態,附恢復順序。
- Dart test 的跨檔案 GetX 狀態污染:flaky 真因不是 fail 訊息上的那個 test
`flutter test` 整套跑隨機 fail、單獨跑該 file 卻 100% 過。根因是 dart test runner 同 process 內 GetX state 跨 file 污染,fail 位置看 `+N -1` 累計而非訊息標示的 test。
- Dart StreamController:single-subscription vs broadcast 的設計選型問題
Dart `Bad state: Stream has already been listened to.` 的根因:預設單訂閱在第二個訂閱者出現時才爆。StreamController vs .broadcast() 修復決策、與 Rx / .obs 的比較。
- Failure Pivot Protocol — 失敗 2 次的轉折協議
requirement-protocol reference:同方向失敗 2 次的轉折協議 — 停下、驗證底層假設、換方向、對外回報模板。
- Progressive Verification — 漸進驗證與最小必要範圍
requirement-protocol reference:placeholder 漸進除錯 + measurement 完整性 + minimum necessary scope 三原則。
- Gradle JVM target 除錯復盤:七個節點的策略權衡
Gradle JVM target 不一致的除錯決策復盤,重點在每步的策略權衡與走過的彎路。
- 為什麼 Bug 在合併後才爆:Gradle Cache 掩蓋潛伏問題的邏輯
feature branch build 正常、合併到 main 後才爆、但合併前 main 也沒錯。根因早已潛伏,Gradle cache 掩蓋、合併只是觸發條件。