fix: debugger concurrency issues

This commit is contained in:
TopchetoEU 2024-12-28 13:19:53 +02:00
parent 4c53689d9c
commit 9ce0504948
Signed by: topchetoeu
GPG Key ID: 6531B8583E5F6ED4
2 changed files with 58 additions and 45 deletions

View File

@ -159,7 +159,9 @@ public class DebugServer {
} }
public void awaitConnection() throws InterruptedException { public void awaitConnection() throws InterruptedException {
connNotifier.wait(); synchronized (connNotifier) {
connNotifier.wait();
}
} }
public void run(InetSocketAddress address) { public void run(InetSocketAddress address) {

View File

@ -1032,24 +1032,29 @@ public class SimpleDebugger implements Debugger {
} }
mappings.put(body, map); mappings.put(body, map);
} }
private boolean instructionLock;
@Override public boolean onInstruction(Environment env, Frame cf, Instruction instruction, Value returnVal, EngineException error, boolean caught) { @Override public boolean onInstruction(Environment env, Frame cf, Instruction instruction, Value returnVal, EngineException error, boolean caught) {
if (!enabled) return false; if (!enabled) return false;
if (instructionLock) return false;
instructionLock = true;
boolean isBreakpointable; try {
Location loc; boolean isBreakpointable;
DebugFrame frame; Location loc;
BreakpointType bptType; DebugFrame frame;
BreakpointType bptType;
synchronized (this) {
frame = getFrame(cf); frame = getFrame(cf);
var map = DebugContext.get(env).getMap(frame.frame.function); var map = DebugContext.get(env).getMap(frame.frame.function);
frame.updateLoc(map.toLocation(frame.frame.codePtr)); frame.updateLoc(map.toLocation(frame.frame.codePtr));
loc = frame.location; loc = frame.location;
bptType = map.getBreakpoint(frame.frame.codePtr); bptType = map.getBreakpoint(frame.frame.codePtr);
isBreakpointable = loc != null && (bptType.shouldStepIn()); isBreakpointable = loc != null && (bptType.shouldStepIn());
if (error != null && (execptionType == CatchType.ALL || execptionType == CatchType.UNCAUGHT && !caught)) { if (error != null && (execptionType == CatchType.ALL || execptionType == CatchType.UNCAUGHT && !caught)) {
pauseException(env, error); pauseException(env, error);
} }
@ -1077,49 +1082,55 @@ public class SimpleDebugger implements Debugger {
instruction.params.length == 1 && instruction.params.length == 1 &&
instruction.get(0).equals("debug") instruction.get(0).equals("debug")
) pauseDebug(env, null); ) pauseDebug(env, null);
}
while (enabled) {
synchronized (this) { synchronized (this) {
switch (state) { }
case PAUSED_EXCEPTION:
case PAUSED_NORMAL: break; while (enabled) {
synchronized (this) {
case STEPPING_OUT: switch (state) {
case RESUMED: return false; case PAUSED_EXCEPTION:
case PAUSED_NORMAL: break;
case STEPPING_IN:
case STEPPING_OVER: case STEPPING_OUT:
if (stepOutFrame.frame == frame.frame) { case RESUMED: return false;
if (returnVal != null || error != null) {
state = State.STEPPING_OUT; case STEPPING_IN:
continue; case STEPPING_OVER:
} if (stepOutFrame.frame == frame.frame) {
else if (stepOutPtr != frame.frame.codePtr) { if (returnVal != null || error != null) {
state = State.STEPPING_OUT;
if (state == State.STEPPING_IN && bptType.shouldStepIn()) { continue;
pauseDebug(env, null);
break;
} }
else if (state == State.STEPPING_OVER && bptType.shouldStepOver()) { else if (stepOutPtr != frame.frame.codePtr) {
pauseDebug(env, null);
break; if (state == State.STEPPING_IN && bptType.shouldStepIn()) {
pauseDebug(env, null);
break;
}
else if (state == State.STEPPING_OVER && bptType.shouldStepOver()) {
pauseDebug(env, null);
break;
}
} }
} }
} return false;
return false; }
} }
try {
synchronized (updateNotifier) {
updateNotifier.wait();
}
}
catch (InterruptedException e) { Thread.currentThread().interrupt(); }
} }
try { return false;
synchronized (updateNotifier) { }
updateNotifier.wait(); finally {
} instructionLock = false;
}
catch (InterruptedException e) { Thread.currentThread().interrupt(); }
} }
return false;
} }
@Override public synchronized void onFramePush(Environment env, Frame frame) { @Override public synchronized void onFramePush(Environment env, Frame frame) {
var prevFrame = currFrame; var prevFrame = currFrame;