【问题标题】:luajit segmentation fault - not in lua-5.2luajit 分段错误 - 不在 lua-5.2 中
【发布时间】:2015-01-29 09:15:35
【问题描述】:

你好,我正在尝试切换到 luajit。 下面的代码在使用 liblua5.2 时编译并运行良好。 当试图编译和链接到 luajit-2.0 时 - 它编译得很好但有段错误

有人给我提示吗?

编译 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

【问题讨论】:

  • 要缩小崩溃发生的范围,首先构建程序的调试版本(在构建时添加-g 标志),然后在调试器中运行它。调试器将停止在崩溃的位置,并让您检查函数调用堆栈。查看调用堆栈,如果崩溃不在您的代码中,则沿着调用堆栈向上走,直到您在代码中。在那里,您可以检查变量的值,看看它们是否符合您的预期。如果不出意外,请编辑您的问题以显示崩溃发生的位置(在您的代码中)。
  • 还要注意它实际上可能是 Lua/Luajit 中的一个错误。尝试最小化代码以重现问题,并确保您的代码正常工作(一个好的开始是添加更多编译器警告,例如-Wall -Wextra -pedantic)。如果崩溃仍然发生,并且您的代码尽可能好,请转到 Lua 并添加一个错误报告,显示您拥有的代码。
  • 您没有检查来自 lua_touserdata() 的返回值,它可以返回 NULL,但您很快就会取消引用。
  • lua_print 没有返回类型。试试return 0;,注意-Wall -pedantic 会警告你。
  • 提供您自己的答案并附上摘要并接受。

标签: c lua luajit


【解决方案1】:

lua_print() 中的 return 0; 丢失。 添加这个 - 修复了段错误。

谢谢 - 所有评论者 - 添加 -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;
}

【讨论】:

    猜你喜欢
    • 2017-02-06
    • 2017-08-23
    • 1970-01-01
    • 2017-11-07
    • 1970-01-01
    • 1970-01-01
    • 2022-07-14
    • 2015-10-16
    • 1970-01-01
    相关资源
    最近更新 更多