[✔️] lua profile细节逻辑

311 阅读2分钟

lua_Debug的namewhat字段

  • "global":表示该名称是全局变量,在 Lua 中使用 _G 表来存储所有的全局变量。
  • "local":表示该名称是当前函数的局部变量,仅在当前函数内可见。
  • "method":表示该名称是某个表的方法,即该名称所处的函数是一个表的元方法或者其它方法。
  • "field":表示该名称是某个表的字段,即该名称所处的函数是一个表的元素。
  • 空字符串:表示该名称没有任何属性,可能是由于该名称不是一个有效的 Lua 变量或函数。

namewhat的2种属性对应的测试例

local m = {}
function m:test(i) # namewhat=method
    i = 10;
    print("test-abc")
end
function m.testField() # namewhat=field
    print("test-field")

end
return m;

捕获堆栈的关系以及每一层的消耗时间

在我之前的lua profile的实现逻辑中,我只对lua_Debug.what="Lua"的HOOK回调进行了捕获,大部分情况下,都能够得到正确的调用堆栈,因为function callfunction return是成对出现的。

但是总有个别情况,比如以下这个例子:

function getLocalTime()
    pcall(
        function()
            -- return require "socket"
        end
    )
end
getLocalTime()

hook回调值会触发了pcall的function call,虽然pcall是个C函数,但是并没有这个pcall的function return

因为我只关心lua_Debug.what=="Lua",所以这个pcall并没影响我的设计,无非是我无法知道pcall的存在。

我在function call的hook中记录当前的调用函数,在function return的hook回调中,是通过lua_Debug的一些数据,比如what、namewhat、functionName、sourFilePath、lineBegin、lineEnd等作为key,来判断是否为同一个函数,如果相等了,我就认为当前函数的call 和 return是配套的,即函数正确返回了,显然这么做,需要严格配套,很不巧,某些情况就是会出现不配套的调用,导致我的堆栈出现了异常。

hook不配对,除了lua hook的机制导致的,还有一个原因,就是我的function的判定key的生成有问题,当我尝试着将

return require "socket"

取消注释后,运行时我发现有时明明不是同一个函数,竟然key是一样的,本质上还是我的key规则有问题,我需要寻找更有代表性的数据作为key的基准数据。