3

I'm trying to write a debugger for a process running lua scripts, and the documented way of doing so (in C) is to use lua_sethook:

int lua_sethook (lua_State *L, lua_Hook f, int mask, int count);

lua_Hook is defined as:

typedef void (*lua_Hook) (lua_State *L, lua_Debug *ar);

The hook only gets a lua_State pointer, which is great, but how can I associate a pointer to my debugger class with it so that I can get back into my debugger class from there?

I would like to avoid using a global variable in this case as I have multiple lua_State instances. I suppose I could use a map of lua_State * pointers to debugger instances, but that doesn't seem efficient. And storing it as a global in the lua_State * doesn't seem to make sense because in order to be able to retrieve it, I would have to push at least one value onto the lua stack, which seems hard/impossible to do in the case of a lua stack overflow.

Am I missing something? How would I accomplish this? I know, I could accomplish this in lua code, but I would like to understand how I can do this from the C side.

greatwolf
  • 20,287
  • 13
  • 71
  • 105
Tom
  • 653
  • 1
  • 8
  • 15
  • What's the multiplicity relationship between your debugger class and `lua_State`? For example, can we assume for a given `lua_State` there can be at most one debugger class? Can a debugger class be shared between several `lua_State` or does each `lua_State` get its own unique indepedent debugger class? – greatwolf Feb 02 '15 at 01:39
  • In my case it is a 1:1 relationship. The debugger class has the pointer to one lua_State*, and I need to effectively be able to get from the lua_State* to the debugger class in the lua_Hook function somehow. – Tom Feb 02 '15 at 02:56
  • 2
    What about storing it in the lua registry? You'll still have to push it onto the stack in your `hook` function but I'm not sure why you have to worry about it overflowing. Can't you just do a `lua_checkstack` and if it does fail just handle it in your C code? – greatwolf Feb 02 '15 at 03:04
  • I suppose I could do that. For now I am maintaining a map of state pointers to debuggers. It's not ideal, but since all the scripts run in the same thread I can get away without any locks. I was hoping there was a more lightweight solution. – Tom Feb 03 '15 at 03:21

2 Answers2

0

Ultimately, you cannot directly associate a value with a hook function.

But you can indirectly do so in a variety of ways. The safest is probably to put the value in a known location within the Lua registry. You could also make it a global. But however you do it, it needs to be something that can be accessed through the lua_State object.

Using data external to the registered Lua instance is dangerous. That is, you might conceivably have an associative container that maps lua_State pointers to registered instance data. However, if you try this, it may fail if your hook function is called during the execution of a Lua coroutine, since they have separate lua_State objects from the main thread.

Nicol Bolas
  • 449,505
  • 63
  • 781
  • 982
0

I noticed that there's an extra space in lua_State, which you can get it with lua_getextraspace. And it is not touched by Lua itself, according to the manual. By default its size is sizeof(void*). So maybe you can allocate a self-defined structure after lua_newstate, use it in the debug hook, and free it before lua_close by yourself.

Kiritow
  • 1
  • 1