[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: tracing Lua API calls
- From: Luiz Henrique de Figueiredo <lhf@...>
- Date: Thu, 23 Mar 2000 11:20:59 -0300
Lua API errors are hard to find without a debugger.
Here is something that might help. I'm posting this to ask people whether this
is useful and if so how it can be improved.
If you find it useful, I'll probably write a LTN about this.
The Lua program at the end of the message reads lua.h and outputs two files,
t.c and t.h.
The file t.c contains a set of wrappers to the API. Here is a typical wrapper:
int Lua_callfunction (lua_Object f,
const char* _FILE, int _LINE, const char* _FUNC) {
int rc;
Lua_tracein("lua_callfunction",_FILE,_LINE,_FUNC);
rc=lua_callfunction(f);
Lua_traceout("lua_callfunction",_FILE,_LINE,_FUNC);
return rc;
}
The file t.h redefines all calls to the official API to go through the wrapper.
Here is the entry for lua_callfunction in t.h:
int Lua_callfunction (lua_Object f,
const char* _FILE, int _LINE, const char* _FUNC);
#define lua_callfunction(f) \
Lua_callfunction(f,__FILE__,__LINE__,__FUNCTION__)
If you're not using gcc, then do
#ifndef __GNUC__
#define __FUNCTION__ ""
#endif
or change the Lua program below.
You have to write your own Lua_tracein and Lua_traceout.
Here is a simple implementation, which generates a lot of output.
void Lua_tracein(char* func, char* file, int line, char* parent)
{
fprintf(stderr,"lua_trace: { %s:%d [%s] %s\n",file,line,parent,func);
}
void Lua_traceout(char* func, char* file, int line, char* parent)
{
fprintf(stderr,"lua_trace: } %s:%d [%s] %s\n",file,line,parent,func);
}
Another possibility would be to save the args to Lua_tracein into static
variables that are output when an error happens. You can do this by registering
a function with atexit.
Comments welcome.
--lhf
-- make APi wrappers: lua thisfile.lua <lua.h
$debug
function bodyC(l,t,f,p,a,A)
write(t," Lua_",f," (",p,A,") {\n")
if t~="void" then write(" ",t," rc;\n") end
write(" Lua_tracein(\"lua_",f,"\",_FILE,_LINE,_FUNC);\n")
if t~="void" then write(" rc=") else write(" ") end
write("lua_",f,"(",a,");\n")
write(" Lua_traceout(\"lua_",f,"\",_FILE,_LINE,_FUNC);\n")
if t~="void" then write(" return rc;\n") end
write("}\n\n")
end
function bodyH(l,t,f,p,a,A)
write(t," Lua_",f," (",p,A,");\n\n")
A="__FILE__,__LINE__,__FUNCTION__"
if p~="" then A=","..A end
write("#define\tlua_",f,"(",a,") \\\n\tLua_",f,"(",a,A,")\n\n\n")
end
function header(o,e,v)
_OUTPUT=o
write("/* luatrace.",e," -- automatically extracted from lua.h (",v,") */\n\n")
end
function body(l)
l=gsub(l,"[\n\t ]+"," ")
l=gsub(l," %*","* ")
local a,b,t,f,p=strfind(l,"(.*) lua_(%w+) %((.*)%)")
if a==nil or f=="newstate" then return end
A="const char* _FILE, int _LINE, const char* _FUNC"
if p=="void" then
p=""
a=""
else
a=gsub(p..",","%s*.-%s*(%w+),","%1,")
a=gsub(a,",$","")
A=",\n\t"..A
end
_OUTPUT=C_OUT bodyC(l,t,f,p,a,A)
_OUTPUT=H_OUT bodyH(l,t,f,p,a,A)
end
C_OUT=openfile("t.c","w")
H_OUT=openfile("t.h","w")
local T=read"*a"
local _,_,v=strfind(T,'LUA_VERSION.-"Lua.- (.-)"')
header(C_OUT,"c",v)
header(H_OUT,"h",v)
gsub(T,'\n([^\n]-%b());',body)