記一次Lua語言中死迴圈查錯
前言
如果在Lua語言中某一處死迴圈了!你特麼的怎麼去查出這特麼的該死的迴圈到底在特麼的哪裡!!!

重現步驟
一開啟技能介面,整個遊戲就卡死不動了
開始排查
檢視一下cpu佔用率,unity佔用60%+,應該是死迴圈
一開始採取冒煙式查錯法,去一些可疑的地方一個個打斷點(我們有lua除錯工具可斷點)。
遊戲的大迴圈,事件派發基層介面,lua呼叫c#的基層介面等等,都加了很多斷點
可喜的是~~ 完全沒有進來!
要怎麼才知道當前執行哪段程式碼呢?這個問題讓我想起一個東西
debug.sethook
debug庫提供了一種hook的方式,可以通過註冊一個handler函式,在lua指令碼執行到某個呼叫時,會觸發這個handler,
獲取到相應的執行資訊,並且給你一個記錄和資料維護的機會。
它主要有四種事件會觸發這個handler的呼叫:
- 當呼叫一個lua函式的時候,會觸發call事件
- 當函式返回的時候,會觸發一個return事件
- 當執行下一行程式碼的時候,會觸發一個line事件
- 當執行指定數目的指令後,會觸發count事件
我們可以通過debug.sethook這個函式來註冊一個hook的handler,他有三個引數:
handler的處理函式,hook事件觸發後被呼叫
描述需要hook的事件型別,call、return和line事件分別對應:’c’, ‘r’, ‘l’,可以互相組合成一個字串
獲取count事件的頻率(可選)
根據這個函式,我可以讓lua每執行一行程式碼,就把它的檔名已經行號輸出到我的日誌檔案中
debug.sethook( function (event, line) WriteLogToFile(debug.getinfo(2).short_src .. ":" .. line) end , "l")
寫好這個工具後,我來到了技能介面前,開啟了hook!然後開啟技能介面!出現吧!死迴圈!
我發現我的日誌檔案,正在以肉眼可見的速度快速增大!
開啟日誌後檢視後,很快就找到了一段死迴圈邏輯!
果然,這個害我加班的BUG, 就是我的寫的!
總結
debug.sethook確實可以幹很多事情,比如基於這個寫一個性能監聽工具,在函式call、return事件觸發時,計算出這個函式的執行時間。
另外這個鍋其實是我們把遊戲從c#語言轉換到lua語言出現的。因為語法不一樣,c#那邊用整形除以整形得到的還是整形,但是lua會得到浮點數。