@@ -37,11 +37,18 @@ void EmmyFacade::HookLua(lua_State* L, lua_Debug* ar)
3737 EmmyFacade::Get ().Hook (L, ar);
3838}
3939
40- void EmmyFacade::InitHook (lua_State* L, lua_Debug* ar)
40+ void EmmyFacade::ReadyLuaHook (lua_State* L, lua_Debug* ar)
4141{
42- auto mainL = GetMainState (L);
42+ {
43+ std::lock_guard<std::mutex> lock (EmmyFacade::Get ().readyHookMtx );
44+ if (!EmmyFacade::Get ().readyHook )
45+ {
46+ return ;
47+ }
48+ EmmyFacade::Get ().readyHook = false ;
49+ }
4350
44- auto states = FindAllCoroutine (mainL );
51+ auto states = FindAllCoroutine (L );
4552
4653 for (auto state : states)
4754 {
@@ -50,6 +57,12 @@ void EmmyFacade::InitHook(lua_State* L, lua_Debug* ar)
5057
5158 lua_sethook (L, HookLua, LUA_MASKCALL | LUA_MASKLINE | LUA_MASKRET, 0 );
5259
60+ auto debugger = EmmyFacade::Get ().GetDebugger (L);
61+ if (debugger)
62+ {
63+ debugger->Attach ();
64+ }
65+
5366 EmmyFacade::Get ().Hook (L, ar);
5467}
5568
@@ -60,7 +73,8 @@ EmmyFacade::EmmyFacade()
6073 isWaitingForIDE(false ),
6174 StartHook(nullptr ),
6275 workMode(WorkMode::EmmyCore),
63- emmyDebuggerManager(std::make_shared<EmmyDebuggerManager>())
76+ emmyDebuggerManager(std::make_shared<EmmyDebuggerManager>()),
77+ readyHook(false )
6478{
6579}
6680
@@ -103,11 +117,10 @@ bool EmmyFacade::TcpListen(lua_State* L, const std::string& host, int port, std:
103117{
104118 Destroy ();
105119
106- // 仅仅luajit需要
107- mainStates.insert (L);
108-
109120 emmyDebuggerManager->AddDebugger (L);
110121
122+ SetReadyHook (L);
123+
111124 const auto s = std::make_shared<SocketServerTransporter>();
112125 transporter = s;
113126 // s->SetHandler(shared_from_this());
@@ -134,11 +147,10 @@ bool EmmyFacade::TcpConnect(lua_State* L, const std::string& host, int port, std
134147{
135148 Destroy ();
136149
137- // 仅仅luajit需要
138- mainStates.insert (L);
139-
140150 emmyDebuggerManager->AddDebugger (L);
141151
152+ SetReadyHook (L);
153+
142154 const auto c = std::make_shared<SocketClientTransporter>();
143155 transporter = c;
144156 // c->SetHandler(shared_from_this());
@@ -160,11 +172,10 @@ bool EmmyFacade::PipeListen(lua_State* L, const std::string& name, std::string&
160172{
161173 Destroy ();
162174
163- // 仅仅luajit需要
164- mainStates.insert (L);
165-
166175 emmyDebuggerManager->AddDebugger (L);
167176
177+ SetReadyHook (L);
178+
168179 const auto p = std::make_shared<PipelineServerTransporter>();
169180 transporter = p;
170181 // p->SetHandler(shared_from_this());
@@ -176,11 +187,10 @@ bool EmmyFacade::PipeConnect(lua_State* L, const std::string& name, std::string&
176187{
177188 Destroy ();
178189
179- // 仅仅luajit需要
180- mainStates.insert (L);
181-
182190 emmyDebuggerManager->AddDebugger (L);
183191
192+ SetReadyHook (L);
193+
184194 const auto p = std::make_shared<PipelineClientTransporter>();
185195 transporter = p;
186196 // p->SetHandler(shared_from_this());
@@ -318,20 +328,13 @@ void EmmyFacade::OnInitReq(const rapidjson::Document& document)
318328 emmyDebuggerManager->extNames = extNames;
319329 }
320330
321- emmyDebuggerManager->SetRunning (true );
322-
323- // TODO 这里有个线程安全问题,消息线程和lua 执行线程不是相同线程,但是没有一个锁能让我做同步
331+ // 这里有个线程安全问题,消息线程和lua 执行线程不是相同线程,但是没有一个锁能让我做同步
324332 // 所以我不能在这里访问lua state 指针的内部结构
325333 //
326- // 只能在消息线程设置hook
327- // 但是存在一个问题只能给主lua_state 设置hook,如果此后进程一直在协程中执行则无法触发该hook
328- // Attach函数内部设置了hook,存在一个线程问题,可能引发崩溃
329334 // 方案:提前为主state 设置hook 利用hook 实现同步
330- auto debuggers = emmyDebuggerManager->GetDebuggers ();
331- for (auto debugger : debuggers)
332- {
333- debugger->Attach (false );
334- }
335+
336+ // fix 以上安全问题
337+ StartDebug ();
335338}
336339
337340void EmmyFacade::OnReadyReq (const rapidjson::Document& document)
@@ -598,6 +601,20 @@ void EmmyFacade::Hook(lua_State* L, lua_Debug* ar)
598601 {
599602 if (!debugger->IsRunning ())
600603 {
604+ if (EmmyFacade::Get ().GetWorkMode () == WorkMode::EmmyCore)
605+ {
606+ if (luaVersion != LuaVersion::LUA_JIT)
607+ {
608+ if (debugger->IsMainCoroutine (L))
609+ {
610+ SetReadyHook (L);
611+ }
612+ }
613+ else
614+ {
615+ SetReadyHook (L);
616+ }
617+ }
601618 return ;
602619 }
603620
@@ -609,7 +626,8 @@ void EmmyFacade::Hook(lua_State* L, lua_Debug* ar)
609626 {
610627 debugger = emmyDebuggerManager->AddDebugger (L);
611628 install_emmy_core (L);
612- if (emmyDebuggerManager->IsRunning ()) {
629+ if (emmyDebuggerManager->IsRunning ())
630+ {
613631 debugger->Start ();
614632 debugger->Attach ();
615633 }
@@ -666,6 +684,18 @@ std::shared_ptr<Debugger> EmmyFacade::GetDebugger(lua_State* L)
666684 return emmyDebuggerManager->GetDebugger (L);
667685}
668686
687+ void EmmyFacade::SetReadyHook (lua_State* L)
688+ {
689+ lua_sethook (L, ReadyLuaHook, LUA_MASKCALL | LUA_MASKLINE | LUA_MASKRET, 0 );
690+ }
691+
692+ void EmmyFacade::StartDebug ()
693+ {
694+ emmyDebuggerManager->SetRunning (true );
695+ std::lock_guard<std::mutex> lock (EmmyFacade::Get ().readyHookMtx );
696+ EmmyFacade::Get ().readyHook = true ;
697+ }
698+
669699void EmmyFacade::StartupHookMode (int port)
670700{
671701 Destroy ();
0 commit comments