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は、2番目のパラメーターで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 に答える