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 call
和function 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的基准数据。