2010-07-09 67 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