lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


2013/12/18 Karol Drożak <karoldro@gmail.com>:
> It works and it is almost good.
> I have a message:
> TRACEBACK test_traceback.lua:6: attempt to call global 'f0' (a nil value)
> stack traceback:
>         test_traceback.lua:6: in function 'f1'
>         test_traceback.lua:14: in function 'f2'
>         test_traceback.lua:19: in function 'f3'
>         test_traceback.lua:23: in function <test_traceback.lua:22>
>
> In the last line I would like to have instead <test_traceback.lua:22>, name
> of the function 'program01'
> TRACEBACK test_traceback.lua:6: attempt to call global 'f0' (a nil value)
> stack traceback:
>         test_traceback.lua:6: in function 'f1'
>         test_traceback.lua:14: in function 'f2'
>         test_traceback.lua:19: in function 'f3'
>         test_traceback.lua:23: in function 'program01'
>
> How to achieve this?

You cannot achieve this if you call program01 from C, because when you
call the function (with lua_pcall) it is on the stack and has no name.

An alternative is to compile a little Lua wrapper that has the name in
it. To do that try the following:

    char buffer[1024];
    size_t size;
    // push debug.traceback on stack
    lua_getglobal(L, "debug");
    lua_getfield(L, -1, "traceback");
    lua_replace(L, -2);
    // generate a one line program with the global function name
    size = snprintf(buffer, sizeof(buffer), "%s()\n", "program01");
    if (luaL_loadbuffer(L, buffer, size, "wrapper")) {
        printf("compilation error: %s\n", lua_tostring(L, -1));
        lua_pop(L, 2); // err msg + traceback fn
        return;
    }
    // call the one line program (which calls the function)
    if (lua_pcall(L, 0, 0, -2)) {
        printf("runtime error: %s\n", lua_tostring(L, -1));
        lua_pop(L, 2); // err msg + traceback fn
        return;
    }
    // cleanup
    lua_pop(L, 1); // traceback fn

You can replace the string "wrapper" with something else, possibly
generated on the fly (like for example "wrapper for program01"). You
can also cache the compiled one-line program to avoid regenerating or
even recompiling it every time, but how to do that well highly depends
on your program architecture.