How can I get the lua stack trace from a core file using gdb

后端 未结 4 940
北海茫月
北海茫月 2021-02-01 18:07

I have a C++ application (for OS X) that calls lua as a scripting language. I\'m running a large number of these applications (100s) and they can run for a very long time (days

4条回答
  •  轻奢々
    轻奢々 (楼主)
    2021-02-01 18:36

    I've created a GDB script to do the stuff in the web page linked to by macs. Its not beautiful, and should probably be properly wrapped into a function etc, but here it is for the curious.

    NOTE: It seems that the web page is wrong about the filename for lua functions. In the case where the string comes from luaL_dofile() the filename starts with a @ symbol. If they're called from lua_dostring(). In that case the $filename variable is set to the whole of the string passed to lua_dostring() - and the user is probably only interested in one or two lines of context from that file. I wasn't sure how to fix that up.

    set $p = L->base_ci
    while ($p <= L->ci )
      if ( $p->func->value.gc->cl.c.isC == 1 )
        printf "0x%x   C FUNCTION", $p
        output $p->func->value.gc->cl.c.f
        printf "\n"
      else
        if ($p->func.tt==6)
          set $proto = $p->func->value.gc->cl.l.p
          set $filename = (char*)(&($proto->source->tsv) + 1)
          set $lineno = $proto->lineinfo[ $p->savedpc - $proto->code -1 ]
          printf "0x%x LUA FUNCTION : %d %s\n", $p, $lineno, $filename
        else
          printf "0x%x LUA BASE\n", $p
        end
      end
      set $p = $p+1
    end
    

    This outputs something like:

    0x1002b0 LUA BASE
    0x1002c8 LUA FUNCTION : 4 @a.lua
    0x1002e0 LUA FUNCTION : 3 @b.lua
    0x100310   C FUNCTION(lua_CFunction) 0x1fda 
    

    When I debug the crash from this code:

    // This is a file designed to crash horribly when run.
    // It should generate a core, and it should crash inside some lua functions
    
    #include "lua.h"
    #include "lualib.h"
    #include "lauxlib.h"
    
    #include 
    #include 
    
    int crash_function(lua_State * L)
    {
      raise( SIGABRT ); //This should dump core!
      return 0;
    }
    
    
    
    int main()
    {
      lua_State * L = luaL_newstate();
      lua_pushcfunction(L, crash_function);
      lua_setfield(L, LUA_GLOBALSINDEX, "C");
    
      luaopen_base(L);
      if( 1 == luaL_dofile(L, "a.lua" ))
      {
        std::cout<<"ERROR: "<

    With a.lua

    -- a.lua
    -- just calls B, which calls C which should crash
    function A()
      B()
    end
    

    and b.lua

    -- b.lua
    function B()
      C()
    end
    

提交回复
热议问题