Lua 堆栈回溯中缺少函数名称

Missing function names in Lua stack traceback

我正在尝试改进运行 Lua 脚本的程序中的错误处理。 简化版:

function _errH(msg)

    print(msg .. "\n" .. debug.traceback(nil, 1))

end

function _main()

  -- cause some random error
  print(a-2)

end

function main()

    xpcall(_main, errH)
end

main()

给我以下调用堆栈(请忽略错误的行号):

stack traceback:
    [string ""]:7428: in function '__sub'
    [string ""]:7651: in function <[string ""]:7432>
    [C]: in function 'xpcall'
    [string ""]:7658: in function 'main'
    [string ""]:7928: in main chunk

现在我想知道为什么到处都是[string ""]

有什么方法可以影响这些缺失的文本吗?除了定义它们之外,我还必须命名函数吗? 例如,为什么我看到 in function '__sub' 而不是 in function '_main'

[string ""] 来自于您将块加载到 vm 中的方式。您没有提供文件名作为 lua_dofile/lua_loadfile/lua_dostring/lua_loadstring 的参数,或者只是在那里提供了空字符串。
请注意,字符串是 lua 文件(lua 块)的名称,而不是函数的名称。

一般在loading时就可以指定chunk名称了。辅助功能使用 lua_load 并且大多数会根据正在加载的内容类型设置块名称:

  • lua_load 接受块名称
  • luaL_loadfile 将使用文件名
  • luaL_dofile 使用 luaL_loadfile
  • luaL_loadstring 将使用字符串内容
  • luaL_dostring 使用 luaL_loadstring
  • luaL_loadbuffer 接受块名称

如果你查看 luaL_loadstring 的源代码:

LUALIB_API int luaL_loadstring (lua_State *L, const char *s) {
  return luaL_loadbuffer(L, s, strlen(s), s);
}

请注意,它实际上只是一个使用字符串作为块名称调用 luaL_loadbuffer 的便利函数。因此,需要从以下字符串加载代码:

luaL_loadbuffer(L, s, strlen(s), "=my_chunk");

其中 "=my_chunk" 是将出现在 debug information 中的块的名称。

名字前的等号改回溯源:

my_chunk:1: in main chunk

省略等号会显示:

[string "my_chunk"]:1: in main chunk