[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: Traceback from C.
- From: Jerome Vuarand <jerome.vuarand@...>
- Date: Wed, 18 Dec 2013 15:23:49 +0000
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.