記一次Lua語言中死循環查錯


前言

如果在Lua語言中某一處死循環了!你特么的怎么去查出這特么的該死的循環到底在特么的哪里!!!

重現步驟

一打開技能界面,整個游戲就卡死不動了

開始排查

查看一下cpu占用率,unity占用60%+,應該是死循環

一開始采取冒煙式查錯法,去一些可疑的地方一個個打斷點(我們有lua調試工具可斷點)。
游戲的大循環,事件派發基層接口,lua調用c#的基層接口等等,都加了很多斷點

可喜的是~~ 完全沒有進來!

要怎么才知道當前運行哪段代碼呢?這個問題讓我想起一個東西
debug.sethook

debug庫提供了一種hook的方式,可以通過注冊一個handler函數,在lua腳本運行到某個調用時,會觸發這個handler,
獲取到相應的執行信息,並且給你一個記錄和數據維護的機會。

它主要有四種事件會觸發這個handler的調用:

  1. 當調用一個lua函數的時候,會觸發call事件
  2. 當函數返回的時候,會觸發一個return事件
  3. 當執行下一行代碼的時候,會觸發一個line事件
  4. 當運行指定數目的指令后,會觸發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會得到浮點數。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM