lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


I try to fix it, but maybe there is a better solution :)

diff --git a/src/ldebug.c b/src/ldebug.c
index 6986bf0..acddc3b 100644
--- a/src/ldebug.c
+++ b/src/ldebug.c
@@ -85,8 +85,16 @@ LUA_API int lua_getstack (lua_State *L, int level, lua_Debug *ar) {
   CallInfo *ci;
   if (level < 0) return 0;  /* invalid (negative) level */
   lua_lock(L);
-  for (ci = L->ci; level > 0 && ci != &L->base_ci; ci = ci->previous)
-    level--;
+  if (level == 0 && L->status == LUA_YIELD && isLua(L->ci)) {
+    ci = &(L->temp_ci);
+    *ci = *(L->ci);
+    ci->func = restorestack(L, ci->extra);
+    status = 1;
+    ar->i_ci = ci;
+  } else {
+    for (ci = L->ci; level > 0 && ci != &L->base_ci; ci = ci->previous)
+      level--;
+  }
   if (level == 0 && ci != &L->base_ci) {  /* level found? */
     status = 1;
     ar->i_ci = ci;
@@ -130,7 +138,7 @@ static const char *findlocal (lua_State *L, CallInfo *ci, int n,
   else
     base = ci->func + 1;
   if (name == NULL) {  /* no 'standard' name? */
-    StkId limit = (ci == L->ci) ? L->top : ci->next->func;
+    StkId limit = (ci == L->ci || ci == &(L->temp_ci)) ? L->top : ci->next->func;
     if (limit - base >= n && n > 0)  /* is 'n' inside 'ci' stack? */
       name = "(*temporary)";  /* generic name for any valid slot */
     else
diff --git a/src/lstate.h b/src/lstate.h
index 81e12c4..c89b910 100644
--- a/src/lstate.h
+++ b/src/lstate.h
@@ -160,6 +160,7 @@ struct lua_State {
   struct lua_State *twups;  /* list of threads with open upvalues */
   struct lua_longjmp *errorJmp;  /* current error recover point */
   CallInfo base_ci;  /* CallInfo for first level (C calling Lua) */
+  CallInfo temp_ci;  /* CallInfo for yield from hook (debug api use) */
   lua_Hook hook;
   ptrdiff_t errfunc;  /* current error handling function (stack index) */
   int stacksize;


2015-02-11 1:01 GMT+08:00 云风 <cloudwu@gmail.com>:
If I call lua_yield(L,0) from a lua_Hook function , and then call lua_getlocal on this yielded thread, it crashes. (Both on lua 5.2 and lua 5.3)

-----
local hook = require "hook"

local co = coroutine.create(function(a)
return a
end)
hook(co)
coroutine.resume(co, 1)
debug.getlocal(co, 0, 1)   -- crashes
------
#include <lua.h>
#include <lauxlib.h>

static void
lhook(lua_State *L, lua_Debug *ar) {
lua_yield(L,0);
}

static int
hook(lua_State *L) {
lua_State *L1 = lua_tothread(L, 1);
lua_sethook(L1, lhook, LUA_MASKLINE, 0);
return 0;
}

int
luaopen_hook(lua_State *L) {
lua_pushcfunction(L, hook);
return 1;
}
---------

I guess the reason is : when yield from a hook, the top function in the yielded thread is a lua function, but the L->ci->func is not a valid lua function object. so lua_getlocal (and other debug api) can't work.




--
http://blog.codingnow.com