【发布时间】: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会警告你。 -
提供您自己的答案并附上摘要并接受。