如何使用lua_yield和lua_sethook逐行调试代码?

我想要实现一个调试器,以便逐步浏览lua脚本。该脚本嵌入在win32 c++环境中,由主GUI线程创建,并通过GUI交互(如按钮、定时器)调用。第二个线程还使用CSingleLock保护调用脚本。

首先,我尝试了这个:

lua_State* start() {
  lua_State* L = luaL_newstate();
  luaL_loadfile(L, "script.lua");
  lua_pcall(L, 0, LUA_MULTRET, 0);
  int count(0);
  lua_sethook(L, trace, LUA_MASKLINE, count);
  return L;
}

void trace(lua_State *L, lua_Debug *ar) {
  // 显示调试信息
  while (blocked) {}
}

以下是对脚本的一些示例调用:

// 由GUI反复调用
void timer() {
   lua_lock();
   lua_getglobal(L,"timer");
   lua_pcall(L, 0, 0, 0);
   lua_unlock();
}

// 另一个线程经常调用
int gettemperature() {
  lua_lock();
  lua_getglobal(L,"gettemperature");
  lua_pcall(L, 0, 1, 0);
  int temperature = lua_checknumber(L, -1);
  lua_unlock();
  return temperature;
}

由于while循环会阻塞GUI,我尝试使用协程:

lua_State* start() {
   lua_State* L = luaL_newstate();
   lua_State* co = luaL_newthread(L);
   luaL_loadfile(co, "script.lua");
   lua_resume(co, L, 0);
   int count(0);
   lua_sethook(L, trace, LUA_MASKLINE, count);
   return co;
}

void trace(lua_State *L, lua_Debug *ar) {
   // 显示调试信息
   lua_yieldk(L, 0, 0, 0);
}

下一步按钮按下时应使用lua_resume重新激活脚本。不幸的是,出现了这个错误:"attempt to yield from outside a coroutine"。

点赞