2010-07-09 92 views
2

我们正在使用多台计算机,执行以c/C++编码的程序并使用lua api,并且每个计算机都会因不同的错误而崩溃。它通常是一个分段错误,它的回溯导致我们调用bululua函数,或者通常在尝试调用一个nil值的时候给出它,就像它是一个函数一样。Lua C api:太多lua_states导致错误?

奇怪的是,直到我们达到了许多国家(不,我们绝对需要多个国家中,只有一个是不够的)的它工作得很好。他们可能会引用相同的文件-again,它可以正常工作,直到不到多个状态打开或不打开。

这里是他们是如何打开,登记,并关闭,万一有使用多种状态时有些不对劲:

lua_State *state=lua_open(); 
luaL_openlibs(state) 
luaL_loadfile(filename.c_str()); 
... 
lua_register(state,"function",function); //dozens of them 
... 
lua_close(state); 

创建任何其他状态,直到所有的寄存器都做了,无论是封闭或不取决于国家在哪里使用。

这就是我分割故障期间得到:

#0 0x0013fe79 in ??() from /usr/lib/liblua5.1.so.0 
#1 0x0013325b in lua_pushlstring() from /usr/lib/liblua5.1.so.0 
#2 0x001442ba in ??() from /usr/lib/liblua5.1.so.0 
#3 0x00144b61 in luaL_pushresult() from /usr/lib/liblua5.1.so.0 
#4 0x00144de5 in luaL_gsub() from /usr/lib/liblua5.1.so.0 
#5 0x0014fb52 in ??() from /usr/lib/liblua5.1.so.0 
#6 0x0014ffb7 in ??() from /usr/lib/liblua5.1.so.0 
#7 0x0013839a in ??() from /usr/lib/liblua5.1.so.0 
#8 0x00138834 in ??() from /usr/lib/liblua5.1.so.0 
#9 0x001337a5 in lua_call() from /usr/lib/liblua5.1.so.0 
#10 0x0014f3ea in ??() from /usr/lib/liblua5.1.so.0 
#11 0x0013839a in ??() from /usr/lib/liblua5.1.so.0 
#12 0x00138834 in ??() from /usr/lib/liblua5.1.so.0 
#13 0x00133761 in ??() from /usr/lib/liblua5.1.so.0 
#14 0x00137ea3 in ??() from /usr/lib/liblua5.1.so.0 
#15 0x00137f05 in ??() from /usr/lib/liblua5.1.so.0 
#16 0x00133588 in lua_pcall() from /usr/lib/liblua5.1.so.0 

和相关代码:

lua_getglobal(L,"require"); 
lua_pushstring(L,"function"); 
if(!lua_pcall(L,1,0,0)) 
{ 
... 

给出的函数的字符串是没有错的,它工作正常用不到打开的州数。

当它输出“nil value”错误时,这意味着我们没有在程序内部使用相关的lua_register调用,但是对于所有其他状态它都是一样的,并且它们再一次没有任何问题地工作。

我认为这可能是由于一些内存泄漏,我真的不明白为什么因为所有的状态都关闭。

这与lua api本身有关吗?(就像有可能一次打开一个预定数量的状态,也许)?我知道我没有提供太多的细节,但这几乎是所有与lua有关的代码。

编辑:我忘了包括“require”语句(我称之为推模块),但它已经在代码中(因此,不是它不起作用的原因),对此很抱歉。

程序是单线程的。一些对象具有lua状态作为它们的属性,因此具有多个状态。

该错误消息表示无法找到它应该使用的文件......这实际上是那里再次,可以没有任何问题较少的状态打开使用。

+0

确保您使用LUA_APICHECK进行编译以在运行时捕获一些错误。如果您可以将代码缩减为具有相同问题的小示例,请在此处发布完整代码,并且可能还会通过电子邮件发送lua列表。 – u0b34a0f6ae 2010-07-09 13:29:54

+0

是否存在多个线程或只有一个线程驱动多个状态? – 2010-07-09 19:19:18

+0

为了确保我们不会错过真正显而易见的事情,在关闭它之后,请注意不要使用Lua状态*,对吗?这样做不可避免地会带来某种错误,但墨菲可能会让事情暂时停滞不前。 – RBerteig 2010-07-12 22:30:30

回答

2

你给的call-site片段没有意义。你有

lua_pushstring(L,"function"); 
if(!lua_pcall(L,1,0,0)) 
{ 
... 

不显示为“功能”功能的恢复,而是调用任何位于堆栈以被指定为字符串"function"其第一个参数的顶部。

你或许意味着

lua_getglobal(L,"function"); 
if(!lua_pcall(L,0,0,0)) 
{ 
... // succcess 
} else { 
    // examine the error from the call for useful information 
    fprintf(stderr, "lua_pcall: %s\n", lua_tostring(L,1)); 
} 

编辑:错误字符串返回从lua_pcall()很可能是信息。有关更多信息,请将合适的错误函数放在堆栈上,并将其索引作为第四个参数传递给lua_pcalldebug.traceback是一个不错的选择。

void callback(lua_State *L, const char *fname) 
{ 
    int status 
    lua_getglobal(L,"debug");  // put debug.traceback on the stack 
    lua_getfield(L,-1,"traceback"); 
    lua_remove(L,-2);  
    lua_getglobal(L,fname); // put function on the stack 
    status = lua_pcall(L,0,0,-2) 
    if (!status)  // call it with no parameters and no return values 
    { 
     // succcess 
    } else { 
     // examine the error from the call for useful information 
     fprintf(stderr, "lua_pcall returned %d: %s\n", status, lua_tostring(L,1)); 
     lua_pop(L,1);    // remove error message from the stack 
    } 
    lua_pop(L,1);     // remove debug.traceback from the stack 
} 

EDIT2:你澄清后,它仍然没有任何意义。

您的代码具有以下片段:

lua_register(state,"function",function); //dozens of them 
... 

后来

lua_getglobal(L,"require"); 
lua_pushstring(L,"function"); 
if(!lua_pcall(L,1,0,0)) 
{ 
... 

第一个片段创建一个全局的值分别C函数。您可以使用get_global()lua_pcall()来调用这些函数,如我的答案的第一部分所述。

第二个片段检索名为require的全局变量,并以字符串"function"作为唯一参数进行调用。在Lua中表示的等效项为require"function",它将在the usual way中寻找名为“function”的模块。即使在拨打require()时,最好还是抓住并报告错误信息。在这种情况下,很可能会告诉您在require查找的任何详细列表中的任何一个列表中都没有名为“function”的模块。

但是你写的没有实际调用函数本身。

但这里有一个更大的问题。目前还不完全清楚为什么你首先需要多个Lua状态,特别是在单线程程序中。有没有可能[coroutines] [2]更合适?

对于多个状态,您必须记住每个状态与其他状态是非常隔离的。将值从一个状态移动到另一个状态的唯一方法是通过使用C API从一个状态检索值并将它们推送到另一个状态。协程给出了单独状态的一些优点,同时分享了一组通用的全局变量。

+0

由于代码位于另一台计算机上,忘记了写入“require”语句,因此不清楚。 – felace 2010-07-15 08:43:11