20

私がこれを正しく理解していれば、エラーが発生したときに、Luaはデフォルトでデバッグライブラリを「debug.traceback」と呼びます。

ただし、次の例のようにLuaをCコードに埋め込む場合: 単純なLuaAPIの例

スタックの一番上にあるエラーメッセージのみを利用できます。

すなわち

if (status) {
    /* If something went wrong, error message is at the top of */
    /* the stack */
    fprintf(stderr, "Couldn't load file: %s\n", lua_tostring(L, -1));

    /* I want to print a stacktrace here. How do I do that? */
    exit(1);
}

初期エラーの後にCからスタックトレースを出力するにはどうすればよいですか?

4

4 に答える 4

20

Luaはデフォルトで、エラーが発生したときにデバッグライブラリを「debug.traceback」と呼びます。

いいえ、ありません。Luaランタイム(lua.exe)はそれを行いますが、Luaライブラリはそれ自体では行いません。Luaエラーを含むコールスタックが必要な場合は、それを生成する必要があります。

Luaランタイムは、lua_pcallエラー関数を使用してこれを行います。エラー関数が呼び出されたときにスタックが巻き戻されていないため、そこでスタックトレースを取得できます。ランタイムが使用するエラー関数は次のとおりです。

static int traceback (lua_State *L) {
  if (!lua_isstring(L, 1))  /* 'message' not a string? */
    return 1;  /* keep it intact */
  lua_getfield(L, LUA_GLOBALSINDEX, "debug");
  if (!lua_istable(L, -1)) {
    lua_pop(L, 1);
    return 1;
  }
  lua_getfield(L, -1, "traceback");
  if (!lua_isfunction(L, -1)) {
    lua_pop(L, 2);
    return 1;
  }
  lua_pushvalue(L, 1);  /* pass error message */
  lua_pushinteger(L, 2);  /* skip this function and traceback */
  lua_call(L, 2, 1);  /* call debug.traceback */
  return 1;
}
于 2012-09-04T03:47:15.830 に答える
10

上記のニコルの答えをここで解決することは、実際の例です:

static int traceback(lua_State *L) {
    lua_getfield(L, LUA_GLOBALSINDEX, "debug");
    lua_getfield(L, -1, "traceback");
    lua_pushvalue(L, 1);
    lua_pushinteger(L, 2);
    lua_call(L, 2, 1);
    fprintf(stderr, "%s\n", lua_tostring(L, -1));
    return 1;
}

int main(int argc, char **argv) {
    lua_State *L = lua_open();
    luaL_openlibs(L);    
    lua_pushcfunction(L, traceback);
    int rv = luaL_loadfile(L, "src/main.lua");
    if (rv) {
        fprintf(stderr, "%s\n", lua_tostring(L, -1));
        return rv;
    } else {
        return lua_pcall(L, 0, 0, lua_gettop(L) - 1);
    }
}
于 2013-05-01T17:41:05.580 に答える
7

私はあなたと同じようにいくつかの質問に答えました、そして私はこの方法がうまくいくのを見つけました:

luaL_traceback(L, L, NULL, 1);
printf("%s\n", lua_tostring(L, -1));

luaL_tracebackはスタックの印刷に正確に使用されているのでdebug.traceback()、これは適切な方法であると思います。LuaのAPIマニュアルをluaL_traceback読むか、Luaのソースコードを読んで、paramsの意味を理解することができます。

于 2015-09-16T09:10:41.813 に答える
2

mxclのコードにはいくつかの問題があります:

static int traceback(lua_State *L) {
    lua_getfield(L, LUA_GLOBALSINDEX, "debug");
    lua_getfield(L, -1, "traceback");
    //---------------------------
    lua_pop(L,-2); //to popup the 'debug'
    //---------------------------
    lua_pushvalue(L, 1);
    lua_pushinteger(L, 2);
    lua_call(L, 2, 1);
    fprintf(stderr, "%s\n", lua_tostring(L, -1));
    return 1;
}
于 2014-04-13T18:48:29.953 に答える