16

在 Lua 中,是否有可能知道哪个函数调用了当前函数。

例如

function a()
    get_calling_function()    --Should print function b
end 


function b()
    a() 
end 

这样的事情可能吗?
调试库有这样的功能吗?

4

2 回答 2

29

你可以使用debug.traceback()

function a()
    print(debug.traceback())
end 


function b()
    a() 
end 

b()

这将打印:

堆栈回溯:
    ./test.lua:45: 在函数'a'中
    ./test.lua:50: 在函数'b'中
    ./test.lua:53: 在主块中
    [C]:在?
于 2012-05-31T18:36:34.573 回答
9

您可以使用 debug.sethook() 设置一个挂钩,每次在 lua 中发生某些特殊事件时都会调用该挂钩。它对这样的事情很有用。

local debugInfo = { caller = nil, callee = nil }
function hook()
    local info = debug.getinfo(2)
    if info == nil then
        debugInfo.callee = nil
        return
    end

    -- we only want to watch lua function calls (not C functions)
    if info.what ~= "Lua" then
        debugInfo.callee = "C function"
        return
    end

    debugInfo.caller = debugInfo.callee
    debugInfo.callee = info.name
end


debug.sethook(hook, "c")

function caller1()
    if debugInfo.caller ~= nil and debugInfo.callee ~= nil then
        msg = debugInfo.callee.. " was called by ".. debugInfo.caller.. "!"
        print(msg)
    end
end

function caller2()
    caller1()
end


caller2()

这将打印“caller1 是从 caller2 调用的!”

debug.sethook 可以在第二个参数中处理 3 个不同的字符,因此您可以让它知道何时通知您。'c' 表示每次在 lua 中调用函数时调用你的钩子函数,'r' 表示每次在 lua 中返回函数时调用你的钩子函数,'l' 表示每当 lua 处理新的一行代码时调用你的钩子函数.

如果你真的想的话,你可以设置它来构建你自己的自定义堆栈跟踪,你也可以在你的钩子中使用 debug.getlocal() 甚至尝试计算出哪些参数被传递给你的被调用函数。

为 lhf 编辑。如果您不需要跟踪它并且只需要知道函数调用方式的上下文,这实际上是一种更简单的方法来完成您所要求的操作。

function caller1()
    local current_func = debug.getinfo(1)
    local calling_func = debug.getinfo(2)
    print(current_func.name.. " was called by ".. calling_func.name.. "!")
end

function caller2()
    caller1()
end
于 2012-05-31T18:56:04.957 回答