diff --git a/lualib-src/lua-skynet.c b/lualib-src/lua-skynet.c index 929354e2..17aa4be5 100644 --- a/lualib-src/lua-skynet.c +++ b/lualib-src/lua-skynet.c @@ -407,11 +407,18 @@ lhpc(lua_State *L) { return 1; } +#define MAX_LEVEL 3 + +struct source_info { + const char * source; + int line; +}; + /* string tag string userstring thread co (default nil) - integer level (default is 3) + integer level */ static int ltrace(lua_State *L) { @@ -420,15 +427,41 @@ ltrace(lua_State *L) { const char * user = luaL_checkstring(L, 2); if (lua_isthread(L, 3)) { lua_State * co = lua_tothread (L, 3); + struct source_info si[MAX_LEVEL]; lua_Debug d; - int level = luaL_optinteger(L, 4, 3); + int level = luaL_checkinteger(L, 4); + int index = 0; do { if (!lua_getstack(co, level, &d)) break; lua_getinfo(co, "Sl", &d); level++; - } while (d.currentline < 0); - skynet_error(context, " %" PRId64 " %s : %s:%d", tag, get_time(), user, d.short_src, d.currentline); + si[index].source = d.source; + si[index].line = d.currentline; + if (d.currentline >= 0) + ++index; + } while (index < MAX_LEVEL); + switch (index) { + case 1: + skynet_error(context, " %" PRId64 " %s : %s:%d", tag, get_time(), user, si[0].source, si[0].line); + break; + case 2: + skynet_error(context, " %" PRId64 " %s : %s:%d %s:%d", tag, get_time(), user, + si[0].source, si[0].line, + si[1].source, si[1].line + ); + break; + case 3: + skynet_error(context, " %" PRId64 " %s : %s:%d %s:%d %s:%d", tag, get_time(), user, + si[0].source, si[0].line, + si[1].source, si[1].line, + si[2].source, si[2].line + ); + break; + default: + skynet_error(context, " %" PRId64 " %s", tag, get_time(), user); + break; + } return 0; } skynet_error(context, " %" PRId64 " %s", tag, get_time(), user); diff --git a/lualib/skynet.lua b/lualib/skynet.lua index cb789975..be009d15 100644 --- a/lualib/skynet.lua +++ b/lualib/skynet.lua @@ -153,14 +153,14 @@ end -- suspend is local function function suspend(co, result, command, param, param2) - local tag = session_coroutine_tracetag[co] if not result then local session = session_coroutine_id[co] if session then -- coroutine may fork by others (session is nil) local addr = session_coroutine_address[co] if session ~= 0 then -- only call response error - if tag then c.trace(tag, "error", co) end + local tag = session_coroutine_tracetag[co] + if tag then c.trace(tag, "error") end c.send(addr, skynet.PTYPE_ERROR, session, "") end session_coroutine_id[co] = nil @@ -169,20 +169,25 @@ function suspend(co, result, command, param, param2) end error(debug.traceback(co,tostring(command))) end - if command == "CALL" then + if command == "CALLTRACE" then + local tag = session_coroutine_tracetag[co] if tag then - c.trace(tag, "call", co) - c.send(param2, skynet.PTYPE_TRACE, 0, tag) + c.trace(tag, "call", co, 2) + c.send(param, skynet.PTYPE_TRACE, 0, tag) end + return suspend(co, coroutine_resume(co)) + elseif command == "CALL" then session_id_coroutine[param] = co elseif command == "SLEEP" then - if tag then c.trace(tag, "sleep", co) end + local tag = session_coroutine_tracetag[co] + if tag then c.trace(tag, "sleep", co, 2) end session_id_coroutine[param] = co if sleep_session[param2] then error(debug.traceback(co, "token duplicative")) end sleep_session[param2] = param elseif command == "RETURN" then + local tag = session_coroutine_tracetag[co] if tag then c.trace(tag, "response") end local co_session = session_coroutine_id[co] session_coroutine_id[co] = nil @@ -416,7 +421,7 @@ skynet.trash = assert(c.trash) local function yield_call(service, session) watching_session[session] = service - local succ, msg, sz = coroutine_yield("CALL", session, service) + local succ, msg, sz = coroutine_yield("CALL", session) watching_session[session] = nil if not succ then error "call failed" @@ -425,6 +430,7 @@ local function yield_call(service, session) end function skynet.call(addr, typename, ...) + coroutine_yield("CALLTRACE", addr) local p = proto[typename] local session = c.send(addr, p.id , nil , p.pack(...)) if session == nil then @@ -434,6 +440,7 @@ function skynet.call(addr, typename, ...) end function skynet.rawcall(addr, typename, msg, sz) + coroutine_yield("CALLTRACE", addr) local p = proto[typename] local session = assert(c.send(addr, p.id , nil , msg, sz), "call to invalid address") return yield_call(addr, session) @@ -525,12 +532,8 @@ local function raw_dispatch_message(prototype, msg, sz, session, source) else local tag = trace_source[source] if tag then - if session ~= 0 then - c.trace(tag, "request") - trace_source[source] = nil - else - tag = nil - end + c.trace(tag, "request") + trace_source[source] = nil end local p = proto[prototype] if p == nil then