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

Lua 5.4中lua_resume触发段错误的原因排查请求

Lua 5.4 C API lua_resume段错误排查与修复

核心错误原因

  1. 局部变量误当全局变量访问
    Lua代码中test函数里的co是局部变量,并非全局变量。在finishpcall中调用lua_getglobal(L, "co")会将nil压入栈,后续lua_tothread(L, 2)返回NULL,调用lua_resume(NULL, ...)直接触发段错误——这是导致崩溃的直接原因。

  2. 续延函数调用逻辑错误
    luaB_pcall中在调用lua_pcallk后主动调用了finishpcall,违背了Lua C API中lua_pcallk的设计逻辑:续延函数finishpcall只会在lua_pcallk执行过程中发生yield时由Lua虚拟机自动调用,手动调用会导致栈状态异常,进一步加剧错误。

  3. lua_resume参数无效
    两次lua_resume调用都使用了无效的线程指针:第一次取栈索引2的元素是nil,第二次取栈顶元素也是nil,传入NULL给lua_resume必然触发段错误。

修正方案

步骤1:修正Lua代码,将co转为全局变量

修改Lua字符串中的test函数,把局部co改为全局:

function test() 
    co = coroutine.create(function() 
        print('me') 
        coroutine.yield() 
        print('me me') 
    end) 
    return co 
end 
pcall(test)

步骤2:修正luaB_pcall的逻辑,移除主动调用finishpcall

lua_pcallk的返回值已经是执行状态,不需要手动调用续延函数:

static int luaB_pcall (lua_State *L) {
    int status;
    luaL_checkany(L, 1);
    // 直接返回lua_pcallk的结果,续延函数会在yield时自动被调用
    return lua_pcallk(L, lua_gettop(L) - 1, LUA_MULTRET, 0, 0, finishpcall);
}

步骤3:确保lua_resume使用有效线程指针

在finishpcall中先检查线程指针是否有效:

static int finishpcall (lua_State *L, int status, intptr_t ctx) {
    (void)ctx;
    // 正确判断状态:status为LUA_OK或LUA_YIELD时表示成功
    int success = (status == LUA_OK || status == LUA_YIELD);
    lua_pushboolean(L, success);
    lua_insert(L, 1);

    printf("From lua, %d\n", lua_gettop(L));
    lua_getglobal(L, "co");

    // 检查是否为有效协程线程
    lua_State *co_thread = lua_tothread(L, 2);
    if (co_thread != NULL) {
        // 第一次resume协程,执行到yield
        lua_resume(co_thread, NULL, 0, 0);
        // 第二次resume,执行剩余代码
        lua_resume(co_thread, NULL, 0, 0);
    }

    return lua_gettop(L);
}

修正后执行流程

  1. Lua代码中创建全局协程co,调用pcall(test)触发C层的luaB_pcall。
  2. lua_pcallk执行test函数,返回协程对象到栈,状态为LUA_OK,续延函数finishpcall被调用。
  3. finishpcall中获取全局协程,两次调用lua_resume:第一次输出me并yield,第二次输出me me。
  4. 最终程序正常执行,无段错误。

内容的提问来源于stack exchange,提问作者kos

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 18:52:03