最近落格輸入法遇到了幾個比較難以復現的問題——關鍵是它不會導致崩潰。這就讓崩潰統計功能根本無效,具體表現為在某些情況下輸入法會突然卡住幾秒,叫人十分惱火。後來我想到,macOS自帶活動管理器中,有個“採樣”功能,可以看到對應進程當前的執行(調用)狀態,那我是不是可以用它來分析錯誤原因呢?
在和用戶溝通後,我得到了一個類似這樣的採樣報告:
1 2 3 4 5 6 7 8 9 10 |
2713 -[IMKSignPostInputController deactivateServer:] (in InputMethodKit) + 326 [0x7fff471f91eb] + 2713 ??? (in LogInputMac2) load address 0x102d32000 + 0x22fb1 [0x102d54fb1] + 2713 ??? (in LogInputMac2) load address 0x102d32000 + 0x22aa3 [0x102d54aa3] + 2713 ??? (in LogInputMac2) load address 0x102d32000 + 0x3b586 [0x102d6d586] + 1774 ??? (in LogInputMac2) load address 0x102d32000 + 0x64a7c [0x102d96a7c] + ! 1774 -[IMKTracingTextInput stringFromRange:actualRange:] (in InputMethodKit) + 197 [0x7fff4714b4e1] + ! 1774 os_activity_apply_f (in libsystem_trace.dylib) + 66 [0x7fff20333811] + ! 1774 __51-[IMKTracingTextInput stringFromRange:actualRange:]_block_invoke (in InputMethodKit) + 94 [0x7fff4714b58a] + ! 1774 __51-[IMKTracingTextInput stringFromRange:actualRange:]_block_invoke_2 (in InputMethodKit) + 70 [0x7fff4714b5f5] + ! 1774 -[IMKLoggingTextInput stringFromRange:actualRange:] (in InputMethodKit) + 192 [0x7fff471d8b76] |
在執行完我程序的代碼後,很快就到了卡住的地方,顯然,應該是我調用的某個 API 觸發了系統的 Bug 之類的,所以我只要能找到具體是哪裡調用的,調用了什麼,應該就很容易定位問題了,具體到這個例子中,就是 1774 ??? (在 LogInputMac2) 代表了什麼。
於是看著後邊的地址,我猜它應該和崩潰記錄差不多,也是需要 dSym 來解析的,只是這一次沒有現成的功能來用了,我們需要手動計算這個地址(當然只是手動調用比較底層的工具罷了,真手算還是不必了)
行為
atos 命令是 Xcode 自帶的,我們使用的各種自動解析崩潰日誌的工具,也都是在它之上進行構建,所以第一步,我們先找到那個對應的 dSym 文件(希望你還找得到)。
得到文件後,我們使用命令來解析它的 uuid,要和採樣數據中的結果一致:
1 2 |
Binary Images: 0x102d32000 - 0x102e79fff +com.logcg.inputmethod.LogInputMac2 (2.4.3 Beta - 2340) <21095D7E-0244-3994-9322-6F4A99BCD198> /Library/Input Methods/LogInputMac2.app/Contents/MacOS/LogInputMac2 |
在採樣數據下方,就是二進制映像,這裡顯示了你程序的版本以及其 uuid。找到對應的 dSym 後,我們用命令 xcrun 矮人轉儲 --烏伊德 LogInputMac2.應用.dSYM/內容/資源/矮人/LogInputMac2 來查看 dSym 中包含的架構和對應的 uuid,比如我的就是:
1 2 3 |
$xcrun dwarfdump --uuid LogInputMac2.app.dSYM/Contents/Resources/DWARF/LogInputMac2 UUID: 21095D7E-0244-3994-9322-6F4A99BCD198 (x86_64) LogInputMac2.app.dSYM/Contents/Resources/DWARF/LogInputMac2 UUID: 77AC203D-8F6F-3486-B1AE-3F3AB539A8A3 (arm64) LogInputMac2.app.dSYM/Contents/Resources/DWARF/LogInputMac2 |
你看,和採樣中對應的就是 x86_64 的那個。
然後我們進入 atos 的交互模式,首先找到你程序的虛擬地址開始點,比如這一行中 2713 ??? (在 LogInputMac2) 加載 地址 0x102d32000 + 0x22aa3 [0x102d54aa3] 我的起始點就是 0x102d32000 你會發現其他行中,這個起始點都是相同的,只有後邊的地址不同,拿到這個起始點後,我們執行命令:
1 |
atos -arch x86_64 -o "LogInputMac2.app.dSYM/Contents/Resources/DWARF/LogInputMac2" -l 0x102d32000 |
這時終端進入了提示符狀態,裡邊什麼都不顯示,然後我們就可以輸入實際地址進行換算了,還是2713這一行,末尾方括號中的地址就是程序運行的實際地址,我們輸入它,atos 就會根據你的 dSym 文件把對應的代碼顯示出來了。
因為是交互模式,你還可以繼續輸入其他地址,不需要重複執行命令:
1 2 3 4 5 6 7 8 9 10 11 |
$atos -arch x86_64 -o "LogInputMac2.app.dSYM/Contents/Resources/DWARF/LogInputMac2" -l 0x102d32000 0x102d54fb1 @objc LogInputController.activateServer(_:) (in LogInputMac2) + 97 0x102d54aa3 LogInputController.deactivateServer(_:) (in LogInputMac2) (<compiler-generated>:0) 0x102d6d586 TouchBarCandidateController.displaySmartHint() (in LogInputMac2) (TouchBarCandidateController.swift:48) 0x102d96a7c IMKTextInput.stringBeforeInput.getter (in LogInputMac2) (EnhancedTextInput.swift:119) 0x102d96a47 IMKTextInput.stringBeforeInput.getter (in LogInputMac2) (EnhancedTextInput.swift:116) |
參考文獻
本文由 落格博客 原創撰寫:落格博客 » macOS 使用 atos 命令解析任意崩潰記錄和採樣數據
轉載請保留出處和原文鏈接:https://www.logcg.com/archives/3475.html