Lua - узнать функцию вызова

В Lua можно узнать, какая функция вызвала текущую функцию.

Например

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


function b()
    a() 
end 

Что-то вроде этого возможно?
Имеет ли библиотека отладки такая функциональность?

Ответ 1

Вы можете использовать debug.traceback():

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


function b()
    a() 
end 

b()

который будет печатать:

stack traceback:
    ./test.lua:45: in function 'a'
    ./test.lua:50: in function 'b'
    ./test.lua:53: in main chunk
    [C]: in ?

Ответ 2

вы можете использовать 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" означает вызов вашей функции hook в любое время, когда функция вызывается в lua, "r" означает вызов вашей функции hook каждый раз, когда функция возвращается в lua, а "l" означает вызов вашей функции hook всякий раз, когда 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