Lua: 这可能导致 segfault 吗?
2014-9-3 14:12:5
收藏:0
阅读:89
评论:2
我正在开发一个使用Lua脚本的程序,有时会崩溃。使用GDB,我认为我找到了问题,但我不知道它是否已经解决,因为段错误只会偶尔发生。所以,旧代码是这样的:
void Call(std::string func){
lua_getglobal(L, func.c_str()); //这是GDB在回溯中提到的行
if( lua_isfunction(L,lua_gettop(L)) ) {
int err = lua_pcall(L, 0, 0,0 );
if(err != 0){
std::cout << "Lua error: " << luaL_checkstring(L, -1) << std::endl;
}
}
}
问题在于,这个函数在每秒钟调用几次,但它需要调用的函数并不总是被定义,所以我认为堆栈会溢出。我添加了以下行:
lua_pop(L,lua_gettop(L));
自那以后,段错误就没有再出现了。这可能是问题吗?
点赞
用户2128694
使用 lua_gettop(L) 作为 lua_pop 的参数将清除整个 Lua API 栈(相当于lua_settop(0)),这可能不是您想要的。但是,确实存在您的问题,即 lua_getglobal 总是会推送一些内容;如果给定名称的全局变量不存在,则它将压入 nil,就像等效的 Lua 表达式一样。但是,lua_pcall 会弹出函数和所有参数(如果有的话;在您的情况下,您指定了零个),因此如果函数存在,则不会出现问题。您应该做的是在外部 if 的 else 子句中添加 lua_pop(L, 1)。这样,您的函数将始终保持 _平衡_(即使栈与之前相同)。
您可以在 Lua 手册中看到这些内容:对于每个函数,在描述中都有详细说明,并且在函数原型的括号旁边用灰色表示。例如,lua_getglobal 具有 [-0, +1, e],这意味着它不会弹出元素,而是总是推送一个元素(e 意味着它可能会导致错误)。
2014-09-03 14:38:11
评论区的留言会收到邮件通知哦~
推荐文章
- 如何将两个不同的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中获取用户配置主目录的跨平台方法
根据 www.lua.org/manual/5.2/manual.html#4.2,你需要负责保持栈的清洁,因为 Lua 不会执行任何检查。我会 假设 如果不保持栈的清洁(将新值推送到实际栈空间之外的内存位置,恰好也在你的进程虚拟内存范围之外)可能导致段错误。
由于你没有调用 lua_pcall 来从栈中移除非函数,这会无限增加栈的大小。
你的解决方案应该是有效的,除非被调用的函数在栈上留下了某些东西。由于你将 nresults 设置为 0,Lua 不会在栈上留下任何结果。
然而,我理解 lua_pcall 参考文献是即使 nresults 为 0,错误代码仍然可能留在栈上。编辑:我也检查了那个行为,它正是我假设的那样。
在这种情况下,在开头调用 lua_gettop 并在结尾处调用 lua_settop 将始终有效,并保持你的栈平衡。