From 877e154463b349a333d7b7fbab691cd4e2c1c40d Mon Sep 17 00:00:00 2001 From: Nipuna Ranasinghe Date: Mon, 21 Oct 2024 23:23:40 +0530 Subject: [PATCH 1/3] Fix Intermittent exceptions when Stepping over code --- .../org/ballerinalang/debugadapter/BreakpointProcessor.java | 6 ++++-- .../org/ballerinalang/debugadapter/JDIEventProcessor.java | 3 ++- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/misc/debug-adapter/modules/debug-adapter-core/src/main/java/org/ballerinalang/debugadapter/BreakpointProcessor.java b/misc/debug-adapter/modules/debug-adapter-core/src/main/java/org/ballerinalang/debugadapter/BreakpointProcessor.java index d0043efada68..f278e2731a55 100644 --- a/misc/debug-adapter/modules/debug-adapter-core/src/main/java/org/ballerinalang/debugadapter/BreakpointProcessor.java +++ b/misc/debug-adapter/modules/debug-adapter-core/src/main/java/org/ballerinalang/debugadapter/BreakpointProcessor.java @@ -250,8 +250,10 @@ void activateDynamicBreakPoints(int threadId, DynamicBreakpointMode mode) { } } catch (JdiProxyException e) { LOGGER.error(e.getMessage()); - int stepType = ((StepRequest) jdiEventProcessor.getStepRequests().get(0)).depth(); - jdiEventProcessor.sendStepRequest(threadId, stepType); + if (!jdiEventProcessor.getStepRequests().isEmpty()) { + int stepType = ((StepRequest) jdiEventProcessor.getStepRequests().get(0)).depth(); + jdiEventProcessor.sendStepRequest(threadId, stepType); + } } } diff --git a/misc/debug-adapter/modules/debug-adapter-core/src/main/java/org/ballerinalang/debugadapter/JDIEventProcessor.java b/misc/debug-adapter/modules/debug-adapter-core/src/main/java/org/ballerinalang/debugadapter/JDIEventProcessor.java index 93722428b10b..37b8a123888a 100755 --- a/misc/debug-adapter/modules/debug-adapter-core/src/main/java/org/ballerinalang/debugadapter/JDIEventProcessor.java +++ b/misc/debug-adapter/modules/debug-adapter-core/src/main/java/org/ballerinalang/debugadapter/JDIEventProcessor.java @@ -42,6 +42,7 @@ import java.util.LinkedHashMap; import java.util.List; import java.util.concurrent.CompletableFuture; +import java.util.concurrent.CopyOnWriteArrayList; import static org.ballerinalang.debugadapter.BreakpointProcessor.DynamicBreakpointMode; import static org.ballerinalang.debugadapter.JBallerinaDebugServer.isBalStackFrame; @@ -55,7 +56,7 @@ public class JDIEventProcessor { private final ExecutionContext context; private final BreakpointProcessor breakpointProcessor; private boolean isRemoteVmAttached = false; - private final List stepRequests = new ArrayList<>(); + private final List stepRequests = new CopyOnWriteArrayList<>(); private static final Logger LOGGER = LoggerFactory.getLogger(JDIEventProcessor.class); JDIEventProcessor(ExecutionContext context) { From e41037c22f9d936750b2d038d61bc8a26995ce9c Mon Sep 17 00:00:00 2001 From: Nipuna Ranasinghe Date: Tue, 22 Oct 2024 14:36:18 +0530 Subject: [PATCH 2/3] Fix NPE when setting breakpoints --- .../debugadapter/BreakpointProcessor.java | 6 ++-- .../debugadapter/JBallerinaDebugServer.java | 33 ++++++++++++------- 2 files changed, 25 insertions(+), 14 deletions(-) diff --git a/misc/debug-adapter/modules/debug-adapter-core/src/main/java/org/ballerinalang/debugadapter/BreakpointProcessor.java b/misc/debug-adapter/modules/debug-adapter-core/src/main/java/org/ballerinalang/debugadapter/BreakpointProcessor.java index f278e2731a55..9d0b8b935ad2 100644 --- a/misc/debug-adapter/modules/debug-adapter-core/src/main/java/org/ballerinalang/debugadapter/BreakpointProcessor.java +++ b/misc/debug-adapter/modules/debug-adapter-core/src/main/java/org/ballerinalang/debugadapter/BreakpointProcessor.java @@ -45,12 +45,12 @@ import java.util.ArrayList; import java.util.Comparator; -import java.util.HashMap; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Optional; import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; @@ -68,7 +68,7 @@ public class BreakpointProcessor { private final ExecutionContext context; private final JDIEventProcessor jdiEventProcessor; - private final Map> userBreakpoints = new HashMap<>(); + private final Map> userBreakpoints = new ConcurrentHashMap<>(); private static final Logger LOGGER = LoggerFactory.getLogger(BreakpointProcessor.class); public BreakpointProcessor(ExecutionContext context, JDIEventProcessor jdiEventProcessor) { @@ -77,7 +77,7 @@ public BreakpointProcessor(ExecutionContext context, JDIEventProcessor jdiEventP } public Map> getUserBreakpoints() { - return Map.copyOf(userBreakpoints); + return userBreakpoints; } /** diff --git a/misc/debug-adapter/modules/debug-adapter-core/src/main/java/org/ballerinalang/debugadapter/JBallerinaDebugServer.java b/misc/debug-adapter/modules/debug-adapter-core/src/main/java/org/ballerinalang/debugadapter/JBallerinaDebugServer.java index 6c4bcdb776b3..d6ac96287dbe 100755 --- a/misc/debug-adapter/modules/debug-adapter-core/src/main/java/org/ballerinalang/debugadapter/JBallerinaDebugServer.java +++ b/misc/debug-adapter/modules/debug-adapter-core/src/main/java/org/ballerinalang/debugadapter/JBallerinaDebugServer.java @@ -224,19 +224,30 @@ public CompletableFuture setBreakpoints(SetBreakpointsAr breakpointsMap.put(bp.getLine(), bp); } - SetBreakpointsResponse breakpointsResponse = new SetBreakpointsResponse(); + SetBreakpointsResponse bpResponse = new SetBreakpointsResponse(); String sourcePathUri = args.getSource().getPath(); Optional qualifiedClassName = getQualifiedClassName(context, sourcePathUri); - qualifiedClassName.ifPresent(className -> { - eventProcessor.enableBreakpoints(className, breakpointsMap); - BreakpointProcessor breakpointProcessor = eventProcessor.getBreakpointProcessor(); - Breakpoint[] breakpoints = breakpointProcessor.getUserBreakpoints().get(qualifiedClassName.get()) - .values().stream() - .map(BalBreakpoint::getAsDAPBreakpoint) - .toArray(Breakpoint[]::new); - breakpointsResponse.setBreakpoints(breakpoints); - }); - return breakpointsResponse; + + if (qualifiedClassName.isEmpty()) { + LOGGER.warn("Failed to set breakpoints. Source path is not a valid Ballerina source: " + sourcePathUri); + return bpResponse; + } + + eventProcessor.enableBreakpoints(qualifiedClassName.get(), breakpointsMap); + BreakpointProcessor bpProcessor = eventProcessor.getBreakpointProcessor(); + Map userBpMap = bpProcessor.getUserBreakpoints().get(qualifiedClassName.get()); + + if (userBpMap == null) { + LOGGER.warn("Failed to set breakpoints for source: " + sourcePathUri); + return bpResponse; + } + + Breakpoint[] breakpoints = userBpMap.values().stream() + .map(BalBreakpoint::getAsDAPBreakpoint) + .toArray(Breakpoint[]::new); + + bpResponse.setBreakpoints(breakpoints); + return bpResponse; }); } From 68e12c336950f9bb1a7d9f9bf3b44e2fb06389cd Mon Sep 17 00:00:00 2001 From: Nipuna Ranasinghe Date: Tue, 22 Oct 2024 22:03:00 +0530 Subject: [PATCH 3/3] Improve formatting --- .../org/ballerinalang/debugadapter/JBallerinaDebugServer.java | 3 --- 1 file changed, 3 deletions(-) diff --git a/misc/debug-adapter/modules/debug-adapter-core/src/main/java/org/ballerinalang/debugadapter/JBallerinaDebugServer.java b/misc/debug-adapter/modules/debug-adapter-core/src/main/java/org/ballerinalang/debugadapter/JBallerinaDebugServer.java index d6ac96287dbe..b6d854e42bf6 100755 --- a/misc/debug-adapter/modules/debug-adapter-core/src/main/java/org/ballerinalang/debugadapter/JBallerinaDebugServer.java +++ b/misc/debug-adapter/modules/debug-adapter-core/src/main/java/org/ballerinalang/debugadapter/JBallerinaDebugServer.java @@ -227,7 +227,6 @@ public CompletableFuture setBreakpoints(SetBreakpointsAr SetBreakpointsResponse bpResponse = new SetBreakpointsResponse(); String sourcePathUri = args.getSource().getPath(); Optional qualifiedClassName = getQualifiedClassName(context, sourcePathUri); - if (qualifiedClassName.isEmpty()) { LOGGER.warn("Failed to set breakpoints. Source path is not a valid Ballerina source: " + sourcePathUri); return bpResponse; @@ -236,7 +235,6 @@ public CompletableFuture setBreakpoints(SetBreakpointsAr eventProcessor.enableBreakpoints(qualifiedClassName.get(), breakpointsMap); BreakpointProcessor bpProcessor = eventProcessor.getBreakpointProcessor(); Map userBpMap = bpProcessor.getUserBreakpoints().get(qualifiedClassName.get()); - if (userBpMap == null) { LOGGER.warn("Failed to set breakpoints for source: " + sourcePathUri); return bpResponse; @@ -245,7 +243,6 @@ public CompletableFuture setBreakpoints(SetBreakpointsAr Breakpoint[] breakpoints = userBpMap.values().stream() .map(BalBreakpoint::getAsDAPBreakpoint) .toArray(Breakpoint[]::new); - bpResponse.setBreakpoints(breakpoints); return bpResponse; });