卢阿:这会引起一个断层吗
Lua: Can this cause a segfault
我正在开发一个使用Lua编写脚本的程序,有时它会崩溃。对于GDB,我想我发现了问题,但我不知道它是否解决了问题,因为segfault只会偶尔发生。所以,旧的代码是这样的:
void Call(std::string func){
lua_getglobal(L, func.c_str()); //This is the line GDB mentioned in a backtrace
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));
而segfault已经不再发生了。这可能是问题所在吗?
使用lua_gettop(L)
作为lua_pop
的参数将清除整个Lua API堆栈(相当于lua_settop(0)
),这可能不是您想要的。但事实上,你的问题是lua_getglobal
总是推动一些东西;如果不存在具有给定名称的全局,它会推送nil
,就像等效的Lua表达式一样。但是,lua_pcall
会弹出函数和所有参数(如果有的话;在您的情况下,您指定了零),所以如果函数存在,您就不会遇到问题。您应该做的是将lua_pop(L, 1)
添加到外部if
的else
子句中。这样,您的函数将始终保持平衡(即保持堆栈原样)。
你可以在Lua手册中看到这些东西:对于每个函数,它都在描述中拼写出来,也用灰色表示,在函数原型旁边的括号中。例如,lua_getglobal
具有[-0,+1,e],这意味着它不会弹出任何元素,并且(总是)推送一个元素(e意味着它可能会导致错误)。
根据www.lua.org/manual/5.2/manual.html#4.2,您有责任保持堆栈清洁,因为lua不会执行任何检查。我会假设segfault是没有保持堆栈干净的合理结果(新值被推到实际堆栈空间之外的内存位置,偶尔也会推到进程虚拟内存之外)。
由于您没有调用lua_call来从堆栈中删除非函数,因此这将无限期地增加堆栈。
除非被调用的函数在堆栈上留下一些内容,否则您的解决方案应该可以工作。由于您将nresults设置为0,因此Lua不会在堆栈上留下任何结果。
不过,我对lua_call引用的理解是,即使nresults为0,错误代码也可以留在堆栈上。编辑:我也检查过这种行为,它和我想象的完全一样。
在这种情况下,在开始时调用lua_gettiop,在结束时调用lua_settop在任何情况下都可以工作,并保持堆栈平衡。
- 如何创建一个CMake变量,除非显式重写,否则使用默认值
- 删除一个线程上有数百万个字符串的大型哈希映射会影响另一个线程的性能
- 为什么两个不同的未命名名称空间可以共存于一个cpp文件中
- 运行同一解决方案的另一个项目的项目
- 挂起和取消挂起一个文件DLL
- 用C++中的一个变量定义一个常量
- 函数向量_指针有不同的原型,我可以构建一个吗
- 在c++中用vector填充一个简单的动态数组
- 如何在选项卡视图Qt中设置一个新项目,并保存以前的项目
- 预处理器:插入结构名称中的前一个行号
- 我在c++代码中生成了一个运行时#3异常
- 我想将一个对T类型的非常量左值引用绑定到一个T类型的临时值
- 从链接列表c++中删除一个项目
- 是否可以使用一个类来控制 C++ 中另一个类的对象?(阿杜伊诺)
- 卢阿洛克斯'gcc-plugin.h'构建错误
- 卢阿:这会引起一个断层吗
- 没有输出,我已经编了一个程序去找所有阿姆斯壮没有.在100到1000之间
- 我不能有一个将多个整数作为参数的构造函数方法/原型吗?阿杜伊诺
- 卢阿布里奇的"addProperty"错误
- 卢阿宾德: "No matching overload found, candidates:"