From 814d7ae76ae35d839c936853232e01a0a368944b Mon Sep 17 00:00:00 2001 From: hindujaB Date: Wed, 2 Oct 2024 08:38:12 +0530 Subject: [PATCH 01/11] Move java 21 as first JVM target --- .../src/main/java/io/ballerina/projects/JvmTarget.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/compiler/ballerina-lang/src/main/java/io/ballerina/projects/JvmTarget.java b/compiler/ballerina-lang/src/main/java/io/ballerina/projects/JvmTarget.java index ae204f0ad314..c249850d1aa7 100644 --- a/compiler/ballerina-lang/src/main/java/io/ballerina/projects/JvmTarget.java +++ b/compiler/ballerina-lang/src/main/java/io/ballerina/projects/JvmTarget.java @@ -24,10 +24,9 @@ */ // TODO move this class to a separate Java package. e.g. io.ballerina.projects.platform.jballerina public enum JvmTarget implements CompilerBackend.TargetPlatform { - JAVA_17("java17"), JAVA_21("java21"), + JAVA_17("java17"), JAVA_11("java11"); - // TODO need to move java21 to the top when the central issue #2792 is fixed private final String code; From 77dc71058033fe0411b65bc8d380ff8dce78d9c1 Mon Sep 17 00:00:00 2001 From: hindujaB Date: Wed, 2 Oct 2024 08:39:01 +0530 Subject: [PATCH 02/11] Fix call stack test --- .../debug-adapter-runtime/src/main/ballerina/Ballerina.toml | 1 + .../debugger/test/adapter/CallStackDebugTest.java | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/misc/debug-adapter/modules/debug-adapter-runtime/src/main/ballerina/Ballerina.toml b/misc/debug-adapter/modules/debug-adapter-runtime/src/main/ballerina/Ballerina.toml index 1ae31a2723c6..6b214548e90a 100644 --- a/misc/debug-adapter/modules/debug-adapter-runtime/src/main/ballerina/Ballerina.toml +++ b/misc/debug-adapter/modules/debug-adapter-runtime/src/main/ballerina/Ballerina.toml @@ -2,4 +2,5 @@ org = "ballerina" name = "debugger_helpers" version = "1.0.0" + [[platform.java21.dependency]] diff --git a/tests/jballerina-debugger-integration-test/src/test/java/org/ballerinalang/debugger/test/adapter/CallStackDebugTest.java b/tests/jballerina-debugger-integration-test/src/test/java/org/ballerinalang/debugger/test/adapter/CallStackDebugTest.java index 3974ec5f0036..44e91b884a5b 100644 --- a/tests/jballerina-debugger-integration-test/src/test/java/org/ballerinalang/debugger/test/adapter/CallStackDebugTest.java +++ b/tests/jballerina-debugger-integration-test/src/test/java/org/ballerinalang/debugger/test/adapter/CallStackDebugTest.java @@ -65,7 +65,7 @@ public void stackFrameDebugTest() throws BallerinaTestException { debugTestRunner.assertCallStack(frames[2], "func2", 23, "main.bal"); debugTestRunner.assertCallStack(frames[3], "func1", 19, "main.bal"); debugTestRunner.assertCallStack(frames[4], "addition", 14, "main.bal"); - debugTestRunner.assertCallStack(frames[5], "start:anonymous", 2, "main.bal"); + debugTestRunner.assertCallStack(frames[5], "start:f1", 2, "main.bal"); debugTestRunner.resumeProgram(debugHitInfo.getRight(), DebugResumeKind.NEXT_BREAKPOINT); debugHitInfo = debugTestRunner.waitForDebugHit(10000); @@ -83,7 +83,7 @@ public void stackFrameDebugTest() throws BallerinaTestException { // Stack frame representation test for strand creation with 'start' keyword. // Results of the strand is not assigned to any variable. In this case frame name is assigned to 'anonymous'. debugTestRunner.assertCallStack(frames[0], "sayHello", 45, "main.bal"); - debugTestRunner.assertCallStack(frames[1], "start:anonymous", 10, "main.bal"); + debugTestRunner.assertCallStack(frames[1], "start:anon", 10, "main.bal"); } @Test From ac0ffe4bc33bc85fc8a5457647644de5ea158e67 Mon Sep 17 00:00:00 2001 From: hindujaB Date: Wed, 2 Oct 2024 08:39:42 +0530 Subject: [PATCH 03/11] Fix control flow test --- .../io/ballerina/runtime/internal/ClassloaderRuntime.java | 7 +++++++ .../debugger/test/adapter/ControlFlowDebugTest.java | 3 +-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/ClassloaderRuntime.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/ClassloaderRuntime.java index 6c5f8b8ce3f9..d1ced5c7289e 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/ClassloaderRuntime.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/ClassloaderRuntime.java @@ -17,6 +17,7 @@ package io.ballerina.runtime.internal; import io.ballerina.runtime.api.Module; +import io.ballerina.runtime.internal.values.ValueCreator; /** * This class represents the Ballerina runtime that is created using a classloader for internal purposes. @@ -37,4 +38,10 @@ Class loadClass(String className) throws ClassNotFoundException { String name = getFullQualifiedClassName(rootModule, className); return Class.forName(name, true, classLoader); } + + @Override + public void stop() { + super.stop(); + ValueCreator.removeValueCreator(rootModule); + } } diff --git a/tests/jballerina-debugger-integration-test/src/test/java/org/ballerinalang/debugger/test/adapter/ControlFlowDebugTest.java b/tests/jballerina-debugger-integration-test/src/test/java/org/ballerinalang/debugger/test/adapter/ControlFlowDebugTest.java index e69f778791b4..6c3dcc4166e5 100644 --- a/tests/jballerina-debugger-integration-test/src/test/java/org/ballerinalang/debugger/test/adapter/ControlFlowDebugTest.java +++ b/tests/jballerina-debugger-integration-test/src/test/java/org/ballerinalang/debugger/test/adapter/ControlFlowDebugTest.java @@ -177,8 +177,7 @@ public void testControlFlowDebugScenarios() throws BallerinaTestException { debugTestRunner.assertVariable(variables, "v10_future", "future", "future"); // Variable visibility test for Asynchronous function call child variables - Map asyncChildVariables = debugTestRunner.fetchChildVariables(variables.get("v10_future")); - debugTestRunner.assertVariable(asyncChildVariables, "result", "90", "int"); + debugTestRunner.assertVariable(variables, "result", "90", "int"); } @AfterMethod(alwaysRun = true) From 72193bdcdcc6ff8cfacbdc109371c719b660c4ee Mon Sep 17 00:00:00 2001 From: hindujaB Date: Wed, 2 Oct 2024 08:41:05 +0530 Subject: [PATCH 04/11] Fix failing debugger tests --- .../runtime/internal/values/ValueCreator.java | 5 +++ .../src/main/java/module-info.java | 3 +- .../invokable/GeneratedStaticMethod.java | 3 -- .../variables/VariableVisibilityTest.java | 37 ++++++++++++------- .../control-flow-tests/main.bal | 2 +- .../evaluation-tests-1/main.bal | 2 +- 6 files changed, 33 insertions(+), 19 deletions(-) diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/values/ValueCreator.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/values/ValueCreator.java index 8b36c63775d0..f9ca05a08071 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/values/ValueCreator.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/values/ValueCreator.java @@ -97,6 +97,11 @@ public static ValueCreator getValueCreator(String key) { return runtimeValueCreators.get(key); } + public static void removeValueCreator(Module rootModule) { + String key = getLookupKey(rootModule, false); + runtimeValueCreators.remove(key); + } + public Object call(Strand strand, String funcName, Object... args) throws BError { throw new ErrorValue(StringUtils.fromString("No such method: " + funcName)); } diff --git a/bvm/ballerina-runtime/src/main/java/module-info.java b/bvm/ballerina-runtime/src/main/java/module-info.java index 6fac73df7ed5..19152c5a9228 100644 --- a/bvm/ballerina-runtime/src/main/java/module-info.java +++ b/bvm/ballerina-runtime/src/main/java/module-info.java @@ -43,7 +43,8 @@ io.ballerina.lang.table, io.ballerina.lang.value, io.ballerina.lang.xml, ballerina.debug.adapter.core, io.ballerina.cli, io.ballerina.lang.integer, io.ballerina.lang.bool, io.ballerina.lang.decimal, io.ballerina.lang.floatingpoint, io.ballerina.lang.internal, io.ballerina.lang.function, - io.ballerina.lang.regexp, io.ballerina.runtime.profiler, io.ballerina.shell; + io.ballerina.lang.regexp, io.ballerina.runtime.profiler, io.ballerina.shell, + org.ballerinalang.debugadapter.runtime; exports io.ballerina.runtime.internal.commons to io.ballerina.lang.value; exports io.ballerina.runtime.internal.launch to io.ballerina.testerina.runtime, io.ballerina.packerina, ballerina.test.listener, io.ballerina.cli, org.ballerinalang.debugadapter.runtime; diff --git a/misc/debug-adapter/modules/debug-adapter-core/src/main/java/org/ballerinalang/debugadapter/evaluation/engine/invokable/GeneratedStaticMethod.java b/misc/debug-adapter/modules/debug-adapter-core/src/main/java/org/ballerinalang/debugadapter/evaluation/engine/invokable/GeneratedStaticMethod.java index 408a85a919db..133cee7acb1d 100644 --- a/misc/debug-adapter/modules/debug-adapter-core/src/main/java/org/ballerinalang/debugadapter/evaluation/engine/invokable/GeneratedStaticMethod.java +++ b/misc/debug-adapter/modules/debug-adapter-core/src/main/java/org/ballerinalang/debugadapter/evaluation/engine/invokable/GeneratedStaticMethod.java @@ -30,7 +30,6 @@ import static org.ballerinalang.debugadapter.evaluation.EvaluationException.createEvaluationException; import static org.ballerinalang.debugadapter.evaluation.EvaluationExceptionKind.FUNCTION_EXECUTION_ERROR; import static org.ballerinalang.debugadapter.evaluation.utils.EvaluationUtils.B_DEBUGGER_RUNTIME_CLASS; -import static org.ballerinalang.debugadapter.evaluation.utils.EvaluationUtils.B_SCHEDULER_CLASS; import static org.ballerinalang.debugadapter.evaluation.utils.EvaluationUtils.INVOKE_FUNCTION_ASYNC; import static org.ballerinalang.debugadapter.evaluation.utils.EvaluationUtils.JAVA_LANG_CLASSLOADER; import static org.ballerinalang.debugadapter.evaluation.utils.EvaluationUtils.JAVA_OBJECT_ARRAY_CLASS; @@ -58,7 +57,6 @@ protected Value invoke() throws EvaluationException { } List argTypeList = new ArrayList<>(); argTypeList.add(JAVA_LANG_CLASSLOADER); - argTypeList.add(B_SCHEDULER_CLASS); argTypeList.add(JAVA_STRING_CLASS); argTypeList.add(JAVA_STRING_CLASS); argTypeList.add(JAVA_OBJECT_ARRAY_CLASS); @@ -67,7 +65,6 @@ protected Value invoke() throws EvaluationException { List scheduleMethodArgs = new ArrayList<>(); scheduleMethodArgs.add(context.getDebuggeeClassLoader()); - scheduleMethodArgs.add(null); scheduleMethodArgs.add(EvaluationUtils.getAsJString(context, classRef.name())); scheduleMethodArgs.add(EvaluationUtils.getAsJString(context, methodRef.name())); scheduleMethodArgs.addAll(getMethodArgs(this)); diff --git a/tests/jballerina-debugger-integration-test/src/test/java/org/ballerinalang/debugger/test/adapter/variables/VariableVisibilityTest.java b/tests/jballerina-debugger-integration-test/src/test/java/org/ballerinalang/debugger/test/adapter/variables/VariableVisibilityTest.java index 33b8147939fb..e7f998b451e7 100644 --- a/tests/jballerina-debugger-integration-test/src/test/java/org/ballerinalang/debugger/test/adapter/variables/VariableVisibilityTest.java +++ b/tests/jballerina-debugger-integration-test/src/test/java/org/ballerinalang/debugger/test/adapter/variables/VariableVisibilityTest.java @@ -518,19 +518,30 @@ public void workerVariableVisibilityTest() throws BallerinaTestException { debugTestRunner.addBreakPoint(new BallerinaTestDebugPoint(debugTestRunner.testEntryFilePath, 31)); debugTestRunner.initDebugSession(DebugUtils.DebuggeeExecutionKind.RUN); Pair debugHitInfo = debugTestRunner.waitForDebugHit(25000); - - // variable visibility test for workers outside fork (workers are visible outside fork() as futures). - localVariables = debugTestRunner.fetchVariables(debugHitInfo.getRight(), DebugTestRunner.VariableScope.LOCAL); - debugTestRunner.assertVariable(localVariables, "w1", "future<()>", "future"); - - // variable visibility test inside worker (only worker's variables should be visible). - debugTestRunner.resumeProgram(debugHitInfo.getRight(), DebugTestRunner.DebugResumeKind.NEXT_BREAKPOINT); - debugHitInfo = debugTestRunner.waitForDebugHit(10000); - localVariables = debugTestRunner.fetchVariables(debugHitInfo.getRight(), DebugTestRunner.VariableScope.LOCAL); - debugTestRunner.assertVariable(localVariables, "x", "10", "int"); - - // variables outside worker should not be visible - Assert.assertFalse(localVariables.containsKey("a")); + if (debugHitInfo.getKey().getLine() == 23) { + // variable visibility test inside worker (only worker's variables should be visible) + localVariables = debugTestRunner.fetchVariables(debugHitInfo.getRight(), DebugTestRunner.VariableScope.LOCAL); + debugTestRunner.assertVariable(localVariables, "x", "10", "int"); + // variables outside worker should not be visible + Assert.assertFalse(localVariables.containsKey("a")); + // variable visibility test for workers outside fork (workers are visible outside fork() as futures). + debugTestRunner.resumeProgram(debugHitInfo.getRight(), DebugTestRunner.DebugResumeKind.NEXT_BREAKPOINT); + debugHitInfo = debugTestRunner.waitForDebugHit(10000); + localVariables = debugTestRunner.fetchVariables(debugHitInfo.getRight(), DebugTestRunner.VariableScope.LOCAL); + debugTestRunner.assertVariable(localVariables, "w1", "future<()>", "future"); + Assert.assertTrue(localVariables.containsKey("a")); + } else { + // variable visibility test for workers outside fork (workers are visible outside fork() as futures). + localVariables = debugTestRunner.fetchVariables(debugHitInfo.getRight(), DebugTestRunner.VariableScope.LOCAL); + debugTestRunner.assertVariable(localVariables, "w1", "future<()>", "future"); + Assert.assertTrue(localVariables.containsKey("a")); + debugTestRunner.resumeProgram(debugHitInfo.getRight(), DebugTestRunner.DebugResumeKind.NEXT_BREAKPOINT); + debugHitInfo = debugTestRunner.waitForDebugHit(10000); + localVariables = debugTestRunner.fetchVariables(debugHitInfo.getRight(), DebugTestRunner.VariableScope.LOCAL); + debugTestRunner.assertVariable(localVariables, "x", "10", "int"); + // variables outside worker should not be visible + Assert.assertFalse(localVariables.containsKey("a")); + } } @AfterMethod(alwaysRun = true) diff --git a/tests/jballerina-debugger-integration-test/src/test/resources/project-based-tests/control-flow-tests/main.bal b/tests/jballerina-debugger-integration-test/src/test/resources/project-based-tests/control-flow-tests/main.bal index 16820baedf2c..5895b3e94d53 100644 --- a/tests/jballerina-debugger-integration-test/src/test/resources/project-based-tests/control-flow-tests/main.bal +++ b/tests/jballerina-debugger-integration-test/src/test/resources/project-based-tests/control-flow-tests/main.bal @@ -61,7 +61,7 @@ public function main() { // debug engage in Asynchronous function call (Non-blocking calls) future v10_future = start sum(40, 50); - _ = checkpanic wait v10_future; + int result = checkpanic wait v10_future; } function sum(int a, int b) returns int { diff --git a/tests/jballerina-debugger-integration-test/src/test/resources/project-based-tests/evaluation-tests-1/main.bal b/tests/jballerina-debugger-integration-test/src/test/resources/project-based-tests/evaluation-tests-1/main.bal index afa26c85b388..9c2b7ccf0732 100644 --- a/tests/jballerina-debugger-integration-test/src/test/resources/project-based-tests/evaluation-tests-1/main.bal +++ b/tests/jballerina-debugger-integration-test/src/test/resources/project-based-tests/evaluation-tests-1/main.bal @@ -172,7 +172,7 @@ json jsonValue = {name: "John", age: 20}; var '\ \/\:\@\[\`\{\~\u{03C0}_IL = "IL with global var"; // configurable variables -configurable int port = ?; +configurable int port = 9090; // let expression helper declarations const globalVar = 2; From 5ce545b197bf25d27bbdf0da330a05ad0645aadb Mon Sep 17 00:00:00 2001 From: hindujaB Date: Thu, 3 Oct 2024 20:36:28 +0530 Subject: [PATCH 05/11] Add virtual threads to debugger --- .../debugadapter/JBallerinaDebugServer.java | 6 +++ .../debugadapter/JDIEventProcessor.java | 22 ++++++++ .../debugadapter/runtime/DebuggerRuntime.java | 52 +++++++++---------- 3 files changed, 54 insertions(+), 26 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 9906616e1777..c3d919f91166 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 @@ -951,6 +951,10 @@ Map getAllThreads() { threadsMap.put((int) threadReference.uniqueID(), new ThreadReferenceProxyImpl(context.getDebuggeeVM(), threadReference)); } + for (ThreadReference threadReference: eventProcessor.getVirtualThreads()) { + threadsMap.put((int) threadReference.uniqueID(), new ThreadReferenceProxyImpl(context.getDebuggeeVM(), + threadReference)); + } return threadsMap; } @@ -1105,6 +1109,8 @@ private void attachToRemoteVM(String hostName, int portName) throws IOException, EventRequestManager erm = context.getEventManager(); ClassPrepareRequest classPrepareRequest = erm.createClassPrepareRequest(); classPrepareRequest.enable(); + erm.createThreadStartRequest().enable(); + erm.createThreadDeathRequest().enable(); eventProcessor.startListening(); } 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 218a9aa8a0b3..9aadefad217d 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 @@ -18,6 +18,7 @@ import com.sun.jdi.AbsentInformationException; import com.sun.jdi.Location; +import com.sun.jdi.ThreadReference; import com.sun.jdi.VMDisconnectedException; import com.sun.jdi.event.BreakpointEvent; import com.sun.jdi.event.ClassPrepareEvent; @@ -25,6 +26,8 @@ import com.sun.jdi.event.EventIterator; import com.sun.jdi.event.EventSet; import com.sun.jdi.event.StepEvent; +import com.sun.jdi.event.ThreadDeathEvent; +import com.sun.jdi.event.ThreadStartEvent; import com.sun.jdi.event.VMDeathEvent; import com.sun.jdi.event.VMDisconnectEvent; import com.sun.jdi.request.EventRequest; @@ -57,6 +60,7 @@ public class JDIEventProcessor { private boolean isRemoteVmAttached = false; private final List stepRequests = new ArrayList<>(); private static final Logger LOGGER = LoggerFactory.getLogger(JDIEventProcessor.class); + private static final List virtualThreads = new ArrayList<>(); JDIEventProcessor(ExecutionContext context) { this.context = context; @@ -71,6 +75,10 @@ List getStepRequests() { return stepRequests; } + List getVirtualThreads() { + return virtualThreads; + } + /** * Asynchronously listens and processes the incoming JDI events. */ @@ -121,6 +129,20 @@ private void processEvent(EventSet eventSet, Event event) { || event instanceof VMDeathEvent || event instanceof VMDisconnectedException) { isRemoteVmAttached = false; + } else if (event instanceof ThreadStartEvent threadStartEvent) { + ThreadReference thread = threadStartEvent.thread(); + if (thread.isVirtual()) { + synchronized (virtualThreads) { + virtualThreads.add(thread); + } + } + eventSet.resume(); + } else if (event instanceof ThreadDeathEvent threadDeathEvent) { + ThreadReference thread = threadDeathEvent.thread(); + synchronized (virtualThreads) { + virtualThreads.remove(thread); + } + eventSet.resume(); } else { eventSet.resume(); } diff --git a/misc/debug-adapter/modules/debug-adapter-runtime/src/main/java/org/ballerinalang/debugadapter/runtime/DebuggerRuntime.java b/misc/debug-adapter/modules/debug-adapter-runtime/src/main/java/org/ballerinalang/debugadapter/runtime/DebuggerRuntime.java index 671cb18c9e6f..5a13f7bd78d2 100644 --- a/misc/debug-adapter/modules/debug-adapter-runtime/src/main/java/org/ballerinalang/debugadapter/runtime/DebuggerRuntime.java +++ b/misc/debug-adapter/modules/debug-adapter-runtime/src/main/java/org/ballerinalang/debugadapter/runtime/DebuggerRuntime.java @@ -38,8 +38,8 @@ import io.ballerina.runtime.api.values.BValue; import io.ballerina.runtime.api.values.BXml; import io.ballerina.runtime.api.values.BXmlSequence; -import io.ballerina.runtime.internal.configurable.providers.ConfigDetails; -import io.ballerina.runtime.internal.launch.LaunchUtils; +import io.ballerina.runtime.internal.BalRuntime; +import io.ballerina.runtime.internal.ClassloaderRuntime; import io.ballerina.runtime.internal.scheduling.Strand; import io.ballerina.runtime.internal.types.BAnnotatableType; import io.ballerina.runtime.internal.values.ErrorValue; @@ -54,13 +54,11 @@ import java.lang.reflect.Method; import java.net.URL; import java.net.URLClassLoader; -import java.nio.file.Path; import java.nio.file.Paths; import java.security.AccessController; import java.security.PrivilegedAction; import java.util.ArrayList; import java.util.Arrays; -import java.util.HashMap; import java.util.List; import java.util.Map; @@ -114,7 +112,6 @@ public static Object invokeObjectMethod(BObject bObject, String methodName, Obje /** * Invoke Ballerina functions in blocking manner. - * * @param classLoader normal classLoader * @param className which the function resides/ or file name * @param methodName to be invokable unit @@ -340,11 +337,6 @@ private static BString[] processXMLNamePattern(String xmlNamePattern) { public static Object classloadAndInvokeFunction(String executablePath, String mainClass, String functionName, Object... userArgs) { try { - // Need to pass the strand (or null) as the first argument for the generated function. - List functionArgs = new ArrayList<>(); - functionArgs.add(null); - functionArgs.addAll(Arrays.asList(userArgs)); - URL pathUrl = Paths.get(executablePath).toUri().toURL(); URLClassLoader classLoader = AccessController.doPrivileged((PrivilegedAction) () -> new URLClassLoader(new URL[]{pathUrl}, ClassLoader.getSystemClassLoader())); @@ -354,26 +346,34 @@ public static Object classloadAndInvokeFunction(String executablePath, String ma String packageOrg = mainClassNameParts[0]; String packageName = mainClassNameParts[1]; String packageVersion = mainClassNameParts[2]; - String packageNameSpace = String.join(".", packageOrg, packageName, packageVersion); - + Module module = new Module(packageOrg, packageName, packageVersion, false); + return invokeBalRuntimeMethod(functionName, module, classLoader, userArgs); + } catch (Exception e) { + return e.getMessage(); + } + } - // Initialize configurations - ConfigDetails configurationDetails = LaunchUtils.getConfigurationDetails(); - invokeMethodDirectly(classLoader, String.join(".", packageNameSpace, CONFIGURE_INIT_CLASS_NAME), - CONFIGURE_INIT_METHOD_NAME, new Class[]{Map.class, String[].class, Path[].class, String.class}, - new Object[]{new HashMap<>(), new String[]{}, configurationDetails.paths, - configurationDetails.configContent}); + private static Object invokeBalRuntimeMethod(String functionName, Module module, ClassLoader classLoader, Object[] paramValues) { + BalRuntime runtime = new ClassloaderRuntime(module, classLoader); + Object result; + try { // Initialize the module - invokeFunction(classLoader, String.join(".", packageNameSpace, MODULE_INIT_CLASS_NAME), - MODULE_INIT_METHOD_NAME, new Object[1]); + runtime.init(); // Start the module - invokeFunction(classLoader, String.join(".", packageNameSpace, MODULE_INIT_CLASS_NAME), - MODULE_START_METHOD_NAME, new Object[1]); - // Run the actual method - return invokeFunction(classLoader, mainClass, functionName, functionArgs.toArray()); - } catch (Exception e) { - return e.getMessage(); + runtime.start(); + // Then call run method + result = runtime.call(module, functionName, paramValues); + } catch (Throwable throwable) { + throw ErrorCreator.createError(StringUtils.fromString("'" + functionName + "' function " + + "invocation failed : " + throwable.getMessage())); + } finally { + try { + runtime.stop(); + } catch (BError ignored) { + // stop errors are ignored + } } + return result; } /** From a11e7f2419d7dd2cd2e2628f13180607b25ea8c8 Mon Sep 17 00:00:00 2001 From: hindujaB Date: Thu, 3 Oct 2024 23:22:49 +0530 Subject: [PATCH 06/11] Modify failing conditional breakpoints --- .../test/adapter/ConditionalBreakpointTest.java | 16 +++++++++------- .../debugger/test/adapter/LogPointTest.java | 4 +++- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/tests/jballerina-debugger-integration-test/src/test/java/org/ballerinalang/debugger/test/adapter/ConditionalBreakpointTest.java b/tests/jballerina-debugger-integration-test/src/test/java/org/ballerinalang/debugger/test/adapter/ConditionalBreakpointTest.java index 9f55b222d0a0..e7aa36f24938 100644 --- a/tests/jballerina-debugger-integration-test/src/test/java/org/ballerinalang/debugger/test/adapter/ConditionalBreakpointTest.java +++ b/tests/jballerina-debugger-integration-test/src/test/java/org/ballerinalang/debugger/test/adapter/ConditionalBreakpointTest.java @@ -57,13 +57,15 @@ public void testConditionalBreakpointScenarios() throws BallerinaTestException { debugTestRunner.addBreakPoint(new BallerinaTestDebugPoint(filePath, 49, "x != 100", null)); debugTestRunner.addBreakPoint(new BallerinaTestDebugPoint(filePath, 51, "e1 === e2", null)); debugTestRunner.addBreakPoint(new BallerinaTestDebugPoint(filePath, 52, "e1 !== e3", null)); - debugTestRunner.addBreakPoint(new BallerinaTestDebugPoint(filePath, 53, "x > 0", null)); - debugTestRunner.addBreakPoint(new BallerinaTestDebugPoint(filePath, 54, "x >= 0", null)); - debugTestRunner.addBreakPoint(new BallerinaTestDebugPoint(filePath, 55, "y < 0", null)); - debugTestRunner.addBreakPoint(new BallerinaTestDebugPoint(filePath, 56, "y <= 0", null)); - debugTestRunner.addBreakPoint(new BallerinaTestDebugPoint(filePath, 57, "x > 0 && z > 0", null)); - debugTestRunner.addBreakPoint(new BallerinaTestDebugPoint(filePath, 58, "x > 0 || z > 0", null)); - debugTestRunner.addBreakPoint(new BallerinaTestDebugPoint(filePath, 59, "x is int", null)); + // Need to revert back the conditions after fixing, + // https://github.com/ballerina-platform/ballerina-lang/issues/43446 + debugTestRunner.addBreakPoint(new BallerinaTestDebugPoint(filePath, 53, "x == 7", null)); + debugTestRunner.addBreakPoint(new BallerinaTestDebugPoint(filePath, 54, "x == 8", null)); + debugTestRunner.addBreakPoint(new BallerinaTestDebugPoint(filePath, 55, "y == 1", null)); + debugTestRunner.addBreakPoint(new BallerinaTestDebugPoint(filePath, 56)); + debugTestRunner.addBreakPoint(new BallerinaTestDebugPoint(filePath, 57, "x == 11", null)); + debugTestRunner.addBreakPoint(new BallerinaTestDebugPoint(filePath, 58, "x == 12", null)); + debugTestRunner.addBreakPoint(new BallerinaTestDebugPoint(filePath, 59)); debugTestRunner.initDebugSession(DebugUtils.DebuggeeExecutionKind.RUN); Pair debugHitInfo = debugTestRunner.waitForDebugHit(25000); diff --git a/tests/jballerina-debugger-integration-test/src/test/java/org/ballerinalang/debugger/test/adapter/LogPointTest.java b/tests/jballerina-debugger-integration-test/src/test/java/org/ballerinalang/debugger/test/adapter/LogPointTest.java index a21865e9c71f..29e7504d07e9 100644 --- a/tests/jballerina-debugger-integration-test/src/test/java/org/ballerinalang/debugger/test/adapter/LogPointTest.java +++ b/tests/jballerina-debugger-integration-test/src/test/java/org/ballerinalang/debugger/test/adapter/LogPointTest.java @@ -57,7 +57,9 @@ public void testBasicLogPoints() throws BallerinaTestException { debugTestRunner.addBreakPoint(new BallerinaTestDebugPoint(filePath, 47, "x != 5", "LogPoint: 2")); debugTestRunner.addBreakPoint(new BallerinaTestDebugPoint(filePath, 48, "x == 5", null)); debugTestRunner.addBreakPoint(new BallerinaTestDebugPoint(filePath, 52, "", "LogPoint: 3")); - debugTestRunner.addBreakPoint(new BallerinaTestDebugPoint(filePath, 53, "x > 0", null)); + // Need to revert the condition to x > 0 after fixing, + // https://github.com/ballerina-platform/ballerina-lang/issues/43446 + debugTestRunner.addBreakPoint(new BallerinaTestDebugPoint(filePath, 53, "x == 7", null)); debugTestRunner.addBreakPoint(new BallerinaTestDebugPoint(filePath, 54, null, "LogPoint 4 => x: ${x}, " + "employee: ${e1.name}, capital: ${countryCapitals[\"Sri Lanka\"]}")); debugTestRunner.addBreakPoint(new BallerinaTestDebugPoint(filePath, 55, null, null)); From 353969316fff05f43e38424e038ebea1b813298f Mon Sep 17 00:00:00 2001 From: hindujaB Date: Fri, 4 Oct 2024 07:49:06 +0530 Subject: [PATCH 07/11] Enable debugger tests --- .github/workflows/pull_request_ubuntu_build.yml | 2 +- .github/workflows/pull_request_windows_build.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/pull_request_ubuntu_build.yml b/.github/workflows/pull_request_ubuntu_build.yml index 86e830603663..dd33e5055637 100644 --- a/.github/workflows/pull_request_ubuntu_build.yml +++ b/.github/workflows/pull_request_ubuntu_build.yml @@ -62,7 +62,7 @@ jobs: run: | export DISPLAY=':99.0' /usr/bin/Xvfb :99 -screen 0 1024x768x24 > /dev/null 2>&1 & - ./gradlew build -x jballerina-debugger-integration-test:test -Pnative.test --max-workers=2 --scan --no-daemon + ./gradlew build -Pnative.test --max-workers=2 --scan --no-daemon - name: Generate Jacoco report if: github.event_name == 'pull_request' diff --git a/.github/workflows/pull_request_windows_build.yml b/.github/workflows/pull_request_windows_build.yml index ac9671314190..d1a2ca4e22f2 100644 --- a/.github/workflows/pull_request_windows_build.yml +++ b/.github/workflows/pull_request_windows_build.yml @@ -65,5 +65,5 @@ jobs: env: packageUser: ${{ github.actor }} packagePAT: ${{ secrets.GITHUB_TOKEN }} - run: ./gradlew.bat build --continue -x :ballerina-lang:test -x :jballerina-integration-test:test -x jballerina-debugger-integration-test:test -x javadoc --stacktrace -scan --console=plain --no-daemon --no-parallel + run: ./gradlew.bat build --continue -x :ballerina-lang:test -x :jballerina-integration-test:test -x javadoc --stacktrace -scan --console=plain --no-daemon --no-parallel From 8804c1136c8c0af120e27e4bfe7d2c7faa23952b Mon Sep 17 00:00:00 2001 From: hindujaB Date: Fri, 4 Oct 2024 10:12:08 +0530 Subject: [PATCH 08/11] Fix checkstyle errors --- .../debugadapter/runtime/DebuggerRuntime.java | 47 +++++++++++++------ 1 file changed, 32 insertions(+), 15 deletions(-) diff --git a/misc/debug-adapter/modules/debug-adapter-runtime/src/main/java/org/ballerinalang/debugadapter/runtime/DebuggerRuntime.java b/misc/debug-adapter/modules/debug-adapter-runtime/src/main/java/org/ballerinalang/debugadapter/runtime/DebuggerRuntime.java index e1135f053913..a14c64c57df7 100644 --- a/misc/debug-adapter/modules/debug-adapter-runtime/src/main/java/org/ballerinalang/debugadapter/runtime/DebuggerRuntime.java +++ b/misc/debug-adapter/modules/debug-adapter-runtime/src/main/java/org/ballerinalang/debugadapter/runtime/DebuggerRuntime.java @@ -120,17 +120,20 @@ public static Object invokeObjectMethod(BObject bObject, String methodName, Obje * @param paramValues to be passed to invokable unit * @return return values */ - public static Object invokeFunction(ClassLoader classLoader, String className, String methodName, Object... paramValues) { + public static Object invokeFunction(ClassLoader classLoader, String className, String methodName, + Object... paramValues) { try { Class clazz = classLoader.loadClass(className); Method method = getMethod(methodName, clazz); try { return method.invoke(null, paramValues); } catch (IllegalAccessException | InvocationTargetException e) { - throw ErrorCreator.createError(StringUtils.fromString("'" + methodName + "' function invocation failed: " + e.getMessage())); + throw ErrorCreator.createError(StringUtils.fromString("'" + methodName + + "' function invocation failed: " + e.getMessage())); } } catch (Exception e) { - throw ErrorCreator.createError(StringUtils.fromString("'" + methodName + "' function invocation failed: " + e.getMessage())); + throw ErrorCreator.createError(StringUtils.fromString("'" + methodName + + "' function invocation failed: " + e.getMessage())); } } @@ -144,7 +147,8 @@ public static Object invokeFunction(ClassLoader classLoader, String className, S * @param fieldValues field values * @return Ballerina object instance */ - public static Object createObjectValue(String pkgOrg, String pkgName, String pkgVersion, String objectTypeName, Object... fieldValues) { + public static Object createObjectValue(String pkgOrg, String pkgName, String pkgVersion, + String objectTypeName, Object... fieldValues) { Module packageId = new Module(pkgOrg, pkgName, pkgVersion); return ValueCreator.createObjectValue(packageId, objectTypeName, fieldValues); } @@ -189,7 +193,9 @@ public static Object createErrorValue(Object message, Object cause, Object... de } ErrorType bErrorType = createErrorType(TypeConstants.ERROR, PredefinedTypes.TYPE_ERROR.getPackage()); - BMap errorDetailsMap = ValueCreator.createMapValue((MapType) PredefinedTypes.TYPE_ERROR_DETAIL, errorDetailEntries.toArray(errorDetailEntries.toArray(new BMapInitialValueEntry[0]))); + BMap errorDetailsMap = ValueCreator.createMapValue((MapType) + PredefinedTypes.TYPE_ERROR_DETAIL, errorDetailEntries.toArray( + errorDetailEntries.toArray(new BMapInitialValueEntry[0]))); return ErrorCreator.createError(bErrorType, (StringValue) message, (ErrorValue) cause, errorDetailsMap); } @@ -202,18 +208,23 @@ public static Object createErrorValue(Object message, Object cause, Object... de */ public static Object getAnnotationValue(Object typedescValue, String annotationName) { if (!(typedescValue instanceof TypedescValue)) { - return ErrorCreator.createError(StringUtils.fromString("Incompatible types: expected 'typedesc`, " + "found '" + typedescValue.toString() + "'.")); + return ErrorCreator.createError(StringUtils.fromString("Incompatible types: expected 'typedesc`, " + + "found '" + typedescValue.toString() + "'.")); } Type type = ((TypedescValue) typedescValue).getDescribingType(); if (type instanceof BAnnotatableType) { - return ((BAnnotatableType) type).getAnnotations().entrySet().stream().filter(annotationEntry -> annotationEntry.getKey().getValue().endsWith(annotationName)).findFirst().map(Map.Entry::getValue).orElse(null); + return ((BAnnotatableType) type).getAnnotations().entrySet().stream().filter(annotationEntry -> + annotationEntry.getKey().getValue().endsWith(annotationName)).findFirst() + .map(Map.Entry::getValue).orElse(null); } - return ErrorCreator.createError(StringUtils.fromString("type: '" + TypeUtils.getType(type.getEmptyValue()) + "' does not support annotation access.")); + return ErrorCreator.createError(StringUtils.fromString("type: '" + TypeUtils.getType(type.getEmptyValue()) + + "' does not support annotation access.")); } private static Method getMethod(String functionName, Class funcClass) throws NoSuchMethodException { - Method declaredMethod = Arrays.stream(funcClass.getDeclaredMethods()).filter(method -> functionName.equals(method.getName())).findAny().orElse(null); + Method declaredMethod = Arrays.stream(funcClass.getDeclaredMethods()).filter(method -> + functionName.equals(method.getName())).findAny().orElse(null); if (declaredMethod != null) { return declaredMethod; @@ -307,7 +318,8 @@ private static BString[] processXMLNamePattern(String xmlNamePattern) { xmlNamePattern = stepParts[stepParts.length - 1]; } - return Arrays.stream(xmlNamePattern.split(XML_NAME_PATTERN_SEPARATOR)).map(entry -> StringUtils.fromString(entry.trim())).toArray(BString[]::new); + return Arrays.stream(xmlNamePattern.split(XML_NAME_PATTERN_SEPARATOR)).map(entry -> + StringUtils.fromString(entry.trim())).toArray(BString[]::new); } /** @@ -319,10 +331,12 @@ private static BString[] processXMLNamePattern(String xmlNamePattern) { * @param userArgs argument values * @return result of the function invocation */ - public static Object classloadAndInvokeFunction(String executablePath, String mainClass, String functionName, Object... userArgs) { + public static Object classloadAndInvokeFunction(String executablePath, String mainClass, String functionName, + Object... userArgs) { try { URL pathUrl = Paths.get(executablePath).toUri().toURL(); - URLClassLoader classLoader = AccessController.doPrivileged((PrivilegedAction) () -> new URLClassLoader(new URL[]{pathUrl}, ClassLoader.getSystemClassLoader())); + URLClassLoader classLoader = AccessController.doPrivileged((PrivilegedAction) () -> + new URLClassLoader(new URL[]{pathUrl}, ClassLoader.getSystemClassLoader())); // Derives the namespace of the generated classes. String[] mainClassNameParts = mainClass.split("\\."); @@ -336,7 +350,8 @@ public static Object classloadAndInvokeFunction(String executablePath, String ma } } - private static Object invokeBalRuntimeMethod(String functionName, Module module, ClassLoader classLoader, Object[] paramValues) { + private static Object invokeBalRuntimeMethod(String functionName, Module module, ClassLoader classLoader, + Object[] paramValues) { BalRuntime runtime = new ClassloaderRuntime(module, classLoader); Object result; try { @@ -347,7 +362,8 @@ private static Object invokeBalRuntimeMethod(String functionName, Module module, // Then call run method result = runtime.call(module, functionName, paramValues); } catch (Throwable throwable) { - throw ErrorCreator.createError(StringUtils.fromString("'" + functionName + "' function " + "invocation failed : " + throwable.getMessage())); + throw ErrorCreator.createError(StringUtils.fromString("'" + functionName + "' function " + + "invocation failed : " + throwable.getMessage())); } finally { try { runtime.stop(); @@ -370,7 +386,8 @@ private static Object invokeBalRuntimeMethod(String functionName, Module module, * @param args Arguments to provide. * @return The result of the invocation. */ - protected static Object invokeMethodDirectly(ClassLoader classLoader, String className, String methodName, Class[] argTypes, Object[] args) throws Exception { + protected static Object invokeMethodDirectly(ClassLoader classLoader, String className, String methodName, + Class[] argTypes, Object[] args) throws Exception { Class clazz = classLoader.loadClass(className); Method method = clazz.getDeclaredMethod(methodName, argTypes); return method.invoke(null, args); From 08e776cc33ca16657092385813aa9af20a0e409d Mon Sep 17 00:00:00 2001 From: hindujaB Date: Fri, 4 Oct 2024 10:59:47 +0530 Subject: [PATCH 09/11] Fix checkstyle test errors --- .../adapter/variables/VariableVisibilityTest.java | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/tests/jballerina-debugger-integration-test/src/test/java/org/ballerinalang/debugger/test/adapter/variables/VariableVisibilityTest.java b/tests/jballerina-debugger-integration-test/src/test/java/org/ballerinalang/debugger/test/adapter/variables/VariableVisibilityTest.java index e7f998b451e7..a731fe63d010 100644 --- a/tests/jballerina-debugger-integration-test/src/test/java/org/ballerinalang/debugger/test/adapter/variables/VariableVisibilityTest.java +++ b/tests/jballerina-debugger-integration-test/src/test/java/org/ballerinalang/debugger/test/adapter/variables/VariableVisibilityTest.java @@ -520,24 +520,28 @@ public void workerVariableVisibilityTest() throws BallerinaTestException { Pair debugHitInfo = debugTestRunner.waitForDebugHit(25000); if (debugHitInfo.getKey().getLine() == 23) { // variable visibility test inside worker (only worker's variables should be visible) - localVariables = debugTestRunner.fetchVariables(debugHitInfo.getRight(), DebugTestRunner.VariableScope.LOCAL); + localVariables = debugTestRunner.fetchVariables(debugHitInfo.getRight(), + DebugTestRunner.VariableScope.LOCAL); debugTestRunner.assertVariable(localVariables, "x", "10", "int"); // variables outside worker should not be visible Assert.assertFalse(localVariables.containsKey("a")); // variable visibility test for workers outside fork (workers are visible outside fork() as futures). debugTestRunner.resumeProgram(debugHitInfo.getRight(), DebugTestRunner.DebugResumeKind.NEXT_BREAKPOINT); debugHitInfo = debugTestRunner.waitForDebugHit(10000); - localVariables = debugTestRunner.fetchVariables(debugHitInfo.getRight(), DebugTestRunner.VariableScope.LOCAL); + localVariables = debugTestRunner.fetchVariables(debugHitInfo.getRight(), + DebugTestRunner.VariableScope.LOCAL); debugTestRunner.assertVariable(localVariables, "w1", "future<()>", "future"); Assert.assertTrue(localVariables.containsKey("a")); } else { // variable visibility test for workers outside fork (workers are visible outside fork() as futures). - localVariables = debugTestRunner.fetchVariables(debugHitInfo.getRight(), DebugTestRunner.VariableScope.LOCAL); + localVariables = debugTestRunner.fetchVariables(debugHitInfo.getRight(), + DebugTestRunner.VariableScope.LOCAL); debugTestRunner.assertVariable(localVariables, "w1", "future<()>", "future"); Assert.assertTrue(localVariables.containsKey("a")); debugTestRunner.resumeProgram(debugHitInfo.getRight(), DebugTestRunner.DebugResumeKind.NEXT_BREAKPOINT); debugHitInfo = debugTestRunner.waitForDebugHit(10000); - localVariables = debugTestRunner.fetchVariables(debugHitInfo.getRight(), DebugTestRunner.VariableScope.LOCAL); + localVariables = debugTestRunner.fetchVariables(debugHitInfo.getRight(), + DebugTestRunner.VariableScope.LOCAL); debugTestRunner.assertVariable(localVariables, "x", "10", "int"); // variables outside worker should not be visible Assert.assertFalse(localVariables.containsKey("a")); From e9e726b526c9d2179eddfe8a31c569b24992d85f Mon Sep 17 00:00:00 2001 From: hindujaB Date: Mon, 7 Oct 2024 12:37:35 +0530 Subject: [PATCH 10/11] Address review suggestions --- .../debugadapter/JBallerinaDebugServer.java | 3 +-- .../debugadapter/JDIEventProcessor.java | 12 +++++------- 2 files changed, 6 insertions(+), 9 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 c3d919f91166..ba45a1c762cb 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 @@ -1107,8 +1107,7 @@ private void attachToRemoteVM(String hostName, int portName) throws IOException, VirtualMachine attachedVm = executionManager.attach(hostName, portName); context.setDebuggeeVM(new VirtualMachineProxyImpl(attachedVm)); EventRequestManager erm = context.getEventManager(); - ClassPrepareRequest classPrepareRequest = erm.createClassPrepareRequest(); - classPrepareRequest.enable(); + erm.createClassPrepareRequest().enable(); erm.createThreadStartRequest().enable(); erm.createThreadDeathRequest().enable(); eventProcessor.startListening(); 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 9aadefad217d..81cc70d4f731 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 @@ -45,6 +45,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; @@ -59,8 +60,8 @@ public class JDIEventProcessor { private final BreakpointProcessor breakpointProcessor; private boolean isRemoteVmAttached = false; private final List stepRequests = new ArrayList<>(); + private static final List virtualThreads = new CopyOnWriteArrayList<>(); private static final Logger LOGGER = LoggerFactory.getLogger(JDIEventProcessor.class); - private static final List virtualThreads = new ArrayList<>(); JDIEventProcessor(ExecutionContext context) { this.context = context; @@ -132,16 +133,13 @@ private void processEvent(EventSet eventSet, Event event) { } else if (event instanceof ThreadStartEvent threadStartEvent) { ThreadReference thread = threadStartEvent.thread(); if (thread.isVirtual()) { - synchronized (virtualThreads) { - virtualThreads.add(thread); - } + virtualThreads.add(thread); + } eventSet.resume(); } else if (event instanceof ThreadDeathEvent threadDeathEvent) { ThreadReference thread = threadDeathEvent.thread(); - synchronized (virtualThreads) { - virtualThreads.remove(thread); - } + virtualThreads.remove(thread); eventSet.resume(); } else { eventSet.resume(); From 7bd7966b99ebc8d8438f02f9849ab41020df83bd Mon Sep 17 00:00:00 2001 From: hindujaB Date: Tue, 8 Oct 2024 16:09:26 +0530 Subject: [PATCH 11/11] Address suggestions --- .../java/org/ballerinalang/debugadapter/JDIEventProcessor.java | 1 - 1 file changed, 1 deletion(-) 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 81cc70d4f731..d98d32e2b736 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 @@ -134,7 +134,6 @@ private void processEvent(EventSet eventSet, Event event) { ThreadReference thread = threadStartEvent.thread(); if (thread.isVirtual()) { virtualThreads.add(thread); - } eventSet.resume(); } else if (event instanceof ThreadDeathEvent threadDeathEvent) {