2015-01-29 4 views
1

привет, я пытаюсь переключиться на luajit. приведенный ниже код компилируется и работает при использовании liblua5.2. при попытке скомпилировать и связать с luajit-2.0 - он компилируется отлично, но segfaultsluajit segmentation fault - не в lua-5.2

есть для меня какой-то намек?

составить 5.2:

gcc -g -O0 -I/usr/include/lua5.2/ -llua5.2 -o lua_sample lua_sample.c 

компиляции LuaJIT-2,0

gcc -Wall -I/usr/local/include/luajit-2.0/ -lluajit-5.1 -o luajit_sample lua_sample.c 

Выход на 5,2:

# ./lua_sample 
LUA: MAIN 
Script ended with 22 
LUA: ######## HOOK CALLED - Start 
LUA: # service_id: 322 
LUA: # service_name: sssasdf 
LUA: #  setting new state to 4 
SET_STATUS: Service Object: sssasdf 
SET_STATUS: Code: 4 
LUA: # call returned RES:-123 
LUA: ######## HOOK CALLED - END 
HOOK ended with -123 

выход на LuaJIT:

# ./luajit_sample 
LUA: MAIN 
Segmentation fault 

lua_sample.c

#include <stdio.h> 

#include "lua.h" 
#include "lualib.h" 
#include "lauxlib.h" 

/* the Lua interpreter */ 

struct service { 
    int service_id; 
    char service_name[50]; 
}; 

static int lua_print(lua_State *L) { 
    int i; 
    int nargs = lua_gettop(L); 

    for (i=1; i <= nargs; ++i) { 
     printf("LUA: %s\n", lua_tostring(L, i)); 
    } 

} 
static int lua_callback_service_set_status(lua_State *L) { 
    int status; 
    struct service * svc; 


    svc=lua_touserdata(L, 1); 
    status=lua_tonumber(L, 2); 

    printf("SET_STATUS: Service Object: %s\n", svc->service_name); 
    printf("SET_STATUS: Code: %d\n",status); 

    lua_pushnumber(L, -123); 
    return 1; 
} 

int main (int argc, char *argv[]) 
{ 
    int res; 
    lua_State* L; 


    struct service svc = { 
     .service_id=322, 
     .service_name="sssasdf" 
    }; 

    /* initialize Lua */  
    L = luaL_newstate(); 

    /* load various Lua libraries */ 
    luaL_openlibs(L); 

    lua_register(L, "callback_service_set_status", lua_callback_service_set_status); 
    lua_register(L, "print", lua_print); 



    /* run the script */ 
    luaL_dostring(L, "return dofile('sample.lua')"); 


    res = lua_tonumber(L, -1); 
    printf("Script ended with %d\n", res); 


    /* the function name */ 
    lua_getglobal(L, "callback_service_finish_hook"); 


    lua_pushlightuserdata(L, (void*)&svc); 


    lua_newtable(L); 

    lua_pushliteral(L, "service_id"); 
    lua_pushnumber(L, svc.service_id); 
    lua_settable(L, -3); 


    lua_pushliteral(L, "service_name"); 
    lua_pushstring(L, svc.service_name); 
    lua_settable(L, -3); 





    if(lua_pcall(L, 2, 1, 0) != 0) { 

     printf("error running function `callback_service_finish_hook': %s\n", lua_tostring(L, -1)); 

    } else { 
     /* get the result */  
     res = (int)lua_tonumber(L, -1); 
     lua_pop(L, 1); 
     printf("HOOK ended with %d\n", res); 
    } 


    /* print the result */ 






    /* cleanup Lua */ 
    lua_close(L); 

    return 0; 
} 

sample.lua (в той же папке)

function callback_service_finish_hook(svc_obj, svc_table) 
    print("######## HOOK CALLED - Start") 
    print("# service_id: " .. svc_table["service_id"]) 
    print("# service_name: " .. svc_table["service_name"]) 
    print("#  setting new state to 4") 
    r = callback_service_set_status(svc_obj, 4) 
    print("# call returned RES:" .. r) 
    print("######## HOOK CALLED - END") 
    return r 
end 


print("MAIN") 
return 22 
+0

Для того, чтобы сузить, где авария происходит, сначала построить отладочную-версию программы (добавить '-g' флаг при строительстве), а затем запустить его в отладчик. Отладчик остановится в месте сбоя и позволит вам проверить стек вызовов функций. Посмотрите на стек вызовов, и если авария не в вашем коде, перейдите в стек вызовов до тех пор, пока вы не найдете в своем коде. Там вы можете проверить значения переменных, чтобы убедиться, что они выглядят так, как вы ожидаете. Если ничего другого, отредактируйте свой вопрос, чтобы показать, где (в вашем коде) произошел сбой. –

+0

сделал это -g -O0, но gdb просто говорит, что программа запуска завершена и не отображает обратную трассировку. –

+0

Если программа не сбой при запуске в отладчике, то скорее всего у вас есть неинициализированный указатель. Отладчик очищает локальные переменные, что означает, что указатели становятся «NULL». Если вы проверите «NULL», то он будет работать в отладчике, но поскольку переменная будет неинициализирована, если не в отладчике, ее значение будет неопределенным (и, казалось бы, случайным), поэтому проверка «NULL» не поймает его, и вы будет использовать неинициализированный указатель и [* неопределенное поведение *] (http://en.wikipedia.org/wiki/Undefined_behavior). Вы должны проверить локальные переменные и убедиться, что они инициализированы. –

ответ

1

return 0; в lua_print() отсутствует. добавив это - исправлено segfault.

thx - всем комментаторам - добавление -Wall -Werror -pedantic показало бы, что lua_print() не возвращает значение.

поэтому окончательный lua_print выглядит следующим образом:

static int lua_print(lua_State *L) { 
    int i; 
    int nargs = lua_gettop(L); 

    for (i=1; i <= nargs; ++i) { 
     printf("LUA: %s\n", lua_tostring(L, i)); 
    } 
    return 0; 
} 

 Смежные вопросы

  • Нет связанных вопросов^_^