You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

从Lua调用C函数触发Segmentation Fault段错误问题排查求助

从Lua调用C函数触发Segmentation Fault段错误问题排查求助

大家好,我遇到了一个从Lua调用C函数时触发Segmentation Fault的问题,折腾了好一阵没找到根源,想请大家帮忙分析下:

问题背景

今天下午我在CentOS7上重新编译了服务器程序,启动后发现进程直接挂掉了。这里有个关键前提:Lua5.1的静态库是在CentOS6上编译的,CentOS6用的gcc版本是4.4.7,而CentOS7的gcc版本是4.8.5。

GDB调试信息

我用gdb做了详细调试,得到以下关键信息:

Breakpoint 4, SGPlatformActMgr::InitDBFromConf (L=0x7fffe577901c) at gamelogic/bg/SGPlatformActMgr.cpp:454

454     ERROR_LOG("astActInfo count:%d InitActDB begin\n" , astActInfo.GetCount());

(gdb) l

449         astActInfo.Add(stActInfo);

450

451         lua_pop(L, 1);

452     }

453

454     ERROR_LOG("astActInfo count:%d InitActDB begin\n" , astActInfo.GetCount());

455     iRet = InitActDB(L, astActInfo);

456     if (iRet)

457     {

458         ERROR_LOG("InitActDB failed:%d\n", iRet);

(gdb) n

455     iRet = InitActDB(L, astActInfo);

(gdb) p L

$2 = (lua_State *) 0x7fffe577901c

(gdb) s

Program received signal SIGSEGV, Segmentation fault.

0x000000000056b0fa in InitActDB (L=<error reading variable: Cannot access memory at address 0x7fffff5e4a48>,
astActInfo=<error reading variable: Cannot access memory at address 0x7fffff5e4a40>)

at gamelogic/bg/SGPlatformActMgr.cpp:292

292 {

(gdb) print L

Cannot access memory at address 0x7fffff5e4a48

相关代码片段

问题出在从Lua调用InitDBFromConf(lua_act_config)这个C函数的流程中,相关核心代码如下:

SGPlatformActMgr::InitDBFromConf函数

int SGPlatformActMgr::InitDBFromConf(lua_State* L)
{
//...
// 其他业务逻辑
SGArray<TPlatformActInfo, 150> astActInfo;
int iTableIdx = 1;
int iRet = 0;
lua_pushnil(L);
while (lua_next(L, iTableIdx) != 0)
{
TPlatformActInfo stActInfo;
iRet = TransformActInfo(L, stActInfo);
if (iRet)
{
ERROR_LOG("invalid TransformActInfo failed(%d)\n", iRet);
return 0;
}
astActInfo.Add(stActInfo);
lua_pop(L, 1);
}

iRet = InitActDB(L, astActInfo);
// 后续业务逻辑
//....
}

TransformActInfo函数及相关宏

#define ASSIGN_LUA_VALUE(L,VAR,KEY,RET_CODE)\
do \
{   \
lua_pushstring((L), (KEY)); \
lua_rawget((L), -2);    \
if (!lua_isnumber((L), -1)) \
{   \
ERROR_LOG("expect number but got:%s\n", lua_typename((L), lua_type(L, -1)));    \
return RET_CODE;    \
}   \
(VAR) = lua_tonumber(L, -1); \
lua_pop((L), 1);    \
} while (0)

#define ASSIGN_LUA_STR_VALUE(L,VAR,KEY,RET_CODE)\
do \
{   \
lua_pushstring((L), (KEY)); \
lua_rawget((L), -2);    \
if (!lua_isstring((L), -1)) \
{   \
ERROR_LOG("expect string but got:%s\n", lua_typename((L), lua_type(L, -1)));    \
return RET_CODE;    \
}   \
const char* pTempStr = lua_tostring(L, -1); \
SAFE_COPYSTR_TO_CARRAY((VAR), pTempStr); \
lua_pop((L), 1);    \
} while (0)

int TransformActInfo(lua_State* L, TPlatformActInfo& stActInfo)
{
if (!lua_istable(L, -1))
{
ERROR_LOG("expect a table but got:%s\n", lua_typename(L, lua_type(L, -1)));
return -1;
}

ASSIGN_LUA_VALUE(L, stActInfo.m_uiActID, "id", -100);
//..... 其他字段赋值逻辑
ASSIGN_LUA_STR_VALUE(L, stActInfo.m_acExtStr, "ext_str", -112);

return 0;
}

已尝试的排查步骤

  • 用gdb的watch命令监控L参数的值,确认从SGPlatformActMgr::InitDBFromConf到调用InitActDB之间,没有任何代码或操作修改或释放L指针
  • 在调用InitActDB前设置断点打印L,确认它是一个有效的lua_State指针
  • 用step命令单步进入InitActDB,发现刚进入函数第一行就触发了段错误
  • 单独调用InitActDB并传入有效的L和astActInfo参数时,函数能正常执行,没有段错误或其他异常

现在我实在搞不清为什么在完整调用链里就会出问题,想请教大家有没有遇到类似的情况,或者能帮我分析下可能的原因和解决办法?

备注:内容来源于stack exchange,提问作者sword windy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.22 09:38:00