[Date Prev][Date Next][Thread Prev][Thread Next]
- Subject: Re: Writing a debugger: line breakpoints
- From: "Dan Posluns" <dposluns@...>
- Date: Thu, 10 Jul 2008 09:23:48 -0700
(Sending this message again with the correct subject header :)
> > I examined the code of lbci and used it to make my own static
> > routine. The requirements for getting all of the line numbers and
> > matching them to names of functions are non-trivial, but it works!
> Could you share your code if it only uses the lbci api?
> > The only thing I don't like about this is that it's tied to the
> > interface of Lua, ie. it is version-dependent and needs access to
> > complete Lua source in order to build. But things could be worse.
> Well, I can promise to keep lbci updated if there's enough interest.
I can share the code, but it's very task-specific and it needs some
extraction from its environment. It doesn't actually use the lbci API;
it just uses the techniques demonstrated in it.
My goal is to create a mapping of valid lines in a source file to a
structure of meta-information (currently only containing a pointer to a
function name). I can then query this map for the nearest valid line of
source to any arbitrary line supplied by the user by calling
const char *functionName;
typedef std::map<int, LineMeta> LineMap;
extern SourceMeta GetSourceMeta(lua_State *L, int stack);
// Implementation details
typedef std::map<int, const char *> FunctionNameMap;
static void RecurseOnPrototype(Proto *p, SourceMeta::LineMap *m,
int lastLine = 0;
// Iterate over the opcodes/set of valid lines
for (int i = 0; i < p->sizelineinfo; i++)
OpCode o = GET_OPCODE(p->code[i]);
int thisLine = p->lineinfo[i];
if (o == OP_SETGLOBAL)
// Store that this line possibly indicates the
start of a function definition
if (lastLine == thisLine)
// We've visited this line already in a previous
// This is a new, valid line of source so create an
entry for it.
// Check to see if the linedefined field matches up to a
global name we've stored off.
FunctionNameMap::iterator itr =
lm.functionName = (itr == fnm->end()) ? NULL :
lastLine = thisLine; // This is the new most-recently
// Process any sub-functions in this definition
for (int i = 0; i < p->sizep; i++)
RecurseOnPrototype(p->p[i], m, fnm);
SourceMeta GetSourceMeta(lua_State *L, int stack)
Proto *p = ((Closure *)lua_topointer(L,
RecurseOnPrototype(p, &result.lineMapping, &fnm);
If you call GetSourceMeta() with your Lua code loaded onto the stack
(eg. by calling luaL_loadbuffer) then it returns the complete mapping of
valid lines to function names.