skynet 單步調試方案(zbstudio remote debug)

先上效果圖:
在單步調試snax服務的一個函數

skynet 調試難題

skynet 的業務代碼全是用 lua 寫的,其實現在 lua 的調試工具已經很多了,也有很多好用的,但是由於 skynet 是多服務的,每個服務都是一個 lua 虛擬機,成百上千的 lua vm 導致現有的 lua 調試工具都沒法直接使用。

雖然雲風提供了一個簡單的調試控制檯,但實在談不上好用,基於命令行的模式對於用慣各種現代 IDE 調試的我們來說實在無法接受。

這篇文章是雲風對 skynet debug console 的介紹:
在線調試 Lua 代碼
裏面也有云風對於調試的態度:

單步跟蹤調試單個 lua coroutine 的能力。這對許多新手來說是個學走路的柺杖,雖然有人一輩子都扔不掉。

對於新生代的程序員來說,他們從入行開始,使用的就是 VS+VA/Eclipse 等等現代 IDE,也習慣了這種方便的調試方式,沒理由開歷史的倒車,去使用命令行調試吧?

當然不是說命令行調試不好,這也是一個合格的服務端程序必備的技能(查線上問題),但是調試效率就不那麼高了。

工具就只是工具,既然有更高效的工具,能提高生產效率,那沒理由不用是吧,程序員的時間可都是錢啊!

使用 zbstudio 遠程調試單個服務

這裏給出一個使用 zbstudio 調試的方案,該方案可以單步調試 skynet 的 lua 代碼,但是隻能調試單個 lua vm,無法跨服務調試,遇到 skynet.call 可以正確返回結果。

但該方案比較麻煩的是,每次調試之前,都要先用 zbstudio 開啓調試服務器,然後在你要調試的服務開始處增加一段代碼,用來連接調試服務器,整個過程比較繁瑣。

如果調試一些簡短的邏輯,建議還是 print 吧,對於非常大塊的邏輯,比如上千行的大功能,用工具單步調試的效率更高。

具體步驟

1. 下載 zbstudio

下載鏈接:https://studio.zerobrane.com/download?not-this-time)

  • 如果是在 Mac 平臺下開發,只下載個 Mac 版就好。
  • 如果是 Windows 開發,Linux 虛擬機跑,要分別下載 Windows 版和 Linux 版。

爲啥要下兩個呢?

由於 zbstudio 在調試時是一個服戶端的角色,所以本身沒有平臺限制,用哪個都一樣,但是一般我們的開發平臺都是 Windows 的,所以當然也是用 Windows 了。

另一個 skynet 運行平臺的 zbstudio, 比如你的 skynet 跑在 Linux 下,那就下載一個 Linux 版的 zbstudio, 這麼做的原因是爲了提取其中的 *.so 庫。

前面不是說過了在要調試的服務開始處要加一些代碼,用來連接調試服務器麼,這些代碼就要用到這些 *.so 庫。

2. 安裝 zbstudio

  • Windows 下比較簡單了,綠色版的,解壓就可以用,安裝版的也很省事。
  • Linux 版的下載下來是個 *.sh 文件,直接 bash 文件名執行就安裝好了,安裝完進入虛擬機(注意這裏不要在 ssh 裏操作了)桌面,打開終端,輸入 zbstudio 即可啓動。
  • Mac 版下載下來是個 *.dmg 文件,安裝也很簡單。

3. 提取 *.so*.lua 文件

我們用來打開調試服務器的代碼長下面這樣:

local mobdebug = require "mobdebug")
local ip = "192.168.0.100"
local port = 8172 -- 可以不填,默認端口就是8172
mobdebug.start(ip, port)

可見我們就用到這一個 mobdebug.lua 文件,只要把這個文件依賴的所有的 *.so*.lua 文件全部提取出來就可以了。

經過實際測試,只要以下 3 個文件就可以了:
* /opt/zbstudio/bin/linux/x64/clibs53/socket/core.so
* /opt/zbstudio/lualibs/mobdebug/mobdebug.lua
* /opt/zbstudio/lualibs/socket.lua

我們把這三個文件放到工程目錄下,並在 luapath 和 luacpath 里加上它們所在目錄。

4. 修改代碼:在 skynet 服務初始化時連接調試服務器

爲了使用的方便,我們把這些代碼封裝到一個全局函數內,放在 preload 內預先加載到全局空間中。

-- zbstudio remote debug
-- 開啓遠程調試
function startRemoteDebug()
    require("mobdebug").start(dbconf.remotedebug.ip, dbconf.remotedebug.port)
    Log.d(">>Start zbstudio's remote debug.")
end

-- 關閉遠程調試
function stopRemoteDebug()
    require("mobdebug").done()
    Log.d("<<Stop zbstudio's remote debug.")
end

注:由於同一時間只能有一個 mobdebug 連接調試服務器,所以在 startRemoteDebug 函數內,可以加個全局標記,防止多次調用,我這裏偷個懶,先不加。

不加的原因還有一個,就是我們自己調試時,肯定都是隻調一次這個函數,調試完也會習慣性的把這段代碼註釋掉。


好了,現在封裝了開始調試的函數了,讓我們實際用一下吧。

這裏我們用一個 snax 服務舉例:

function init()
     startRemoteDebug()
end

function exit()
    -- 這裏也可以不加,因爲我們調試完一般都會 ctrl+c 強退進程
    -- 反正我是從來不加這句的的,這裏加上只是爲了演示下還有 stop 這種“優雅”的用法,其實對調試來說沒什麼必要
    stopRemoteDebug()
end

-- 在調試完後,不要忘記把這兩個函數註釋掉。

5. 打開 zbstuido 並定位到要調試的 skynet 工程

打開後默認是 zbstudio 自己的目錄,要改成自己工程的目錄。

說來慚愧,當初改這個目錄都改了好久,我覺得不是我搓,而是這個工具太難用:)

方法:
鼠標點中左側工程根目錄處,按F2,填入自己工程的路徑,回車。

6. 開啓 zbstudio 調試服務器

在 zbstudio 主界面中,點擊菜單中的 Project --> Start Debugger Server

7. 下斷點

Ctrl + P 打開要下斷點的文件。

在自己要調試的邏輯處按 Ctrl+F9 下個斷點,僅限你要調試的那個服務,其他的下了斷點也沒用。

8. 開啓你的 skynet 進程

這時如果正常,你應該能在 zbstudio 的 Output 欄看到:
Debugging session started in 'xxxxx'

這就說明已經連上調試服務器了,之後 zbstudio 會斷在調用 startRemoteDebug() 那,這時按F5,就會到你下斷點的地方了。

跨文件 Step into 的方法

在按 F10 Step into 時,如果某個函數在另一個 lua 文件內,這時要先打開那個文件(只要開着就行,在標籤上能看到),再按 F10,才能過去,否則不會過去,這個比較坑,我也是用了一段時間後發現的,之前一直以爲跨文件無法 Step into,其實是可以的!

有了這個技巧後,這個工具纔算是真的好用了起來。

結束語

好了,本教程到此結束,剩下的關於 zbstudio 的功能,自己可以慢慢摸索,它的目錄裏面也有一些不錯的 lua 庫,可以拿來用用。

其實這個 IDE 功能並不多,你看它十幾 MB 的身板,功能也多不了,有個比較好玩的功能是 lua 註釋裏支持 markdown, 簡直要上天=。=

另外,本調試方案最初是 lf723 同學摸索出來的,非常感謝!

END

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章