fix: debugger concurrency issues
This commit is contained in:
parent
4c53689d9c
commit
9ce0504948
@ -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) {
|
||||||
|
@ -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;
|
||||||
|
Loading…
Reference in New Issue
Block a user