Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/58.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Lua C api:过多的Lua_状态会导致错误吗?_C_Api_Lua_Segmentation Fault - Fatal编程技术网

Lua C api:过多的Lua_状态会导致错误吗?

Lua C api:过多的Lua_状态会导致错误吗?,c,api,lua,segmentation-fault,C,Api,Lua,Segmentation Fault,我们在多台计算机上工作,执行一个用c/c++编写的程序,并使用LuaAPI,每台计算机都会因不同的错误而崩溃。它通常是一个分段错误,其回溯导致我们调用bu liblua,或者是一个通常在尝试调用nil值时给出的错误,就好像它是一个函数一样 奇怪的是,它工作得很好,直到我们达到许多状态(不,我们绝对需要多个状态,只有一个是不够的)。它们可能引用同一个文件——同样,在打开的状态数不到一定数量之前,该文件工作正常——也可能没有 以下是如何打开、注册和关闭它们,以防在使用多个状态时出现问题: lua_S

我们在多台计算机上工作,执行一个用c/c++编写的程序,并使用LuaAPI,每台计算机都会因不同的错误而崩溃。它通常是一个分段错误,其回溯导致我们调用bu liblua,或者是一个通常在尝试调用nil值时给出的错误,就好像它是一个函数一样

奇怪的是,它工作得很好,直到我们达到许多状态(不,我们绝对需要多个状态,只有一个是不够的)。它们可能引用同一个文件——同样,在打开的状态数不到一定数量之前,该文件工作正常——也可能没有

以下是如何打开、注册和关闭它们,以防在使用多个状态时出现问题:

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_寄存器调用,但对所有其他状态都是一样的,而且它们工作起来没有任何问题

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

这是否与LuaAPI本身有关(比如一次可能会打开预定数量的状态)?我知道我没有给出太多的细节,但这几乎是所有与lua相关的代码

编辑:我忘了包含“require”语句(我调用它来推送模块),但它已经在代码中了(因此,这不是它不工作的原因),对此表示抱歉

该程序是单线程的。有些对象的属性是lua状态,因此有多个状态


错误消息表明它找不到应该使用的文件。。。它实际上在那里,而且可以在打开的状态较少的情况下使用,没有任何问题。

您给出的调用站点片段没有意义。你有

lua_pushstring(L,"function");
if(!lua_pcall(L,1,0,0)) 
{
 ...
它不显示名为“function”的函数的检索,而是调用堆栈顶部的任何函数,其第一个参数为字符串
“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));
}
Edit:
lua\u pcall()
返回的错误字符串可能会提供信息。有关更多信息,请在堆栈上放置适当的错误函数,并将其索引作为第四个参数传递给
lua\u pcall
。一个好的选择是
debug.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))
{
 ...
第一个片段创建一个globals,其值为每个C函数。您可以使用
get\u global()
lua\u pcall()
调用这些函数,如我回答的第一部分所述

第二个片段检索名为
require
的全局函数,并使用字符串
“function”
作为其唯一参数调用它。用Lua表示的等价物是
需要“function”
,它将在中查找名为“function”的模块。即使在调用
require()
时,也最好捕获并报告错误消息。在这种情况下,很可能会告诉您,在
需要查看的任何一个详细列出的位置中,都没有名为“function”的模块

但是您编写的任何东西实际上都不会调用函数本身

但这里有一个更大的担忧。现在还不完全清楚为什么首先需要多个Lua状态,尤其是在单线程程序中。[coroutines][2]是否更适合


对于多个状态,您必须记住,每个状态都与所有其他状态极其隔离。将值从一个状态移动到另一个状态的唯一方法是使用C API从一个状态检索值并将其推送到另一个状态。协同程序提供了分离状态的一些优点,同时共享了一组通用的全局变量。

请确保使用LUA_APICHECK进行编译,以便在运行时捕获一些错误。如果您可以将代码简化为一个具有相同问题的小示例,请在此处发布完整的代码,并可能通过电子邮件发送lua列表。是否涉及多个线程,或者只有一个线程驱动多个状态?为了确保我们没有遗漏真正明显的问题,请在关闭lua状态后小心不要使用它,对吗?这样做将不可避免地涉及到某种错误,但墨菲可以让事情在一段时间内几乎正常工作。忘记编写之前推送的“require”语句,因为代码在另一台计算机上,很抱歉不清楚。