从C中回调闭包时,在垃圾回收中发生了MemFault。
2013-8-19 12:57:14
收藏:0
阅读:126
评论:2
我正在使用 Keil、MDK-ARM Pro 4.71 为 Cortex-M3 目标(STM32F107)工作。
我已经编译了 Lua 解释器和一个 Lua"计时器"模块,它与芯片的定时器接口。当计时器过期时,我想调用一个 lua 函数。
以下是样例:
t = timer.open()
t.event = function() print("Bing !") end
t:start()
到目前为止,一切正常:-)!每次计时器过期时,我都会看到打印"Bing !"的消息。
现在,如果我使用一个闭包:
t = timer.open()
i = 0
t.event = function() i = i + 1; print(i); end
t:start()
在一些计时器更新后,我会在 GC 中遇到糟糕的内存访问。由于它是一个内嵌的上下文,有非常少的内存,如果存在泄漏,我可能会很快用完内存。
这是"t.event"设置器(ELIB \ _TIMER 是一个表示我的计时器的 C 结构):
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;
}
这是本地回调实现:
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);
}
}
这是在外部同步的,所以这不是同步问题。
我做错了什么吗?
编辑
这是调用栈(使用 lua \ _pcall 而不是 lua \ _call,但它是相同的)。第一行是我硬故障处理程序的。

点赞
用户254057
我解决了问题!我已经用尽了堆栈(原生堆栈,而不是Lua堆栈)空间 :p。
我猜测这个特定的脚本引起了一个非常长的调用堆栈。在增加分配给原生堆栈的内存之后,问题消失了。相反,如果我减少它,我甚至无法初始化解释器。
非常感谢在这里尝试帮助的人们。
2013-08-20 06:59:15
评论区的留言会收到邮件通知哦~
推荐文章
- 如何将两个不同的lua文件合成一个 东西有点长 大佬请耐心看完 我是小白研究几天了都没搞定
- 如何在roblox studio中1:1导入真实世界的地形?
- 求解,lua_resume的第二次调用继续执行协程问题。
- 【上海普陀区】内向猫网络招募【Skynet游戏框架Lua后端程序员】
- SF爱好求教:如何用lua实现游戏内调用数据库函数实现账号密码注册?
- Lua实现网站后台开发
- LUA错误显式返回,社区常见的规约是怎么样的
- lua5.3下载库失败
- 请问如何实现文本框内容和某个网页搜索框内容连接,并把网页输出来的结果反馈到另外一个文本框上
- lua lanes多线程使用
- 一个kv数据库
- openresty 有没有比较轻量的 docker 镜像
- 想问一下,有大佬用过luacurl吗
- 在Lua执行过程中使用Load函数出现问题
- 为什么 neovim 里没有显示一些特殊字符?
- Lua比较两个表的值(不考虑键的顺序)
- 有个lua简单的项目,外包,有意者加微信 liuheng600456详谈,最好在成都
- 如何在 Visual Studio 2022 中运行 Lua 代码?
- addEventListener 返回 nil Lua
- Lua中获取用户配置主目录的跨平台方法
发现你的 C 代码中有一个 bug。你在
static int ElibTimerSetEvent(lua_State* L)中打破了 lua 堆栈。luaL_ref会弹出 Lua 堆栈顶部的值:http://www.lua.org/manual/5.2/manual.html#luaL_ref所以在调用
luaL_ref之前,你需要将被引用的值复制一份:lua_pushvalue(L, 2); // 将回调函数推入栈顶,然后由 luaL_ref() 使用请修复这个问题并重试。