Question

I working with Keil, MDK-ARM Pro 4.71 for a Cortex-M3 target(STM32F107).

I have compiled the Lua interpreter and a Lua "timer" module that interfaces the chip's timers. I'd like to call a lua function when the timer is elapsed.

Here is a sample use :

t = timer.open()
t.event = function() print("Bing !") end
t:start()

Until here, everything works fine :-) ! I see the "Bing !" message being printed each time the timer elapses.

Now if I use a closure :

t = timer.open()
i = 0
t.event = function() i = i + 1; print(i); end
t:start()

I'm having a bad memory access in the GC after some amount of timer's updates. Since it's an embedded context with very few memory, I may be running out of memory quite fast if there is a leak.

Here is the "t.event" setter (ELIB_TIMER is a C structure representing my timer) :

static int ElibTimerSetEvent(lua_State* L)
{
   ELIB_TIMER* pTimer_X = ElibCheckTimer(L, 1, TRUE);

   if (pTimer_X->LuaFuncKey_i != LUA_REFNIL)
   {
      luaL_unref(L, LUA_REGISTRYINDEX, pTimer_X->LuaFuncKey_i);
      pTimer_X->LuaFuncKey_i = LUA_REFNIL;
   }

   if (!lua_isnil(L, 2))
   {
      pTimer_X->LuaFuncKey_i = luaL_ref(L, LUA_REGISTRYINDEX);
   }

   return 0;
}

And here is the native callback implementation :

static void ElibTimerEventHandler(SYSEVT_HANDLE Event_H)
{
   ELIB_TIMER* pTimer_X = (ELIB_TIMER*)SWLIB_SYSEVT_GetSideData(Event_H);
   lua_State* L = pTimer_X->L;
   int i = lua_gettop(L);
   if (pTimer_X->LuaFuncKey_i != LUA_REFNIL)
   {
      lua_rawgeti(L, LUA_REGISTRYINDEX, pTimer_X->LuaFuncKey_i);
      lua_call(L, 0, 0);
      lua_settop(L, i);
   }
}

This is synchronized externally, so this isn't a synchronization issue.

Am I doing something wrong ?

EDIT

Here is the callstack (with a lua_pcall instead of lua_call, but it is the same). The first line is my hard fault handler.

Lua call stack

Was it helpful?

Solution

I have found the problem ! I ran out of stack (native stack, not Lua) space :p. I guess this specific script was causing a particularly long call stack. After increasing the allocated memory for my native stack, the problem is gone. On the opposite, if I reduce it, I can't even initialize the interpreter.

Many thanks to those who tried to help here.

OTHER TIPS

Found a bug in your C code. You broke the lua stack in static int ElibTimerSetEvent(lua_State* L)

luaL_ref will pop the value on the top of Lua stack: http://www.lua.org/manual/5.2/manual.html#luaL_ref

So you need to copy the value to be refed, before the call to luaL_ref:

lua_pushvalue(L, 2); // push the callback to stack top, and then it will be consumed by luaL_ref()

Please fix this and try again.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top