跳到主要內容

借助 AI 除錯:解決登出時的解密錯誤

 

前言

最近遇到一個有趣的 bug,趁這次機會試試看用 AI 來協助除錯。整個過程蠻有收穫的,分享給大家參考。

問題發現

Bug 描述

在測試登出功能時,發現 app 會發生 crash。追蹤後發現是在登出時,API 會呼叫底層的解密函式,但解密用的 key 明顯有問題,導致解密失敗而引發錯誤。

由於這段流程是另一位同事負責開發的,程式碼邏輯比較複雜,短時間內看不出根本原因。於是先採取防禦性做法:如果 key 為空值,就將解密失敗的錯誤吃掉不處理。判斷後認為這樣不會影響 UI 操作,因為登出後 key 會重新取得。測試後確認沒問題,就先把這個 bug 暫時壓下來了。

深入追查

第一回合:初步分析

趁著有空檔,決定詳細釐清這個問題。想試試 AI 的能耐,於是下了第一個 prompt:

分析 SessionManagerprocessEncryptedData 方法中,為何會發生 bytesToTrim > currentLength 的錯誤?從呼叫該方法的地方分析可能發生的原因。

AI 給出了幾個可能的原因:

  1. 加密數據損壞或截斷

    • 網路傳輸過程中數據包丟失或損壞
    • API 回應中的加密字串不完整
    • 解密後的最後一個字節值異常大
  2. 錯誤的加密算法或密鑰

    • 使用了錯誤的解密密鑰或 IV
    • Session key 交換失敗,但程式繼續使用無效密鑰解密
    • 解密產生亂碼
  3. Hex 字串轉換錯誤

    • 包含非法字符、長度不是偶數、部分缺失等問題
  4. AES CBC 解密失敗但沒有檢查錯誤

    • Whitebox 密鑰準備失敗
    • IV 不匹配
    • 數據長度不符合 AES 塊大小要求
  5. PKCS7 Padding 格式錯誤

    • 加密時使用了錯誤的 padding 方式
    • 最後字節不是有效的 padding 長度值 (1-16)
  6. 多重解密處理錯誤

    • 數據被重複解密或解密順序錯誤
  7. 記憶體緩衝區問題

    • 緩衝區大小分配錯誤或溢出

AI 也分析了呼叫鏈:

API 回應 → DataTransformer → CryptoHandler → decryptSessionKey → processEncryptedData

評估: 這些分析大多是從相關函式內部找錯誤,但沒有太大用處,感覺方向不太對。

第二回合:調整思路

我調整了 prompt 的方向:

登出時會發生此錯誤,從登出後重新呼叫相關 API 的流程來分析原因。

這次 AI 的分析就切中要點了!它指出了幾個關鍵情況:

情況 1:競爭條件(Race Condition)

  • 使用者點擊登出時,可能還有進行中的 API 請求
  • cancelAllRequests() 取消請求,但部分回應可能已經在解密處理中
  • 解密過程使用的是登出前的有效密鑰,但處理的是已被截斷或損壞的回應數據

情況 2:密鑰狀態不一致

  • 登出過程中 sessionManager 狀態可能部分清除
  • 相關的 session 在伺服器端已失效
  • 後續的 API 回應使用失效的加密上下文進行解密

情況 3:網路請求取消時機

  • cancelAllRequests() 執行時,某些請求可能正在接收數據
  • 數據被截斷但仍被傳遞給解密程序
  • hex 字串轉換處理不完整的數據

情況 4:登出 API 回應處理

  • 伺服器可能回傳空內容或錯誤格式的加密數據
  • 解密時觸發 padding 錯誤

具體發生時序:

  1. 使用者點擊登出
  2. logout() 被呼叫
  3. cancelAllRequests() 取消所有進行中請求
  4. 同時執行登出 API 請求
  5. 某個被取消的請求回應仍在處理中
  6. 嘗試解密已損壞/截斷的數據
  7. processEncryptedDatabytesToTrim 計算錯誤
  8. bytesToTrim > currentLength 導致錯誤

可是依照這個分析去修改後,登出後的 UX 出現了問題

第三回合:提供關鍵線索

我 trace code 發現登出後又呼叫了其他 API,這些會被 cancel 影響到。於是給了更具體的線索:

原呼叫 APIClient.logout 的地方會馬上又呼叫其他 API,必須等 cancel 完成後才能再進行其他 API。

這次 AI 給出的修正方案就很完整了:

最終解決方案

修正內容

  1. 修正 APIClient.logout() 為 async 方法

    • 確保登出、取消請求、重置狀態按順序執行
  2. 修正 AppCoordinator.logout() 等待完成

    • 使用 await APIClient.logout() 確保完全結束後再進行後續操作
  3. 修正其他關鍵地方的登出調用

    • LoginViewModelAuthenticationFlow 中的調用都改為 await
  4. 關於 AppContext.logout()

    • MenuViewController 中是通過 Notification 機制觸發
    • 最終會觸發 AppCoordinator 中的 logout 方法
    • 已修正最關鍵的路徑

修正效果

避免競爭條件 - 登出 API 完成後才取消其他請求
確保狀態一致 - 重置加密狀態防止使用失效密鑰
防止重疊 API 調用 - 等待完全取消後才進行後續操作

心得總結:用 AI 修 Bug 的五個要點

經過這次經驗,我整理出使用 AI 輔助除錯的幾個心得:

1. 先分析,不要直接要求修正

一開始不要叫 AI 直接修改程式碼,而是先讓它分析問題。因為分析的方向有可能不對,或者給的線索不夠,它也看不出真正的原因。

2. 確認分析方向後再請求修改

確定 AI 的分析有道理之後,再讓它嘗試修改。這樣可以避免走錯方向浪費時間。

3. 根據測試結果提供更多線索

測試完後,依據測試的狀況給 AI 更多線索。這種迭代式的對話往往能找出真正的問題點。

4. 讓 AI 做總結

可以讓 AI 總結整個修正內容,這對寫 git commit message 或技術文件很有幫助。

5. 適合場景:修別人寫的 Bug

AI 特別適合用來修別人寫的 bug。對於自己寫的程式碼,因為已經很熟悉邏輯,自己修可能還是比較快且正確。但面對不熟悉的程式碼時,AI 可以作為很好的第二雙眼睛。


結語: AI 不是萬能的,但在正確的使用方式下,確實能成為開發者的好幫手。關鍵是要懂得如何引導它,給予適當的上下文和線索。希望這次經驗分享對大家有幫助!

留言

這個網誌中的熱門文章

勝券在握

其實這本書,感覺上寫的有點雜,比上一本講巴非特的書更難懂,兩個講的東西其實是一致的。投資原則便是先選產業,再選公司,慎選時機進場。只買了解的企業是價值投資一貫的原則。價值投資的書大概就先看到這裡了,彼得林區不知道是屬於那一類的,接下來大概會看這部份的書。暫時的目標是把杜金龍介紹的書單看完,真的還不少。接下來的投資會以巴菲特的方法來做,感覺上這比較適合我,練習把漲跌不當一回事,對我而言真的很重要。期權大概不會再玩了,買了以後一直在看漲跌,令人受不了。工作時都不能專心。 就價值投資人而言,真的不需要我們的產品,因為第一點就把我們程式特性打死,不理會股票市場的漲跌,這樣報價功能就沒什麼意義了,價值投資根本不需要技術分析,除非我們能提供相關價值投資的資訊,但我們基本分析真的很爛,看不到什麼資料。有機會我來思考一下價值投資到底要什麼資料,能不能把他寫成一個可運用的程式。 以下是我認為重要的書摘,其實這也只包含最後一章,我認為也只有這章值得做書摘。 巴非特相信使用短期價格來判斷一家公司的成功與否是愚蠢的。取而代之的是,他要公司向他報告因經濟實力成長所獲得的價值,一年一次,他固定檢查幾個變數: 初始的股東權益報酬率。 營運毛利、負債水準與資本支出需求的變化。 該公司的現金產生能力。 如果這些經濟指標正在進展,他知道長期下來,結果會反應在股價上。短期之內,股價所發生的是是不合常理的。 投資策略 不理會股票市場每日的漲跌 不擔心經濟情勢。 買下一家公司,而不是股票 管理企業的投資組合 巴非特原則 企業原則 這家企業是簡單且可以了解的 了解一家企業如何產生利潤的相關經濟活動。 這家企業的營運歷史是否穩定 他必須經得起時間的考驗。 這家企業的長期發展前景是否看好 市場特許權,五力分析 經營原則 經營者是否理性 理性的經營者將只會把多餘的現金,投資在那些產生較資本成本報酬率為高的計畫裡。 經營者對他的股東是誠實坦白的 報告時能知道營業部門如何營業,坦承失敗,了解公司的目的是使股東權益報酬率達到最大。 經營者是會盲從其他法人機構的行為 當心『其他公司也這麼做,一定沒問題』為自己行為辯護的經營者。衡量經營者競爭力的一個方法是,看他們如何運用自己的思考能力以避免依附群眾心理。 財務原則 把重點集中...

10/17部會心得

其實部會一開完,我就想寫了,只是最近沉迷於小說,直到今天才有開始動工的心情。 業務的報告部份就不要講了,一點都不感興趣,講的好像會大賣的樣子,薪水有增加再說啦! 技術方面, DQ 做的功能好像挺有意思的,不過感覺上沒人看出他的價值,不過我覺得最佳的 UI 還是 vs 2005 為主,如果要研發基底的 UI 我覺得要以類 VS 為目標。金融網的東西也令人興奮,我本來就覺得網頁的東西潛力無窮,雖然是抄的,不過覺得還不錯,網頁互抄比 AP 互抄容易多了,很多 AP 的功能要模擬出來,真的比想像中難太多了。雖然金融網聽到最後我睡著了,但我非常期待他下一版能帶來什麼。好吧!說一下我們這邊技術心得,看起來炫,但是我一點都不心動,因為我想不到這東西能增加我們產品的價值嗎? 這場部會最棒的是最後副總的報告,這是第一次瞭解整個產業環境與我們的應對方法,這樣我才清楚為什麼要成立那麼多非資訊本業部門,金融網成立的原因何在,產業鏈垂直整合的價值在哪裡。但是會像如規劃中的成功嗎?其實從旁觀察規劃與現在實際的運作,我抱的期望沒那麼大,不過這是有意思的夢,就看能不能實現囉! 不過在會中,我就想到一個我覺得可以配合上我們的產業架構,而且還不錯的商業模式,這也是我想寫這篇心得的原因。 在副總的報告中,提到金融網是為了提供一個入門的金融資訊,接觸最底層不付費的又想看金融資訊的民眾,其實我想到更進階的是接觸所有上網的人。而這功能結合 43thing 與財務規劃(參考 到底要賺多少錢才能退休呢? )你要作這些你想要做的事情(如遊學、旅遊)或退休,你到底要賺多少錢,然後開始洗腦光靠上班的死薪水是達不成這些目的的,所以要開始投資,投資如何規劃,就是要買我們的金融產品,一步一步引君入彀。這功能主要的對象就不只是想投資的人,而是所有的人,只要你心中有任何的夢想,而這夢想需要錢來達成,就需要這個工具。這就是把基底做的更大,個體經濟學常用的互補效應。所以這功能包含紀錄你要達成的夢想,財務管理包含薪資增加目標、稅務、相關的投資規劃與風險等。目標就是吸引所有人來理財、投資。 另一方面,我想倒也有一些人就是他沒有時間也沒有能力去學如何投資或操作股票,他們只想跟老師聽名牌,那這個就可以結合 blog 的功能來作,吸引一些老師來 blog 建立個人投資說明,開發一個跟單工具,這跟單工具可以比較所...