Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,10 @@ class EmmyDebuggerManager

void SetHitDebugger(std::shared_ptr<Debugger> debugger);

// 如果当前没有 hit debugger,pause(Break)请求会被挂起到这里,
// 由下一次任意 debugger 的 hook 触发时消费(原子读+清)。
bool ConsumePendingBreak();

bool IsDebuggerEmpty();

void AddBreakpoint(std::shared_ptr<BreakPoint> breakpoint);
Expand Down Expand Up @@ -100,6 +104,10 @@ class EmmyDebuggerManager
std::mutex breakDebuggerMtx;
std::shared_ptr<Debugger> hitDebugger;

// pause(Break)请求挂起标记: DoAction(Break) 时若无 hitDebugger 就置位,
// hook 路径上首次进入 line 事件时消费。
std::atomic<bool> pendingBreak{false};

std::mutex breakpointsMtx;
std::vector<std::shared_ptr<BreakPoint>> breakpoints;

Expand Down
11 changes: 11 additions & 0 deletions emmy_debugger/src/debugger/emmy_debugger.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,17 @@ void Debugger::Hook(lua_Debug *ar, lua_State *L) {
luaThreadExecutors.clear();
}
}

// 处理 pause: 如果 manager 上有挂起的 Break 请求(DoAction(Break)
// 时无 hitDebugger),这里消费一下,把当前 debugger 设为 hitDebugger,
// 然后走原来的 DoAction(Break) 路径设置 hookState = stateBreak。
// 下面读 hookState 时就会拿到 stateBreak, ProcessHook 在当前 LINE
// 事件上立刻命中 HandleBreak。
if (manager->ConsumePendingBreak()) {
manager->SetHitDebugger(shared_from_this());
DoAction(DebugAction::Break);
}

auto bp = FindBreakPoint(ar);
if (bp && ProcessBreakPoint(bp)) {
HandleBreak();
Expand Down
13 changes: 13 additions & 0 deletions emmy_debugger/src/debugger/emmy_debugger_manager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -215,7 +215,20 @@ void EmmyDebuggerManager::DoAction(DebugAction action)
if (debugger)
{
debugger->DoAction(action);
return;
}
// 还没有 hit debugger: 只有 Break(pause) 在这种情况下有意义,
// 挂起 pending 标记,由下次任意 hook 触发时消费。
// 其它 action(continue/step/stop) 必须在已断下后才有意义,这里直接丢弃。
if (action == DebugAction::Break)
{
pendingBreak.store(true);
}
}

bool EmmyDebuggerManager::ConsumePendingBreak()
{
return pendingBreak.exchange(false);
}

void EmmyDebuggerManager::Eval(std::shared_ptr<EvalContext> ctx)
Expand Down
7 changes: 0 additions & 7 deletions emmy_debugger/src/emmy_facade.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -334,10 +334,6 @@ void EmmyFacade::Hook(lua_State *L, lua_Debug *ar) {
return;
}

// 没人断着时,把当前活跃 vm 记下来,使未断点过的 pause 能定位到目标
if (!_emmyDebuggerManager.GetHitBreakpoint()) {
_emmyDebuggerManager.SetHitDebugger(debugger);
}
debugger->Hook(ar, L);
} else {
if (workMode == WorkMode::Attach) {
Expand All @@ -353,9 +349,6 @@ void EmmyFacade::Hook(lua_State *L, lua_Debug *ar) {

this->transporter->Send(int(MessageCMD::AttachedNotify), obj);

if (!_emmyDebuggerManager.GetHitBreakpoint()) {
_emmyDebuggerManager.SetHitDebugger(debugger);
}
debugger->Hook(ar, L);
}
}
Expand Down