[Lldb-commits] [lldb] [lldb-dap] Added "port" property to vscode "attach" command. (PR #91570)

Santhosh Kumar Ellendula via lldb-commits lldb-commits at lists.llvm.org
Mon Jun 10 05:29:04 PDT 2024


https://github.com/santhoshe447 updated https://github.com/llvm/llvm-project/pull/91570

>From 960351c9abf51f42d92604ac6297aa5b76ddfba5 Mon Sep 17 00:00:00 2001
From: Santhosh Kumar Ellendula <sellendu at hu-sellendu-hyd.qualcomm.com>
Date: Fri, 17 Nov 2023 15:09:10 +0530
Subject: [PATCH 01/15] [lldb][test] Add the ability to extract the variable
 value out of the summary.

---
 .../Python/lldbsuite/test/tools/lldb-dap/lldbdap_testcase.py   | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/lldbdap_testcase.py b/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/lldbdap_testcase.py
index 9d79872b029a3..0cf9d4fde4948 100644
--- a/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/lldbdap_testcase.py
+++ b/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/lldbdap_testcase.py
@@ -195,6 +195,9 @@ def collect_console(self, duration):
 
     def get_local_as_int(self, name, threadId=None):
         value = self.dap_server.get_local_variable_value(name, threadId=threadId)
+        # 'value' may have the variable value and summary.
+        # Extract the variable value since summary can have nonnumeric characters.
+        value = value.split(" ")[0]
         if value.startswith("0x"):
             return int(value, 16)
         elif value.startswith("0"):

>From ab44a6991c5bc8ac5764c3f71cbe3acc747b3776 Mon Sep 17 00:00:00 2001
From: Santhosh Kumar Ellendula <sellendu at hu-sellendu-lv.qualcomm.com>
Date: Fri, 3 May 2024 02:47:05 -0700
Subject: [PATCH 02/15] [lldb-dap] Added "port" property to vscode "attach"
 command.

Adding a "port" property to the VsCode "attach" command likely extends the functionality of the debugger configuratiuon to allow attaching to a process using PID or PORT number.
Currently, the "Attach" configuration lets the user specify a pid. We tell the user to use the attachCommands property to run "gdb-remote <port>".
Followed the below conditions for "attach" command with "port" and "pid"
We should add a "port" property. If port is specified and pid is not, use that port to attach. If both port and pid are specified, return an error saying that the user can't specify both pid and port.

Ex - launch.json
{
	"version": "0.2.0",
    "configurations": [
        {
            "name": "lldb-dap Debug",
            "type": "lldb-dap",
            "request": "attach",
            "port":1234,
            "program": "${workspaceFolder}/a.out",
            "args": [],
            "stopOnEntry": false,
            "cwd": "${workspaceFolder}",
            "env": [],

        }
    ]
}
---
 lldb/include/lldb/lldb-defines.h              |   1 +
 .../Python/lldbsuite/test/lldbtest.py         |   9 ++
 .../test/tools/lldb-dap/dap_server.py         |   6 +
 .../test/tools/lldb-dap/lldbdap_testcase.py   |  20 +++
 .../attach/TestDAP_attachByPortNum.py         | 120 ++++++++++++++++++
 lldb/tools/lldb-dap/lldb-dap.cpp              |  36 +++++-
 lldb/tools/lldb-dap/package.json              |  11 ++
 7 files changed, 199 insertions(+), 4 deletions(-)
 create mode 100644 lldb/test/API/tools/lldb-dap/attach/TestDAP_attachByPortNum.py

diff --git a/lldb/include/lldb/lldb-defines.h b/lldb/include/lldb/lldb-defines.h
index c7bd019c5c90e..a1e6ee2ce468c 100644
--- a/lldb/include/lldb/lldb-defines.h
+++ b/lldb/include/lldb/lldb-defines.h
@@ -96,6 +96,7 @@
 #define LLDB_INVALID_QUEUE_ID 0
 #define LLDB_INVALID_CPU_ID UINT32_MAX
 #define LLDB_INVALID_WATCHPOINT_RESOURCE_ID UINT32_MAX
+#define LLDB_INVALID_PORT_NUMBER 0
 
 /// CPU Type definitions
 #define LLDB_ARCH_DEFAULT "systemArch"
diff --git a/lldb/packages/Python/lldbsuite/test/lldbtest.py b/lldb/packages/Python/lldbsuite/test/lldbtest.py
index 5fd686c143e9f..fb3cd22959df2 100644
--- a/lldb/packages/Python/lldbsuite/test/lldbtest.py
+++ b/lldb/packages/Python/lldbsuite/test/lldbtest.py
@@ -1572,6 +1572,15 @@ def findBuiltClang(self):
 
         return os.environ["CC"]
 
+    def getBuiltServerTool(self, server_tool):
+        # Tries to find simulation/lldb-server/gdbserver tool at the same folder as the lldb.
+        lldb_dir = os.path.dirname(lldbtest_config.lldbExec)
+        path = shutil.which(server_tool, path=lldb_dir)
+        if path is not None:
+            return path
+
+        return ""
+
     def yaml2obj(self, yaml_path, obj_path, max_size=None):
         """
         Create an object file at the given path from a yaml file.
diff --git a/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py b/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py
index 5838281bcb1a1..96d312565f953 100644
--- a/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py
+++ b/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py
@@ -568,6 +568,8 @@ def request_attach(
         coreFile=None,
         postRunCommands=None,
         sourceMap=None,
+        port=None,
+        hostname=None
     ):
         args_dict = {}
         if pid is not None:
@@ -597,6 +599,10 @@ def request_attach(
             args_dict["postRunCommands"] = postRunCommands
         if sourceMap:
             args_dict["sourceMap"] = sourceMap
+        if port is not None:
+            args_dict['port'] = port
+        if hostname is not None:
+            args_dict['hostname'] = hostname
         command_dict = {"command": "attach", "type": "request", "arguments": args_dict}
         return self.send_recv(command_dict)
 
diff --git a/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/lldbdap_testcase.py b/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/lldbdap_testcase.py
index d56ea5dca14be..ba58a3075c6a2 100644
--- a/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/lldbdap_testcase.py
+++ b/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/lldbdap_testcase.py
@@ -335,6 +335,26 @@ def cleanup():
                 response["success"], "attach failed (%s)" % (response["message"])
             )
 
+    def attach_by_port(self, program=None, pid=None, disconnectAutomatically=True, waitFor=None, sourceInitFile=False, port=None, hostname=None):
+        '''Build the default Makefile target, create the VSCode debug adaptor,
+           and attach to the process.
+        '''
+        # This overloaded function helps to request attach by port number
+        # Make sure we disconnect and terminate the VSCode debug adaptor even
+        # if we throw an exception during the test case.
+        def cleanup():
+            if disconnectAutomatically:
+                self.dap_server.request_disconnect(terminateDebuggee=True)
+            self.dap_server.terminate()
+
+        # Execute the cleanup function during test case tear down.
+        self.addTearDownHook(cleanup)
+        # Initialize and launch the program
+        self.dap_server.request_initialize(sourceInitFile)
+        response = self.dap_server.request_attach(
+            program=program, pid=pid, waitFor=waitFor, port=port, hostname=hostname)
+        return response
+
     def launch(
         self,
         program=None,
diff --git a/lldb/test/API/tools/lldb-dap/attach/TestDAP_attachByPortNum.py b/lldb/test/API/tools/lldb-dap/attach/TestDAP_attachByPortNum.py
new file mode 100644
index 0000000000000..0c0ea6ca43616
--- /dev/null
+++ b/lldb/test/API/tools/lldb-dap/attach/TestDAP_attachByPortNum.py
@@ -0,0 +1,120 @@
+"""
+Test lldb-dap "port" configuration to "attach" request
+"""
+
+
+import dap_server
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
+import lldbdap_testcase
+import os
+import shutil
+import subprocess
+import tempfile
+import threading
+import time
+import sys
+import re
+
+class TestDAP_attachByPortNum(lldbdap_testcase.DAPTestCaseBase):
+
+    def runTargetProgramOnPort(self, port=None, program=None):
+        # sim_tool="hexagon-sim"
+        # if isIUTarget():
+        #     sim_tool="iu-sim"
+        target_sim_path=self.getBuiltServerTool("lldb-server")
+        if target_sim_path:
+            target_sim_path +=' g localhost:' +  port + ' '
+
+        self.process = subprocess.Popen([target_sim_path + program], shell=True,
+                                        stdin=subprocess.PIPE,
+                                        stdout=subprocess.PIPE,
+                                        stderr=subprocess.PIPE)
+        
+        return self.process
+
+    def set_and_hit_breakpoint(self, continueToExit=True):
+        source = 'main.c'
+        main_source_path = os.path.join(os.getcwd(), source)
+        breakpoint1_line = line_number(main_source_path, '// breakpoint 1')
+        lines = [breakpoint1_line]
+        # Set breakpoint in the thread function so we can step the threads
+        breakpoint_ids = self.set_source_breakpoints(main_source_path, lines)
+        self.assertEqual(len(breakpoint_ids), len(lines),
+                         "expect correct number of breakpoints")
+        self.continue_to_breakpoints(breakpoint_ids)
+        if continueToExit:
+            self.continue_to_exit()
+
+    @skipIfWindows
+    @skipIfNetBSD  # Hangs on NetBSD as well
+    @skipIfRemote
+    def test_by_port(self):
+        '''
+            Tests attaching to a process by port.
+        '''
+        self.build_and_create_debug_adaptor()
+        program = self.getBuildArtifact("a.out")
+
+        port = '2345'
+        self.process = self.runTargetProgramOnPort(port=port, program=program)
+        pid=self.process.pid 
+        response = self.attach_by_port(program=program, port=int(port), sourceInitFile=True)
+        if not (response and response['success']):
+            self.assertTrue(response['success'],
+                            'attach failed (%s)' % (response['message']))
+        self.set_and_hit_breakpoint(continueToExit=True)
+        self.process.kill()
+        os.system('killall hexagon-sim')
+
+    @skipIfWindows
+    @skipIfNetBSD  # Hangs on NetBSD as well
+    @skipIfRemote
+    def test_by_port_and_pid(self):
+        '''
+            Tests attaching to a process by process ID and port number.
+        '''
+        self.build_and_create_debug_adaptor()
+        program = self.getBuildArtifact("a.out")
+
+        port = '2345'
+        self.process = self.runTargetProgramOnPort(port=port, program=program)
+        response = self.attach_by_port(program=program,pid=1234, port=int(port), sourceInitFile=True)
+        if not (response and response['success']):
+            self.assertFalse(response['success'], "The user can't specify both pid and port")
+        self.process.kill()
+
+    @skipIfWindows
+    @skipIfNetBSD  # Hangs on NetBSD as well
+    @skipIfRemote
+    def test_by_invalid_port(self):
+        '''
+            Tests attaching to a process by invalid port number 0.
+        '''
+        self.build_and_create_debug_adaptor()
+        program = self.getBuildArtifact("a.out")
+
+        port = '0'
+        self.process = self.runTargetProgramOnPort(port=port, program=program)
+        response = self.attach_by_port(program=program, port=int(port), sourceInitFile=True)
+        if not (response and response['success']):
+            self.assertFalse(response['success'], "The user can't attach with invalid port (%s)" % port)
+        self.process.kill()
+
+    @skipIfWindows
+    @skipIfNetBSD  # Hangs on NetBSD as well
+    @skipIfRemote
+    def test_by_illegal_port(self):
+        '''
+            Tests attaching to a process by illegal/greater port number 65536
+        '''
+        self.build_and_create_debug_adaptor()
+        program = self.getBuildArtifact("a.out")
+
+        port = '65536'
+        self.process = self.runTargetProgramOnPort(port=port, program=program)
+        response = self.attach_by_port(program=program, port=int(port), sourceInitFile=True)
+        if not (response and response['success']):
+            self.assertFalse(response['success'], "The user can't attach with illegal port (%s)" % port)
+        self.process.kill()
diff --git a/lldb/tools/lldb-dap/lldb-dap.cpp b/lldb/tools/lldb-dap/lldb-dap.cpp
index 8000d68dea7e3..2280e7217eaaa 100644
--- a/lldb/tools/lldb-dap/lldb-dap.cpp
+++ b/lldb/tools/lldb-dap/lldb-dap.cpp
@@ -688,6 +688,8 @@ void request_attach(const llvm::json::Object &request) {
   auto arguments = request.getObject("arguments");
   const lldb::pid_t pid =
       GetUnsigned(arguments, "pid", LLDB_INVALID_PROCESS_ID);
+  const auto port = GetUnsigned(arguments, "port", LLDB_INVALID_PORT_NUMBER);
+  llvm::StringRef hostname = GetString(arguments, "hostname");
   if (pid != LLDB_INVALID_PROCESS_ID)
     attach_info.SetProcessID(pid);
   const auto wait_for = GetBoolean(arguments, "waitFor", false);
@@ -749,7 +751,7 @@ void request_attach(const llvm::json::Object &request) {
     return;
   }
 
-  if (pid == LLDB_INVALID_PROCESS_ID && wait_for) {
+  if ((pid == LLDB_INVALID_PROCESS_ID || port == LLDB_INVALID_PORT_NUMBER) && wait_for) {
     char attach_msg[256];
     auto attach_msg_len = snprintf(attach_msg, sizeof(attach_msg),
                                    "Waiting to attach to \"%s\"...",
@@ -762,9 +764,35 @@ void request_attach(const llvm::json::Object &request) {
     // Disable async events so the attach will be successful when we return from
     // the launch call and the launch will happen synchronously
     g_dap.debugger.SetAsync(false);
-    if (core_file.empty())
-      g_dap.target.Attach(attach_info, error);
-    else
+    if (core_file.empty()) {
+      if ((pid != LLDB_INVALID_PROCESS_ID) &&
+          (port != LLDB_INVALID_PORT_NUMBER)) {
+        // If both pid and port numbers are specified.
+        error.SetErrorString("The user can't specify both pid and port");
+      } else if ((pid != LLDB_INVALID_PROCESS_ID) &&
+                 (port == LLDB_INVALID_PORT_NUMBER)) {
+        // If pid is specified and port is not.
+        g_dap.target.Attach(attach_info, error);
+      } else if ((port != LLDB_INVALID_PORT_NUMBER) && (port < UINT16_MAX) &&
+                 (pid == LLDB_INVALID_PROCESS_ID)) {
+        // If port is specified and pid is not.
+        lldb::SBListener listener = g_dap.debugger.GetListener();
+
+        // If the user hasn't provided the hostname property, default localhost
+        // being used.
+        std::string connect_url("connect://localhost:");
+
+        // If the user has provided hostname other than localhost.
+        if (!hostname.empty() && !hostname.starts_with("localhost")) {
+          connect_url = llvm::formatv("connect://{0}:", hostname.data());
+        }
+        connect_url += std::to_string(port);
+        g_dap.target.ConnectRemote(listener, connect_url.c_str(), "gdb-remote",
+                                   error);
+      } else {
+        error.SetErrorString("Invalid pid/port number specified");
+      }
+    } else
       g_dap.target.LoadCore(core_file.data(), error);
     // Reenable async events
     g_dap.debugger.SetAsync(true);
diff --git a/lldb/tools/lldb-dap/package.json b/lldb/tools/lldb-dap/package.json
index 2e8ad074256bf..624b5710f50fa 100644
--- a/lldb/tools/lldb-dap/package.json
+++ b/lldb/tools/lldb-dap/package.json
@@ -347,6 +347,17 @@
                 "type": "string",
                 "description": "The time in seconds to wait for a program to stop when attaching using \"attachCommands\". Defaults to 30 seconds."
               },
+              "port": {
+                "type": [
+									"number",
+									"string"
+								],
+                "description": "TCP/IP port to attach to. Specifying both pid and port is an error."
+              },
+              "hostname": {
+								"type": "string",
+								"description": "The hostname to connect to a remote system. The default hostname being used localhost."
+							},
               "enableAutoVariableSummaries": {
                 "type": "boolean",
                 "description": "Enable auto generated summaries for variables when no summaries exist for a given type. This feature can cause performance delays in large projects when viewing variables.",

>From 4e2e524f7d468cbd3b8c283635e766bb6de35376 Mon Sep 17 00:00:00 2001
From: Santhosh Kumar Ellendula <sellendu at hu-sellendu-lv.qualcomm.com>
Date: Wed, 8 May 2024 12:41:43 -0700
Subject: [PATCH 03/15] [lldb-dap] Added "port" property to vscode "attach"
 command.

Adding a "port" property to the VsCode "attach" command likely extends the functionality of the debugger configuration to allow attaching to a process using PID or PORT number.
Currently, the "Attach" configuration lets the user specify a pid. We tell the user to use the attachCommands property to run "gdb-remote ".
Followed the below conditions for "attach" command with "port" and "pid"
We should add a "port" property. If port is specified and pid is not, use that port to attach. If both port and pid are specified, return an error saying that the user can't specify both pid and port.

Ex - launch.json
{
"version": "0.2.0",
"configurations": [
{
"name": "lldb-dap Debug",
"type": "lldb-dap",
"request": "attach",
"port":1234,
"program": "${workspaceFolder}/a.out",
"args": [],
"stopOnEntry": false,
"cwd": "${workspaceFolder}",
"env": [],

    }
]
}

In this patch we have resolved code formatting issues and fixed "test_by_name" failure.
---
 .../Python/lldbsuite/test/lldbtest.py         |   2 +-
 .../test/tools/lldb-dap/dap_server.py         |   6 +-
 .../test/tools/lldb-dap/lldbdap_testcase.py   |  21 +++-
 .../attach/TestDAP_attachByPortNum.py         | 109 ++++++++++--------
 lldb/tools/lldb-dap/lldb-dap.cpp              |  13 +--
 lldb/tools/lldb-dap/package.json              |  12 +-
 6 files changed, 94 insertions(+), 69 deletions(-)

diff --git a/lldb/packages/Python/lldbsuite/test/lldbtest.py b/lldb/packages/Python/lldbsuite/test/lldbtest.py
index fb3cd22959df2..dde3efd8f5f87 100644
--- a/lldb/packages/Python/lldbsuite/test/lldbtest.py
+++ b/lldb/packages/Python/lldbsuite/test/lldbtest.py
@@ -1572,7 +1572,7 @@ def findBuiltClang(self):
 
         return os.environ["CC"]
 
-    def getBuiltServerTool(self, server_tool):
+    def getBuiltinServerTool(self, server_tool):
         # Tries to find simulation/lldb-server/gdbserver tool at the same folder as the lldb.
         lldb_dir = os.path.dirname(lldbtest_config.lldbExec)
         path = shutil.which(server_tool, path=lldb_dir)
diff --git a/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py b/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py
index 613180bc99af6..bab16479d26c3 100644
--- a/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py
+++ b/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py
@@ -573,7 +573,7 @@ def request_attach(
         postRunCommands=None,
         sourceMap=None,
         port=None,
-        hostname=None
+        hostname=None,
     ):
         args_dict = {}
         if pid is not None:
@@ -604,9 +604,9 @@ def request_attach(
         if sourceMap:
             args_dict["sourceMap"] = sourceMap
         if port is not None:
-            args_dict['port'] = port
+            args_dict["port"] = port
         if hostname is not None:
-            args_dict['hostname'] = hostname
+            args_dict["hostname"] = hostname
         command_dict = {"command": "attach", "type": "request", "arguments": args_dict}
         return self.send_recv(command_dict)
 
diff --git a/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/lldbdap_testcase.py b/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/lldbdap_testcase.py
index ba58a3075c6a2..922fb1d5784e6 100644
--- a/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/lldbdap_testcase.py
+++ b/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/lldbdap_testcase.py
@@ -335,10 +335,20 @@ def cleanup():
                 response["success"], "attach failed (%s)" % (response["message"])
             )
 
-    def attach_by_port(self, program=None, pid=None, disconnectAutomatically=True, waitFor=None, sourceInitFile=False, port=None, hostname=None):
-        '''Build the default Makefile target, create the VSCode debug adaptor,
-           and attach to the process.
-        '''
+    def attach_by_port(
+        self,
+        program=None,
+        pid=None,
+        disconnectAutomatically=True,
+        waitFor=None,
+        sourceInitFile=False,
+        port=None,
+        hostname=None,
+    ):
+        """Build the default Makefile target, create the VSCode debug adaptor,
+        and attach to the process.
+        """
+
         # This overloaded function helps to request attach by port number
         # Make sure we disconnect and terminate the VSCode debug adaptor even
         # if we throw an exception during the test case.
@@ -352,7 +362,8 @@ def cleanup():
         # Initialize and launch the program
         self.dap_server.request_initialize(sourceInitFile)
         response = self.dap_server.request_attach(
-            program=program, pid=pid, waitFor=waitFor, port=port, hostname=hostname)
+            program=program, pid=pid, waitFor=waitFor, port=port, hostname=hostname
+        )
         return response
 
     def launch(
diff --git a/lldb/test/API/tools/lldb-dap/attach/TestDAP_attachByPortNum.py b/lldb/test/API/tools/lldb-dap/attach/TestDAP_attachByPortNum.py
index 0c0ea6ca43616..4b9965cbb5571 100644
--- a/lldb/test/API/tools/lldb-dap/attach/TestDAP_attachByPortNum.py
+++ b/lldb/test/API/tools/lldb-dap/attach/TestDAP_attachByPortNum.py
@@ -15,34 +15,35 @@
 import threading
 import time
 import sys
-import re
 
 class TestDAP_attachByPortNum(lldbdap_testcase.DAPTestCaseBase):
 
     def runTargetProgramOnPort(self, port=None, program=None):
-        # sim_tool="hexagon-sim"
-        # if isIUTarget():
-        #     sim_tool="iu-sim"
-        target_sim_path=self.getBuiltServerTool("lldb-server")
-        if target_sim_path:
-            target_sim_path +=' g localhost:' +  port + ' '
+        server_tool = "lldb-server"
+        server_path = self.getBuiltinServerTool(server_tool)
+        if server_path:
+            server_path +=" g localhost:" +  port + " " 
 
-        self.process = subprocess.Popen([target_sim_path + program], shell=True,
-                                        stdin=subprocess.PIPE,
-                                        stdout=subprocess.PIPE,
-                                        stderr=subprocess.PIPE)
+        self.process = subprocess.Popen(
+            [server_path + program],
+            shell=True,
+            stdin=subprocess.PIPE,
+            stdout=subprocess.PIPE,
+            stderr=subprocess.PIPE,
+        )
         
         return self.process
 
     def set_and_hit_breakpoint(self, continueToExit=True):
-        source = 'main.c'
+        source = "main.c"
         main_source_path = os.path.join(os.getcwd(), source)
-        breakpoint1_line = line_number(main_source_path, '// breakpoint 1')
+        breakpoint1_line = line_number(main_source_path, "// breakpoint 1")
         lines = [breakpoint1_line]
         # Set breakpoint in the thread function so we can step the threads
         breakpoint_ids = self.set_source_breakpoints(main_source_path, lines)
-        self.assertEqual(len(breakpoint_ids), len(lines),
-                         "expect correct number of breakpoints")
+        self.assertEqual(
+            len(breakpoint_ids), len(lines), "expect correct number of breakpoints"
+        )        
         self.continue_to_breakpoints(breakpoint_ids)
         if continueToExit:
             self.continue_to_exit()
@@ -51,70 +52,86 @@ def set_and_hit_breakpoint(self, continueToExit=True):
     @skipIfNetBSD  # Hangs on NetBSD as well
     @skipIfRemote
     def test_by_port(self):
-        '''
-            Tests attaching to a process by port.
-        '''
+        """
+        Tests attaching to a process by port.
+        """
         self.build_and_create_debug_adaptor()
         program = self.getBuildArtifact("a.out")
 
-        port = '2345'
+        port = "2345"
         self.process = self.runTargetProgramOnPort(port=port, program=program)
-        pid=self.process.pid 
-        response = self.attach_by_port(program=program, port=int(port), sourceInitFile=True)
-        if not (response and response['success']):
-            self.assertTrue(response['success'],
-                            'attach failed (%s)' % (response['message']))
+        pid = self.process.pid
+        response = self.attach_by_port(
+            program=program, port=int(port), sourceInitFile=True
+        )
+        if not (response and response["success"]):
+            self.assertTrue(
+                response["success"], "attach failed (%s)" % (response["message"])
+            )
         self.set_and_hit_breakpoint(continueToExit=True)
         self.process.kill()
-        os.system('killall hexagon-sim')
 
     @skipIfWindows
     @skipIfNetBSD  # Hangs on NetBSD as well
     @skipIfRemote
     def test_by_port_and_pid(self):
-        '''
-            Tests attaching to a process by process ID and port number.
-        '''
+        """
+        Tests attaching to a process by process ID and port number.
+        """
         self.build_and_create_debug_adaptor()
         program = self.getBuildArtifact("a.out")
 
-        port = '2345'
+        port = "2345"
         self.process = self.runTargetProgramOnPort(port=port, program=program)
-        response = self.attach_by_port(program=program,pid=1234, port=int(port), sourceInitFile=True)
-        if not (response and response['success']):
-            self.assertFalse(response['success'], "The user can't specify both pid and port")
+        response = self.attach_by_port(
+            program=program, pid=1234, port=int(port), sourceInitFile=True
+        )
+        if not (response and response["success"]):
+            self.assertFalse(
+                response["success"], "The user can't specify both pid and port"
+            )
         self.process.kill()
 
     @skipIfWindows
     @skipIfNetBSD  # Hangs on NetBSD as well
     @skipIfRemote
     def test_by_invalid_port(self):
-        '''
-            Tests attaching to a process by invalid port number 0.
-        '''
+        """
+        Tests attaching to a process by invalid port number 0.
+        """
         self.build_and_create_debug_adaptor()
         program = self.getBuildArtifact("a.out")
 
-        port = '0'
+        port = "0"
         self.process = self.runTargetProgramOnPort(port=port, program=program)
-        response = self.attach_by_port(program=program, port=int(port), sourceInitFile=True)
-        if not (response and response['success']):
-            self.assertFalse(response['success'], "The user can't attach with invalid port (%s)" % port)
+        response = self.attach_by_port(
+            program=program, port=int(port), sourceInitFile=True
+        )
+        if not (response and response["success"]):
+            self.assertFalse(
+                response["success"],
+                "The user can't attach with invalid port (%s)" % port,
+            )
         self.process.kill()
 
     @skipIfWindows
     @skipIfNetBSD  # Hangs on NetBSD as well
     @skipIfRemote
     def test_by_illegal_port(self):
-        '''
-            Tests attaching to a process by illegal/greater port number 65536
-        '''
+        """
+        Tests attaching to a process by illegal/greater port number 65536
+        """
         self.build_and_create_debug_adaptor()
         program = self.getBuildArtifact("a.out")
 
-        port = '65536'
+        port = "65536"
         self.process = self.runTargetProgramOnPort(port=port, program=program)
-        response = self.attach_by_port(program=program, port=int(port), sourceInitFile=True)
-        if not (response and response['success']):
-            self.assertFalse(response['success'], "The user can't attach with illegal port (%s)" % port)
+        response = self.attach_by_port(
+            program=program, port=int(port), sourceInitFile=True
+        )
+        if not (response and response["success"]):
+            self.assertFalse(
+                response["success"],
+                "The user can't attach with illegal port (%s)" % port,
+            )
         self.process.kill()
diff --git a/lldb/tools/lldb-dap/lldb-dap.cpp b/lldb/tools/lldb-dap/lldb-dap.cpp
index 787a732c18410..2b123a01da657 100644
--- a/lldb/tools/lldb-dap/lldb-dap.cpp
+++ b/lldb/tools/lldb-dap/lldb-dap.cpp
@@ -751,7 +751,8 @@ void request_attach(const llvm::json::Object &request) {
     return;
   }
 
-  if ((pid == LLDB_INVALID_PROCESS_ID || port == LLDB_INVALID_PORT_NUMBER) && wait_for) {
+  if ((pid == LLDB_INVALID_PROCESS_ID || port == LLDB_INVALID_PORT_NUMBER) &&
+      wait_for) {
     char attach_msg[256];
     auto attach_msg_len = snprintf(attach_msg, sizeof(attach_msg),
                                    "Waiting to attach to \"%s\"...",
@@ -769,12 +770,7 @@ void request_attach(const llvm::json::Object &request) {
           (port != LLDB_INVALID_PORT_NUMBER)) {
         // If both pid and port numbers are specified.
         error.SetErrorString("The user can't specify both pid and port");
-      } else if ((pid != LLDB_INVALID_PROCESS_ID) &&
-                 (port == LLDB_INVALID_PORT_NUMBER)) {
-        // If pid is specified and port is not.
-        g_dap.target.Attach(attach_info, error);
-      } else if ((port != LLDB_INVALID_PORT_NUMBER) && (port < UINT16_MAX) &&
-                 (pid == LLDB_INVALID_PROCESS_ID)) {
+      } else if ((port != LLDB_INVALID_PORT_NUMBER) && (port < UINT16_MAX)) {
         // If port is specified and pid is not.
         lldb::SBListener listener = g_dap.debugger.GetListener();
 
@@ -790,7 +786,8 @@ void request_attach(const llvm::json::Object &request) {
         g_dap.target.ConnectRemote(listener, connect_url.c_str(), "gdb-remote",
                                    error);
       } else {
-        error.SetErrorString("Invalid pid/port number specified");
+        // Attach by process name or id.
+        g_dap.target.Attach(attach_info, error);
       }
     } else
       g_dap.target.LoadCore(core_file.data(), error);
diff --git a/lldb/tools/lldb-dap/package.json b/lldb/tools/lldb-dap/package.json
index 624b5710f50fa..224115b8ddffb 100644
--- a/lldb/tools/lldb-dap/package.json
+++ b/lldb/tools/lldb-dap/package.json
@@ -349,15 +349,15 @@
               },
               "port": {
                 "type": [
-									"number",
-									"string"
-								],
+                  "number",
+                  "string"
+                ],
                 "description": "TCP/IP port to attach to. Specifying both pid and port is an error."
               },
               "hostname": {
-								"type": "string",
-								"description": "The hostname to connect to a remote system. The default hostname being used localhost."
-							},
+                "type": "string",
+                "description": "The hostname to connect to a remote system. The default hostname being used localhost."
+              },
               "enableAutoVariableSummaries": {
                 "type": "boolean",
                 "description": "Enable auto generated summaries for variables when no summaries exist for a given type. This feature can cause performance delays in large projects when viewing variables.",

>From 175f1d32c446473252f4ed87632372a607c22579 Mon Sep 17 00:00:00 2001
From: Santhosh Kumar Ellendula <sellendu at hu-sellendu-lv.qualcomm.com>
Date: Thu, 9 May 2024 01:46:51 -0700
Subject: [PATCH 04/15] [lldb-dap] Added "port" property to vscode "attach"
 command. Resolved code format issues.

---
 .../API/tools/lldb-dap/attach/TestDAP_attachByPortNum.py    | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/lldb/test/API/tools/lldb-dap/attach/TestDAP_attachByPortNum.py b/lldb/test/API/tools/lldb-dap/attach/TestDAP_attachByPortNum.py
index 4b9965cbb5571..c1b0d57cffb94 100644
--- a/lldb/test/API/tools/lldb-dap/attach/TestDAP_attachByPortNum.py
+++ b/lldb/test/API/tools/lldb-dap/attach/TestDAP_attachByPortNum.py
@@ -22,7 +22,7 @@ def runTargetProgramOnPort(self, port=None, program=None):
         server_tool = "lldb-server"
         server_path = self.getBuiltinServerTool(server_tool)
         if server_path:
-            server_path +=" g localhost:" +  port + " " 
+            server_path += " g localhost:" +  port + " "
 
         self.process = subprocess.Popen(
             [server_path + program],
@@ -31,7 +31,7 @@ def runTargetProgramOnPort(self, port=None, program=None):
             stdout=subprocess.PIPE,
             stderr=subprocess.PIPE,
         )
-        
+
         return self.process
 
     def set_and_hit_breakpoint(self, continueToExit=True):
@@ -43,7 +43,7 @@ def set_and_hit_breakpoint(self, continueToExit=True):
         breakpoint_ids = self.set_source_breakpoints(main_source_path, lines)
         self.assertEqual(
             len(breakpoint_ids), len(lines), "expect correct number of breakpoints"
-        )        
+        )
         self.continue_to_breakpoints(breakpoint_ids)
         if continueToExit:
             self.continue_to_exit()

>From e5c0aed39eb5903d1d98355bb2af4af134b98546 Mon Sep 17 00:00:00 2001
From: Santhosh Kumar Ellendula <sellendu at hu-sellendu-lv.qualcomm.com>
Date: Thu, 9 May 2024 01:58:17 -0700
Subject: [PATCH 05/15] Resolved code format issue.

---
 lldb/test/API/tools/lldb-dap/attach/TestDAP_attachByPortNum.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/lldb/test/API/tools/lldb-dap/attach/TestDAP_attachByPortNum.py b/lldb/test/API/tools/lldb-dap/attach/TestDAP_attachByPortNum.py
index c1b0d57cffb94..8962e887cd8b7 100644
--- a/lldb/test/API/tools/lldb-dap/attach/TestDAP_attachByPortNum.py
+++ b/lldb/test/API/tools/lldb-dap/attach/TestDAP_attachByPortNum.py
@@ -22,7 +22,7 @@ def runTargetProgramOnPort(self, port=None, program=None):
         server_tool = "lldb-server"
         server_path = self.getBuiltinServerTool(server_tool)
         if server_path:
-            server_path += " g localhost:" +  port + " "
+            server_path += " g localhost:" + port + " "
 
         self.process = subprocess.Popen(
             [server_path + program],

>From c502203c6b129ba569e36a1d922bb13c322f3706 Mon Sep 17 00:00:00 2001
From: Santhosh Kumar Ellendula <sellendu at hu-sellendu-lv.qualcomm.com>
Date: Thu, 9 May 2024 02:04:18 -0700
Subject: [PATCH 06/15] Resolved code format errors.

---
 lldb/test/API/tools/lldb-dap/attach/TestDAP_attachByPortNum.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/lldb/test/API/tools/lldb-dap/attach/TestDAP_attachByPortNum.py b/lldb/test/API/tools/lldb-dap/attach/TestDAP_attachByPortNum.py
index 8962e887cd8b7..aee92d94d1ae0 100644
--- a/lldb/test/API/tools/lldb-dap/attach/TestDAP_attachByPortNum.py
+++ b/lldb/test/API/tools/lldb-dap/attach/TestDAP_attachByPortNum.py
@@ -16,8 +16,8 @@
 import time
 import sys
 
-class TestDAP_attachByPortNum(lldbdap_testcase.DAPTestCaseBase):
 
+class TestDAP_attachByPortNum(lldbdap_testcase.DAPTestCaseBase):
     def runTargetProgramOnPort(self, port=None, program=None):
         server_tool = "lldb-server"
         server_path = self.getBuiltinServerTool(server_tool)

>From c1bf2bdaa33353913b8529750d41da482ce18161 Mon Sep 17 00:00:00 2001
From: Santhosh Kumar Ellendula <sellendu at hu-sellendu-lv.qualcomm.com>
Date: Wed, 15 May 2024 15:16:44 -0700
Subject: [PATCH 07/15] [lldb-dap] Added "port" property to vscode "attach"
 command - Addressed review comments Addressed all review comments.

---
 .../test/tools/lldb-dap/lldbdap_testcase.py   | 36 +++--------------
 .../attach/TestDAP_attachByPortNum.py         | 39 +++++++++++--------
 lldb/tools/lldb-dap/lldb-dap.cpp              |  2 +-
 3 files changed, 29 insertions(+), 48 deletions(-)

diff --git a/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/lldbdap_testcase.py b/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/lldbdap_testcase.py
index 922fb1d5784e6..d95a80482a60b 100644
--- a/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/lldbdap_testcase.py
+++ b/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/lldbdap_testcase.py
@@ -297,6 +297,9 @@ def attach(
         sourceMap=None,
         sourceInitFile=False,
         expectFailure=False,
+        port=None,
+        hostname=None,
+        
     ):
         """Build the default Makefile target, create the DAP debug adaptor,
         and attach to the process.
@@ -327,6 +330,8 @@ def cleanup():
             coreFile=coreFile,
             postRunCommands=postRunCommands,
             sourceMap=sourceMap,
+            port=port,
+            hostname=hostname,
         )
         if expectFailure:
             return response
@@ -335,37 +340,6 @@ def cleanup():
                 response["success"], "attach failed (%s)" % (response["message"])
             )
 
-    def attach_by_port(
-        self,
-        program=None,
-        pid=None,
-        disconnectAutomatically=True,
-        waitFor=None,
-        sourceInitFile=False,
-        port=None,
-        hostname=None,
-    ):
-        """Build the default Makefile target, create the VSCode debug adaptor,
-        and attach to the process.
-        """
-
-        # This overloaded function helps to request attach by port number
-        # Make sure we disconnect and terminate the VSCode debug adaptor even
-        # if we throw an exception during the test case.
-        def cleanup():
-            if disconnectAutomatically:
-                self.dap_server.request_disconnect(terminateDebuggee=True)
-            self.dap_server.terminate()
-
-        # Execute the cleanup function during test case tear down.
-        self.addTearDownHook(cleanup)
-        # Initialize and launch the program
-        self.dap_server.request_initialize(sourceInitFile)
-        response = self.dap_server.request_attach(
-            program=program, pid=pid, waitFor=waitFor, port=port, hostname=hostname
-        )
-        return response
-
     def launch(
         self,
         program=None,
diff --git a/lldb/test/API/tools/lldb-dap/attach/TestDAP_attachByPortNum.py b/lldb/test/API/tools/lldb-dap/attach/TestDAP_attachByPortNum.py
index aee92d94d1ae0..cfa20260fed39 100644
--- a/lldb/test/API/tools/lldb-dap/attach/TestDAP_attachByPortNum.py
+++ b/lldb/test/API/tools/lldb-dap/attach/TestDAP_attachByPortNum.py
@@ -7,6 +7,8 @@
 from lldbsuite.test.decorators import *
 from lldbsuite.test.lldbtest import *
 from lldbsuite.test import lldbutil
+from lldbsuite.test import lldbplatformutil
+import lldbgdbserverutils
 import lldbdap_testcase
 import os
 import shutil
@@ -19,13 +21,22 @@
 
 class TestDAP_attachByPortNum(lldbdap_testcase.DAPTestCaseBase):
     def runTargetProgramOnPort(self, port=None, program=None):
-        server_tool = "lldb-server"
-        server_path = self.getBuiltinServerTool(server_tool)
-        if server_path:
-            server_path += " g localhost:" + port + " "
+        server_tool = None
+        if (lldbplatformutil.getPlatform() == "linux"):
+            server_tool = lldbgdbserverutils.get_lldb_server_exe()
+            if server_tool is None:
+                self.dap_server.request_disconnect(terminateDebuggee=True)
+                self.assertIsNotNone(server_tool, "lldb-server not found.")
+            server_tool += " g localhost:" +  port + " "
+        elif (lldbplatformutil.getPlatform() == "macosx"):
+            server_tool = lldbgdbserverutils.get_debugserver_exe()
+            if server_tool is None:
+                self.dap_server.request_disconnect(terminateDebuggee=True)
+                self.assertIsNotNone(server_tool, "debugserver not found.")
+            server_tool += " --listen localhost:" +  port + " "
 
         self.process = subprocess.Popen(
-            [server_path + program],
+            [server_tool + program],
             shell=True,
             stdin=subprocess.PIPE,
             stdout=subprocess.PIPE,
@@ -61,13 +72,9 @@ def test_by_port(self):
         port = "2345"
         self.process = self.runTargetProgramOnPort(port=port, program=program)
         pid = self.process.pid
-        response = self.attach_by_port(
+        response = self.attach(
             program=program, port=int(port), sourceInitFile=True
         )
-        if not (response and response["success"]):
-            self.assertTrue(
-                response["success"], "attach failed (%s)" % (response["message"])
-            )
         self.set_and_hit_breakpoint(continueToExit=True)
         self.process.kill()
 
@@ -83,8 +90,8 @@ def test_by_port_and_pid(self):
 
         port = "2345"
         self.process = self.runTargetProgramOnPort(port=port, program=program)
-        response = self.attach_by_port(
-            program=program, pid=1234, port=int(port), sourceInitFile=True
+        response = self.attach(
+            program=program, pid=1234, port=int(port), sourceInitFile=True, expectFailure=True
         )
         if not (response and response["success"]):
             self.assertFalse(
@@ -104,8 +111,8 @@ def test_by_invalid_port(self):
 
         port = "0"
         self.process = self.runTargetProgramOnPort(port=port, program=program)
-        response = self.attach_by_port(
-            program=program, port=int(port), sourceInitFile=True
+        response = self.attach(
+            program=program, port=int(port), sourceInitFile=True, expectFailure=True
         )
         if not (response and response["success"]):
             self.assertFalse(
@@ -126,8 +133,8 @@ def test_by_illegal_port(self):
 
         port = "65536"
         self.process = self.runTargetProgramOnPort(port=port, program=program)
-        response = self.attach_by_port(
-            program=program, port=int(port), sourceInitFile=True
+        response = self.attach(
+            program=program, port=int(port), sourceInitFile=True, expectFailure=True
         )
         if not (response and response["success"]):
             self.assertFalse(
diff --git a/lldb/tools/lldb-dap/lldb-dap.cpp b/lldb/tools/lldb-dap/lldb-dap.cpp
index a403e7ae26bfd..c9cd6ffe1db43 100644
--- a/lldb/tools/lldb-dap/lldb-dap.cpp
+++ b/lldb/tools/lldb-dap/lldb-dap.cpp
@@ -758,7 +758,7 @@ void request_attach(const llvm::json::Object &request) {
           (port != LLDB_INVALID_PORT_NUMBER)) {
         // If both pid and port numbers are specified.
         error.SetErrorString("The user can't specify both pid and port");
-      } else if ((port != LLDB_INVALID_PORT_NUMBER) && (port < UINT16_MAX)) {
+      } else if (port != LLDB_INVALID_PORT_NUMBER) {
         // If port is specified and pid is not.
         lldb::SBListener listener = g_dap.debugger.GetListener();
 

>From 5590afc46aff9765f314139bbf4a446ca0f21b0c Mon Sep 17 00:00:00 2001
From: Santhosh Kumar Ellendula <sellendu at hu-sellendu-lv.qualcomm.com>
Date: Wed, 15 May 2024 15:32:29 -0700
Subject: [PATCH 08/15] [lldb-dap] Added "port" property to vscode "attach"
 command - fix code format resolved code format issues.

---
 .../test/tools/lldb-dap/lldbdap_testcase.py    |  1 -
 .../lldb-dap/attach/TestDAP_attachByPortNum.py | 18 ++++++++++--------
 2 files changed, 10 insertions(+), 9 deletions(-)

diff --git a/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/lldbdap_testcase.py b/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/lldbdap_testcase.py
index d95a80482a60b..a2bef31ceb0ce 100644
--- a/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/lldbdap_testcase.py
+++ b/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/lldbdap_testcase.py
@@ -299,7 +299,6 @@ def attach(
         expectFailure=False,
         port=None,
         hostname=None,
-        
     ):
         """Build the default Makefile target, create the DAP debug adaptor,
         and attach to the process.
diff --git a/lldb/test/API/tools/lldb-dap/attach/TestDAP_attachByPortNum.py b/lldb/test/API/tools/lldb-dap/attach/TestDAP_attachByPortNum.py
index cfa20260fed39..e5cdc256a7abc 100644
--- a/lldb/test/API/tools/lldb-dap/attach/TestDAP_attachByPortNum.py
+++ b/lldb/test/API/tools/lldb-dap/attach/TestDAP_attachByPortNum.py
@@ -22,18 +22,18 @@
 class TestDAP_attachByPortNum(lldbdap_testcase.DAPTestCaseBase):
     def runTargetProgramOnPort(self, port=None, program=None):
         server_tool = None
-        if (lldbplatformutil.getPlatform() == "linux"):
+        if lldbplatformutil.getPlatform() == "linux":
             server_tool = lldbgdbserverutils.get_lldb_server_exe()
             if server_tool is None:
                 self.dap_server.request_disconnect(terminateDebuggee=True)
                 self.assertIsNotNone(server_tool, "lldb-server not found.")
-            server_tool += " g localhost:" +  port + " "
-        elif (lldbplatformutil.getPlatform() == "macosx"):
+            server_tool += " g localhost:" + port + " "
+        elif lldbplatformutil.getPlatform() == "macosx":
             server_tool = lldbgdbserverutils.get_debugserver_exe()
             if server_tool is None:
                 self.dap_server.request_disconnect(terminateDebuggee=True)
                 self.assertIsNotNone(server_tool, "debugserver not found.")
-            server_tool += " --listen localhost:" +  port + " "
+            server_tool += " --listen localhost:" + port + " "
 
         self.process = subprocess.Popen(
             [server_tool + program],
@@ -72,9 +72,7 @@ def test_by_port(self):
         port = "2345"
         self.process = self.runTargetProgramOnPort(port=port, program=program)
         pid = self.process.pid
-        response = self.attach(
-            program=program, port=int(port), sourceInitFile=True
-        )
+        response = self.attach(program=program, port=int(port), sourceInitFile=True)
         self.set_and_hit_breakpoint(continueToExit=True)
         self.process.kill()
 
@@ -91,7 +89,11 @@ def test_by_port_and_pid(self):
         port = "2345"
         self.process = self.runTargetProgramOnPort(port=port, program=program)
         response = self.attach(
-            program=program, pid=1234, port=int(port), sourceInitFile=True, expectFailure=True
+            program=program,
+            pid=1234,
+            port=int(port),
+            sourceInitFile=True,
+            expectFailure=True,
         )
         if not (response and response["success"]):
             self.assertFalse(

>From 023b51e61e3e5127dc2289ea47e2e4d3e7a6db26 Mon Sep 17 00:00:00 2001
From: Santhosh Kumar Ellendula <sellendu at hu-sellendu-lv.qualcomm.com>
Date: Tue, 28 May 2024 11:11:33 -0700
Subject: [PATCH 09/15] [lldb-dap] Added "port" property to vscode "attach"
 command - resolved all review comments. All review comments have been
 addressed, and the attach-by-port tests have been verified on Linux machine.
 Although the functionality is intended to support both Linux and macOS, we
 were unable to verify it on macOS due to lack of access.

---
 lldb/include/lldb/lldb-defines.h              |  1 -
 .../Python/lldbsuite/test/lldbtest.py         |  9 ----
 .../test/tools/lldb-dap/lldbdap_testcase.py   | 20 ++++++++
 .../attach/TestDAP_attachByPortNum.py         | 50 +++++++++----------
 lldb/tools/lldb-dap/lldb-dap.cpp              | 11 ++--
 5 files changed, 49 insertions(+), 42 deletions(-)

diff --git a/lldb/include/lldb/lldb-defines.h b/lldb/include/lldb/lldb-defines.h
index a1e6ee2ce468c..c7bd019c5c90e 100644
--- a/lldb/include/lldb/lldb-defines.h
+++ b/lldb/include/lldb/lldb-defines.h
@@ -96,7 +96,6 @@
 #define LLDB_INVALID_QUEUE_ID 0
 #define LLDB_INVALID_CPU_ID UINT32_MAX
 #define LLDB_INVALID_WATCHPOINT_RESOURCE_ID UINT32_MAX
-#define LLDB_INVALID_PORT_NUMBER 0
 
 /// CPU Type definitions
 #define LLDB_ARCH_DEFAULT "systemArch"
diff --git a/lldb/packages/Python/lldbsuite/test/lldbtest.py b/lldb/packages/Python/lldbsuite/test/lldbtest.py
index 5a93dc93c3eee..1ad8ab6e6e462 100644
--- a/lldb/packages/Python/lldbsuite/test/lldbtest.py
+++ b/lldb/packages/Python/lldbsuite/test/lldbtest.py
@@ -1637,15 +1637,6 @@ def findBuiltClang(self):
 
         return os.environ["CC"]
 
-    def getBuiltinServerTool(self, server_tool):
-        # Tries to find simulation/lldb-server/gdbserver tool at the same folder as the lldb.
-        lldb_dir = os.path.dirname(lldbtest_config.lldbExec)
-        path = shutil.which(server_tool, path=lldb_dir)
-        if path is not None:
-            return path
-
-        return ""
-
     def yaml2obj(self, yaml_path, obj_path, max_size=None):
         """
         Create an object file at the given path from a yaml file.
diff --git a/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/lldbdap_testcase.py b/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/lldbdap_testcase.py
index a2bef31ceb0ce..15d8a94a1f714 100644
--- a/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/lldbdap_testcase.py
+++ b/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/lldbdap_testcase.py
@@ -3,6 +3,8 @@
 
 import dap_server
 from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbplatformutil
+import lldbgdbserverutils
 
 
 class DAPTestCaseBase(TestBase):
@@ -487,3 +489,21 @@ def build_and_launch(
             launchCommands=launchCommands,
             expectFailure=expectFailure,
         )
+
+    def getBuiltinServerToolWithPortArg(self, port):
+        # Tries to find simulation/lldb-server/gdbserver tool and
+        # configure the server arguments to attach with given port numeber.
+        server_tool = None
+        if lldbplatformutil.getPlatform() == "linux":
+            server_tool = lldbgdbserverutils.get_lldb_server_exe()
+            if server_tool is None:
+                self.dap_server.request_disconnect(terminateDebuggee=True)
+                self.assertIsNotNone(server_tool, "lldb-server not found.")
+            server_tool += " g localhost:" + str(port) + " "
+        elif lldbplatformutil.getPlatform() == "macosx":
+            server_tool = lldbgdbserverutils.get_debugserver_exe()
+            if server_tool is None:
+                self.dap_server.request_disconnect(terminateDebuggee=True)
+                self.assertIsNotNone(server_tool, "debugserver not found.")
+            server_tool += " --listen localhost:" + str(port) + " "
+        return server_tool
diff --git a/lldb/test/API/tools/lldb-dap/attach/TestDAP_attachByPortNum.py b/lldb/test/API/tools/lldb-dap/attach/TestDAP_attachByPortNum.py
index e5cdc256a7abc..6933bd04fdda4 100644
--- a/lldb/test/API/tools/lldb-dap/attach/TestDAP_attachByPortNum.py
+++ b/lldb/test/API/tools/lldb-dap/attach/TestDAP_attachByPortNum.py
@@ -17,24 +17,19 @@
 import threading
 import time
 import sys
+import socket
 
 
 class TestDAP_attachByPortNum(lldbdap_testcase.DAPTestCaseBase):
-    def runTargetProgramOnPort(self, port=None, program=None):
-        server_tool = None
-        if lldbplatformutil.getPlatform() == "linux":
-            server_tool = lldbgdbserverutils.get_lldb_server_exe()
-            if server_tool is None:
-                self.dap_server.request_disconnect(terminateDebuggee=True)
-                self.assertIsNotNone(server_tool, "lldb-server not found.")
-            server_tool += " g localhost:" + port + " "
-        elif lldbplatformutil.getPlatform() == "macosx":
-            server_tool = lldbgdbserverutils.get_debugserver_exe()
-            if server_tool is None:
-                self.dap_server.request_disconnect(terminateDebuggee=True)
-                self.assertIsNotNone(server_tool, "debugserver not found.")
-            server_tool += " --listen localhost:" + port + " "
+    def get_free_port(self):
+        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+        s.bind(('', 0))
+        port = s.getsockname()[1]
+        s.close()
+        return port
 
+    def runTargetProgramOnPort(self, port=None, program=None):
+        server_tool = self.getBuiltinServerToolWithPortArg(port)
         self.process = subprocess.Popen(
             [server_tool + program],
             shell=True,
@@ -60,7 +55,7 @@ def set_and_hit_breakpoint(self, continueToExit=True):
             self.continue_to_exit()
 
     @skipIfWindows
-    @skipIfNetBSD  # Hangs on NetBSD as well
+    @skipIfNetBSD
     @skipIfRemote
     def test_by_port(self):
         """
@@ -69,15 +64,15 @@ def test_by_port(self):
         self.build_and_create_debug_adaptor()
         program = self.getBuildArtifact("a.out")
 
-        port = "2345"
+        port = self.get_free_port()
         self.process = self.runTargetProgramOnPort(port=port, program=program)
         pid = self.process.pid
-        response = self.attach(program=program, port=int(port), sourceInitFile=True)
+        response = self.attach(program=program, port=port, sourceInitFile=True)
         self.set_and_hit_breakpoint(continueToExit=True)
         self.process.kill()
 
     @skipIfWindows
-    @skipIfNetBSD  # Hangs on NetBSD as well
+    @skipIfNetBSD
     @skipIfRemote
     def test_by_port_and_pid(self):
         """
@@ -86,12 +81,13 @@ def test_by_port_and_pid(self):
         self.build_and_create_debug_adaptor()
         program = self.getBuildArtifact("a.out")
 
-        port = "2345"
+        port = self.get_free_port()
         self.process = self.runTargetProgramOnPort(port=port, program=program)
+        pid = self.process.pid
         response = self.attach(
             program=program,
-            pid=1234,
-            port=int(port),
+            pid=pid,
+            port=port,
             sourceInitFile=True,
             expectFailure=True,
         )
@@ -102,7 +98,7 @@ def test_by_port_and_pid(self):
         self.process.kill()
 
     @skipIfWindows
-    @skipIfNetBSD  # Hangs on NetBSD as well
+    @skipIfNetBSD
     @skipIfRemote
     def test_by_invalid_port(self):
         """
@@ -111,10 +107,10 @@ def test_by_invalid_port(self):
         self.build_and_create_debug_adaptor()
         program = self.getBuildArtifact("a.out")
 
-        port = "0"
+        port = 0
         self.process = self.runTargetProgramOnPort(port=port, program=program)
         response = self.attach(
-            program=program, port=int(port), sourceInitFile=True, expectFailure=True
+            program=program, port=port, sourceInitFile=True, expectFailure=True
         )
         if not (response and response["success"]):
             self.assertFalse(
@@ -124,7 +120,7 @@ def test_by_invalid_port(self):
         self.process.kill()
 
     @skipIfWindows
-    @skipIfNetBSD  # Hangs on NetBSD as well
+    @skipIfNetBSD
     @skipIfRemote
     def test_by_illegal_port(self):
         """
@@ -133,10 +129,10 @@ def test_by_illegal_port(self):
         self.build_and_create_debug_adaptor()
         program = self.getBuildArtifact("a.out")
 
-        port = "65536"
+        port = 65536
         self.process = self.runTargetProgramOnPort(port=port, program=program)
         response = self.attach(
-            program=program, port=int(port), sourceInitFile=True, expectFailure=True
+            program=program, port=port, sourceInitFile=True, expectFailure=True
         )
         if not (response and response["success"]):
             self.assertFalse(
diff --git a/lldb/tools/lldb-dap/lldb-dap.cpp b/lldb/tools/lldb-dap/lldb-dap.cpp
index 1a45ae3d7adbd..9fedad8a41482 100644
--- a/lldb/tools/lldb-dap/lldb-dap.cpp
+++ b/lldb/tools/lldb-dap/lldb-dap.cpp
@@ -672,11 +672,12 @@ void request_attach(const llvm::json::Object &request) {
   lldb::SBError error;
   FillResponse(request, response);
   lldb::SBAttachInfo attach_info;
+  const int invalid_port = 0;
   auto arguments = request.getObject("arguments");
   const lldb::pid_t pid =
       GetUnsigned(arguments, "pid", LLDB_INVALID_PROCESS_ID);
-  const auto port = GetUnsigned(arguments, "port", LLDB_INVALID_PORT_NUMBER);
-  llvm::StringRef hostname = GetString(arguments, "hostname");
+  const auto port = GetUnsigned(arguments, "port", invalid_port);
+  llvm::StringRef hostname = GetString(arguments, "hostname", "localhost");
   if (pid != LLDB_INVALID_PROCESS_ID)
     attach_info.SetProcessID(pid);
   const auto wait_for = GetBoolean(arguments, "waitFor", false);
@@ -738,7 +739,7 @@ void request_attach(const llvm::json::Object &request) {
     return;
   }
 
-  if ((pid == LLDB_INVALID_PROCESS_ID || port == LLDB_INVALID_PORT_NUMBER) &&
+  if ((pid == LLDB_INVALID_PROCESS_ID || port == invalid_port) &&
       wait_for) {
     char attach_msg[256];
     auto attach_msg_len = snprintf(attach_msg, sizeof(attach_msg),
@@ -754,10 +755,10 @@ void request_attach(const llvm::json::Object &request) {
     g_dap.debugger.SetAsync(false);
     if (core_file.empty()) {
       if ((pid != LLDB_INVALID_PROCESS_ID) &&
-          (port != LLDB_INVALID_PORT_NUMBER)) {
+          (port != invalid_port)) {
         // If both pid and port numbers are specified.
         error.SetErrorString("The user can't specify both pid and port");
-      } else if (port != LLDB_INVALID_PORT_NUMBER) {
+      } else if (port != invalid_port) {
         // If port is specified and pid is not.
         lldb::SBListener listener = g_dap.debugger.GetListener();
 

>From d19eb88231cb1ca3d7519061811cbacf34402194 Mon Sep 17 00:00:00 2001
From: Santhosh Kumar Ellendula <sellendu at hu-sellendu-lv.qualcomm.com>
Date: Tue, 28 May 2024 11:27:04 -0700
Subject: [PATCH 10/15] [lldb-dap] Added "port" property to vscode "attach"
 command -resolved format check issues.

---
 .../API/tools/lldb-dap/attach/TestDAP_attachByPortNum.py    | 2 +-
 lldb/tools/lldb-dap/lldb-dap.cpp                            | 6 ++----
 2 files changed, 3 insertions(+), 5 deletions(-)

diff --git a/lldb/test/API/tools/lldb-dap/attach/TestDAP_attachByPortNum.py b/lldb/test/API/tools/lldb-dap/attach/TestDAP_attachByPortNum.py
index 6933bd04fdda4..f220b45488301 100644
--- a/lldb/test/API/tools/lldb-dap/attach/TestDAP_attachByPortNum.py
+++ b/lldb/test/API/tools/lldb-dap/attach/TestDAP_attachByPortNum.py
@@ -23,7 +23,7 @@
 class TestDAP_attachByPortNum(lldbdap_testcase.DAPTestCaseBase):
     def get_free_port(self):
         s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
-        s.bind(('', 0))
+        s.bind(("", 0))
         port = s.getsockname()[1]
         s.close()
         return port
diff --git a/lldb/tools/lldb-dap/lldb-dap.cpp b/lldb/tools/lldb-dap/lldb-dap.cpp
index 9fedad8a41482..e5165459dd914 100644
--- a/lldb/tools/lldb-dap/lldb-dap.cpp
+++ b/lldb/tools/lldb-dap/lldb-dap.cpp
@@ -739,8 +739,7 @@ void request_attach(const llvm::json::Object &request) {
     return;
   }
 
-  if ((pid == LLDB_INVALID_PROCESS_ID || port == invalid_port) &&
-      wait_for) {
+  if ((pid == LLDB_INVALID_PROCESS_ID || port == invalid_port) && wait_for) {
     char attach_msg[256];
     auto attach_msg_len = snprintf(attach_msg, sizeof(attach_msg),
                                    "Waiting to attach to \"%s\"...",
@@ -754,8 +753,7 @@ void request_attach(const llvm::json::Object &request) {
     // the launch call and the launch will happen synchronously
     g_dap.debugger.SetAsync(false);
     if (core_file.empty()) {
-      if ((pid != LLDB_INVALID_PROCESS_ID) &&
-          (port != invalid_port)) {
+      if ((pid != LLDB_INVALID_PROCESS_ID) && (port != invalid_port)) {
         // If both pid and port numbers are specified.
         error.SetErrorString("The user can't specify both pid and port");
       } else if (port != invalid_port) {

>From fe9a4b685eb089cadcc914ba1583bcbc085ada5a Mon Sep 17 00:00:00 2001
From: Santhosh Kumar Ellendula <sellendu at hu-sellendu-lv.qualcomm.com>
Date: Thu, 30 May 2024 04:24:09 -0700
Subject: [PATCH 11/15] [lldb-dap] Added "port" property to vscode "attach"
 command. #91570 Resolved few review commennts.

---
 .../API/tools/lldb-dap/attach/TestDAP_attachByPortNum.py   | 4 ----
 lldb/tools/lldb-dap/lldb-dap.cpp                           | 7 +------
 2 files changed, 1 insertion(+), 10 deletions(-)

diff --git a/lldb/test/API/tools/lldb-dap/attach/TestDAP_attachByPortNum.py b/lldb/test/API/tools/lldb-dap/attach/TestDAP_attachByPortNum.py
index f220b45488301..2198fc77b8326 100644
--- a/lldb/test/API/tools/lldb-dap/attach/TestDAP_attachByPortNum.py
+++ b/lldb/test/API/tools/lldb-dap/attach/TestDAP_attachByPortNum.py
@@ -56,7 +56,6 @@ def set_and_hit_breakpoint(self, continueToExit=True):
 
     @skipIfWindows
     @skipIfNetBSD
-    @skipIfRemote
     def test_by_port(self):
         """
         Tests attaching to a process by port.
@@ -73,7 +72,6 @@ def test_by_port(self):
 
     @skipIfWindows
     @skipIfNetBSD
-    @skipIfRemote
     def test_by_port_and_pid(self):
         """
         Tests attaching to a process by process ID and port number.
@@ -99,7 +97,6 @@ def test_by_port_and_pid(self):
 
     @skipIfWindows
     @skipIfNetBSD
-    @skipIfRemote
     def test_by_invalid_port(self):
         """
         Tests attaching to a process by invalid port number 0.
@@ -121,7 +118,6 @@ def test_by_invalid_port(self):
 
     @skipIfWindows
     @skipIfNetBSD
-    @skipIfRemote
     def test_by_illegal_port(self):
         """
         Tests attaching to a process by illegal/greater port number 65536
diff --git a/lldb/tools/lldb-dap/lldb-dap.cpp b/lldb/tools/lldb-dap/lldb-dap.cpp
index e5165459dd914..985652f4801eb 100644
--- a/lldb/tools/lldb-dap/lldb-dap.cpp
+++ b/lldb/tools/lldb-dap/lldb-dap.cpp
@@ -762,12 +762,7 @@ void request_attach(const llvm::json::Object &request) {
 
         // If the user hasn't provided the hostname property, default localhost
         // being used.
-        std::string connect_url("connect://localhost:");
-
-        // If the user has provided hostname other than localhost.
-        if (!hostname.empty() && !hostname.starts_with("localhost")) {
-          connect_url = llvm::formatv("connect://{0}:", hostname.data());
-        }
+        std::string connect_url = llvm::formatv("connect://{0}:", hostname.data());
         connect_url += std::to_string(port);
         g_dap.target.ConnectRemote(listener, connect_url.c_str(), "gdb-remote",
                                    error);

>From c91b02de2896cc6ce5a9ab9493dedb44244c329c Mon Sep 17 00:00:00 2001
From: Santhosh Kumar Ellendula <sellendu at hu-sellendu-lv.qualcomm.com>
Date: Thu, 30 May 2024 05:24:23 -0700
Subject: [PATCH 12/15] [lldb-dap] Added "port" property to vscode "attach"
 command. Resolved code format issues.

---
 lldb/tools/lldb-dap/lldb-dap.cpp | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/lldb/tools/lldb-dap/lldb-dap.cpp b/lldb/tools/lldb-dap/lldb-dap.cpp
index 985652f4801eb..ac862dc4ea1d2 100644
--- a/lldb/tools/lldb-dap/lldb-dap.cpp
+++ b/lldb/tools/lldb-dap/lldb-dap.cpp
@@ -762,7 +762,8 @@ void request_attach(const llvm::json::Object &request) {
 
         // If the user hasn't provided the hostname property, default localhost
         // being used.
-        std::string connect_url = llvm::formatv("connect://{0}:", hostname.data());
+        std::string connect_url =
+            llvm::formatv("connect://{0}:", hostname.data());
         connect_url += std::to_string(port);
         g_dap.target.ConnectRemote(listener, connect_url.c_str(), "gdb-remote",
                                    error);

>From de29728f0ccf7c82035eba751062608b85833d5a Mon Sep 17 00:00:00 2001
From: Santhosh Kumar Ellendula <sellendu at hu-sellendu-lv.qualcomm.com>
Date: Tue, 4 Jun 2024 10:36:02 -0700
Subject: [PATCH 13/15] [lldb-dap] Added "port" property to vscode "attach"
 command - addressed review comments. Used named pipe to read debug server
 listening port. Since we are only using "gdb-remote" process plugin, changed
 to "gdb-remote-port" and "gdb-remote-hostname" from "port" and "hostname"

---
 .../test/tools/lldb-dap/dap_server.py         |  12 +-
 .../test/tools/lldb-dap/lldbdap_testcase.py   |  15 +-
 .../attach/TestDAP_attachByPortNum.py         | 129 +++++++++++++-----
 lldb/tools/lldb-dap/lldb-dap.cpp              |  14 +-
 lldb/tools/lldb-dap/package.json              |   4 +-
 5 files changed, 115 insertions(+), 59 deletions(-)

diff --git a/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py b/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py
index bab16479d26c3..fbfa851c1356c 100644
--- a/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py
+++ b/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py
@@ -572,8 +572,8 @@ def request_attach(
         coreFile=None,
         postRunCommands=None,
         sourceMap=None,
-        port=None,
-        hostname=None,
+        gdbRemotePort=None,
+        gdbRemoteHostname=None,
     ):
         args_dict = {}
         if pid is not None:
@@ -603,10 +603,10 @@ def request_attach(
             args_dict["postRunCommands"] = postRunCommands
         if sourceMap:
             args_dict["sourceMap"] = sourceMap
-        if port is not None:
-            args_dict["port"] = port
-        if hostname is not None:
-            args_dict["hostname"] = hostname
+        if gdbRemotePort is not None:
+            args_dict["gdb-remote-port"] = gdbRemotePort
+        if gdbRemoteHostname is not None:
+            args_dict["gdb-remote-hostname"] = gdbRemoteHostname
         command_dict = {"command": "attach", "type": "request", "arguments": args_dict}
         return self.send_recv(command_dict)
 
diff --git a/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/lldbdap_testcase.py b/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/lldbdap_testcase.py
index 15d8a94a1f714..086c6c5f90655 100644
--- a/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/lldbdap_testcase.py
+++ b/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/lldbdap_testcase.py
@@ -299,8 +299,8 @@ def attach(
         sourceMap=None,
         sourceInitFile=False,
         expectFailure=False,
-        port=None,
-        hostname=None,
+        gdbRemotePort=None,
+        gdbRemoteHostname=None,
     ):
         """Build the default Makefile target, create the DAP debug adaptor,
         and attach to the process.
@@ -331,8 +331,8 @@ def cleanup():
             coreFile=coreFile,
             postRunCommands=postRunCommands,
             sourceMap=sourceMap,
-            port=port,
-            hostname=hostname,
+            gdbRemotePort=gdbRemotePort,
+            gdbRemoteHostname=gdbRemoteHostname,
         )
         if expectFailure:
             return response
@@ -490,20 +490,17 @@ def build_and_launch(
             expectFailure=expectFailure,
         )
 
-    def getBuiltinServerToolWithPortArg(self, port):
-        # Tries to find simulation/lldb-server/gdbserver tool and
-        # configure the server arguments to attach with given port numeber.
+    def getBuiltinDebugServerTool(self):
+        # Tries to find simulation/lldb-server/gdbserver tool path.
         server_tool = None
         if lldbplatformutil.getPlatform() == "linux":
             server_tool = lldbgdbserverutils.get_lldb_server_exe()
             if server_tool is None:
                 self.dap_server.request_disconnect(terminateDebuggee=True)
                 self.assertIsNotNone(server_tool, "lldb-server not found.")
-            server_tool += " g localhost:" + str(port) + " "
         elif lldbplatformutil.getPlatform() == "macosx":
             server_tool = lldbgdbserverutils.get_debugserver_exe()
             if server_tool is None:
                 self.dap_server.request_disconnect(terminateDebuggee=True)
                 self.assertIsNotNone(server_tool, "debugserver not found.")
-            server_tool += " --listen localhost:" + str(port) + " "
         return server_tool
diff --git a/lldb/test/API/tools/lldb-dap/attach/TestDAP_attachByPortNum.py b/lldb/test/API/tools/lldb-dap/attach/TestDAP_attachByPortNum.py
index 2198fc77b8326..5c247462350c6 100644
--- a/lldb/test/API/tools/lldb-dap/attach/TestDAP_attachByPortNum.py
+++ b/lldb/test/API/tools/lldb-dap/attach/TestDAP_attachByPortNum.py
@@ -8,38 +8,39 @@
 from lldbsuite.test.lldbtest import *
 from lldbsuite.test import lldbutil
 from lldbsuite.test import lldbplatformutil
-import lldbgdbserverutils
 import lldbdap_testcase
 import os
 import shutil
 import subprocess
 import tempfile
 import threading
-import time
 import sys
 import socket
+import select
 
 
-class TestDAP_attachByPortNum(lldbdap_testcase.DAPTestCaseBase):
-    def get_free_port(self):
-        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
-        s.bind(("", 0))
-        port = s.getsockname()[1]
-        s.close()
-        return port
-
-    def runTargetProgramOnPort(self, port=None, program=None):
-        server_tool = self.getBuiltinServerToolWithPortArg(port)
-        self.process = subprocess.Popen(
-            [server_tool + program],
-            shell=True,
-            stdin=subprocess.PIPE,
-            stdout=subprocess.PIPE,
-            stderr=subprocess.PIPE,
-        )
+# A class representing a pipe for communicating with debug server.
+# This class includes menthods to open the pipe and read the port number from it.
+class Pipe(object):
+    def __init__(self, prefix):
+        self.name = os.path.join(prefix, "stub_port_number")
+        os.mkfifo(self.name)
+        self._fd = os.open(self.name, os.O_RDONLY | os.O_NONBLOCK)
+
+    def finish_connection(self, timeout):
+        pass
+
+    def read(self, size, timeout):
+        (readers, _, _) = select.select([self._fd], [], [], timeout)
+        if self._fd not in readers:
+            raise TimeoutError
+        return os.read(self._fd, size)
 
-        return self.process
+    def close(self):
+        os.close(self._fd)
 
+class TestDAP_attachByPortNum(lldbdap_testcase.DAPTestCaseBase):
+    default_timeout = 20
     def set_and_hit_breakpoint(self, continueToExit=True):
         source = "main.c"
         main_source_path = os.path.join(os.getcwd(), source)
@@ -54,21 +55,54 @@ def set_and_hit_breakpoint(self, continueToExit=True):
         if continueToExit:
             self.continue_to_exit()
 
+    def get_debug_server_command_line_args(self):
+        args = []
+        if lldbplatformutil.getPlatform() == "linux":
+            args = ["gdbserver"]    
+        elif lldbplatformutil.getPlatform() == "macosx":
+            args = ["--listen"]
+        if lldb.remote_platform:
+            args += ["*:0"]
+        else:
+            args += ["localhost:0"]
+        return args
+
+    def get_debug_server_pipe(self):
+        pipe = Pipe(self.getBuildDir())
+        self.addTearDownHook(lambda: pipe.close())
+        pipe.finish_connection(self.default_timeout)
+        return pipe
+        
     @skipIfWindows
     @skipIfNetBSD
     def test_by_port(self):
         """
         Tests attaching to a process by port.
         """
+        
         self.build_and_create_debug_adaptor()
         program = self.getBuildArtifact("a.out")
+        
+        debug_server_tool = self.getBuiltinDebugServerTool()
 
-        port = self.get_free_port()
-        self.process = self.runTargetProgramOnPort(port=port, program=program)
-        pid = self.process.pid
-        response = self.attach(program=program, port=port, sourceInitFile=True)
+        pipe = self.get_debug_server_pipe()
+        args = self.get_debug_server_command_line_args()
+        args += [program]
+        args += ["--named-pipe", pipe.name]
+        
+        self.process = self.spawnSubprocess(
+            debug_server_tool, args, install_remote=False
+        )
+        
+        # Read the port number from the debug server pipe.
+        port = pipe.read(10, 30)
+        # Trim null byte, convert to int
+        port = int(port[:-1])
+        self.assertIsNotNone(port, " Failed to read the port number from debug server pipe")
+
+        self.attach(program=program, gdbRemotePort=port, sourceInitFile=True)
         self.set_and_hit_breakpoint(continueToExit=True)
-        self.process.kill()
+        self.process.terminate()
 
     @skipIfWindows
     @skipIfNetBSD
@@ -79,13 +113,28 @@ def test_by_port_and_pid(self):
         self.build_and_create_debug_adaptor()
         program = self.getBuildArtifact("a.out")
 
-        port = self.get_free_port()
-        self.process = self.runTargetProgramOnPort(port=port, program=program)
+        debug_server_tool = self.getBuiltinDebugServerTool()
+        pipe = self.get_debug_server_pipe()
+        args = self.get_debug_server_command_line_args()
+        args += [program]
+        args += ["--named-pipe", pipe.name]
+        
+        self.process = self.spawnSubprocess(
+            debug_server_tool, args, install_remote=False
+        )
+        
+        # Read the port number from the debug server pipe.
+        port = pipe.read(10, 30)
+        # Trim null byte, convert to int
+        port = int(port[:-1])
+        self.assertIsNotNone(port, " Failed to read the port number from debug server pipe")
+        
         pid = self.process.pid
+        
         response = self.attach(
             program=program,
             pid=pid,
-            port=port,
+            gdbRemotePort=port,
             sourceInitFile=True,
             expectFailure=True,
         )
@@ -93,7 +142,7 @@ def test_by_port_and_pid(self):
             self.assertFalse(
                 response["success"], "The user can't specify both pid and port"
             )
-        self.process.kill()
+        self.process.terminate()
 
     @skipIfWindows
     @skipIfNetBSD
@@ -105,16 +154,21 @@ def test_by_invalid_port(self):
         program = self.getBuildArtifact("a.out")
 
         port = 0
-        self.process = self.runTargetProgramOnPort(port=port, program=program)
+        args = [program]
+        debug_server_tool = self.getBuiltinDebugServerTool()
+        self.process = self.spawnSubprocess(
+            debug_server_tool, args, install_remote=False
+        )
+
         response = self.attach(
-            program=program, port=port, sourceInitFile=True, expectFailure=True
+            program=program, gdbRemotePort=port, sourceInitFile=True, expectFailure=True
         )
         if not (response and response["success"]):
             self.assertFalse(
                 response["success"],
                 "The user can't attach with invalid port (%s)" % port,
             )
-        self.process.kill()
+        self.process.terminate()
 
     @skipIfWindows
     @skipIfNetBSD
@@ -126,13 +180,18 @@ def test_by_illegal_port(self):
         program = self.getBuildArtifact("a.out")
 
         port = 65536
-        self.process = self.runTargetProgramOnPort(port=port, program=program)
+        args = [program]
+        debug_server_tool = self.getBuiltinDebugServerTool()
+        self.process = self.spawnSubprocess(
+            debug_server_tool, args, install_remote=False
+        )
+
         response = self.attach(
-            program=program, port=port, sourceInitFile=True, expectFailure=True
+            program=program, gdbRemotePort=port, sourceInitFile=True, expectFailure=True
         )
         if not (response and response["success"]):
             self.assertFalse(
                 response["success"],
                 "The user can't attach with illegal port (%s)" % port,
             )
-        self.process.kill()
+        self.process.terminate()
diff --git a/lldb/tools/lldb-dap/lldb-dap.cpp b/lldb/tools/lldb-dap/lldb-dap.cpp
index ac862dc4ea1d2..b852a470f6d4b 100644
--- a/lldb/tools/lldb-dap/lldb-dap.cpp
+++ b/lldb/tools/lldb-dap/lldb-dap.cpp
@@ -676,8 +676,8 @@ void request_attach(const llvm::json::Object &request) {
   auto arguments = request.getObject("arguments");
   const lldb::pid_t pid =
       GetUnsigned(arguments, "pid", LLDB_INVALID_PROCESS_ID);
-  const auto port = GetUnsigned(arguments, "port", invalid_port);
-  llvm::StringRef hostname = GetString(arguments, "hostname", "localhost");
+  const auto gdb_remote_port = GetUnsigned(arguments, "gdb-remote-port", invalid_port);
+  llvm::StringRef gdb_remote_hostname = GetString(arguments, "gdb-remote-hostname", "localhost");
   if (pid != LLDB_INVALID_PROCESS_ID)
     attach_info.SetProcessID(pid);
   const auto wait_for = GetBoolean(arguments, "waitFor", false);
@@ -739,7 +739,7 @@ void request_attach(const llvm::json::Object &request) {
     return;
   }
 
-  if ((pid == LLDB_INVALID_PROCESS_ID || port == invalid_port) && wait_for) {
+  if ((pid == LLDB_INVALID_PROCESS_ID || gdb_remote_port == invalid_port) && wait_for) {
     char attach_msg[256];
     auto attach_msg_len = snprintf(attach_msg, sizeof(attach_msg),
                                    "Waiting to attach to \"%s\"...",
@@ -753,18 +753,18 @@ void request_attach(const llvm::json::Object &request) {
     // the launch call and the launch will happen synchronously
     g_dap.debugger.SetAsync(false);
     if (core_file.empty()) {
-      if ((pid != LLDB_INVALID_PROCESS_ID) && (port != invalid_port)) {
+      if ((pid != LLDB_INVALID_PROCESS_ID) && (gdb_remote_port != invalid_port)) {
         // If both pid and port numbers are specified.
         error.SetErrorString("The user can't specify both pid and port");
-      } else if (port != invalid_port) {
+      } else if (gdb_remote_port != invalid_port) {
         // If port is specified and pid is not.
         lldb::SBListener listener = g_dap.debugger.GetListener();
 
         // If the user hasn't provided the hostname property, default localhost
         // being used.
         std::string connect_url =
-            llvm::formatv("connect://{0}:", hostname.data());
-        connect_url += std::to_string(port);
+            llvm::formatv("connect://{0}:", gdb_remote_hostname.data());
+        connect_url += std::to_string(gdb_remote_port);
         g_dap.target.ConnectRemote(listener, connect_url.c_str(), "gdb-remote",
                                    error);
       } else {
diff --git a/lldb/tools/lldb-dap/package.json b/lldb/tools/lldb-dap/package.json
index c9f05b7c572b4..62cf69b359728 100644
--- a/lldb/tools/lldb-dap/package.json
+++ b/lldb/tools/lldb-dap/package.json
@@ -348,14 +348,14 @@
                 "type": "string",
                 "description": "The time in seconds to wait for a program to stop when attaching using \"attachCommands\". Defaults to 30 seconds."
               },
-              "port": {
+              "gdb-remote-port": {
                 "type": [
                   "number",
                   "string"
                 ],
                 "description": "TCP/IP port to attach to. Specifying both pid and port is an error."
               },
-              "hostname": {
+              "gdb-remote-hostname": {
                 "type": "string",
                 "description": "The hostname to connect to a remote system. The default hostname being used localhost."
               },

>From ac84b5334435e976489037a2779785db84f48bf9 Mon Sep 17 00:00:00 2001
From: Santhosh Kumar Ellendula <sellendu at hu-sellendu-lv.qualcomm.com>
Date: Tue, 4 Jun 2024 11:03:38 -0700
Subject: [PATCH 14/15] [lldb-dap] Added "port" property to vscode "attach"
 command - resolved code format issues.

---
 .../attach/TestDAP_attachByPortNum.py         | 33 +++++++++++--------
 lldb/tools/lldb-dap/lldb-dap.cpp              | 12 ++++---
 2 files changed, 27 insertions(+), 18 deletions(-)

diff --git a/lldb/test/API/tools/lldb-dap/attach/TestDAP_attachByPortNum.py b/lldb/test/API/tools/lldb-dap/attach/TestDAP_attachByPortNum.py
index 5c247462350c6..e49c2eabeb50d 100644
--- a/lldb/test/API/tools/lldb-dap/attach/TestDAP_attachByPortNum.py
+++ b/lldb/test/API/tools/lldb-dap/attach/TestDAP_attachByPortNum.py
@@ -39,8 +39,10 @@ def read(self, size, timeout):
     def close(self):
         os.close(self._fd)
 
+
 class TestDAP_attachByPortNum(lldbdap_testcase.DAPTestCaseBase):
     default_timeout = 20
+
     def set_and_hit_breakpoint(self, continueToExit=True):
         source = "main.c"
         main_source_path = os.path.join(os.getcwd(), source)
@@ -58,7 +60,7 @@ def set_and_hit_breakpoint(self, continueToExit=True):
     def get_debug_server_command_line_args(self):
         args = []
         if lldbplatformutil.getPlatform() == "linux":
-            args = ["gdbserver"]    
+            args = ["gdbserver"]
         elif lldbplatformutil.getPlatform() == "macosx":
             args = ["--listen"]
         if lldb.remote_platform:
@@ -72,33 +74,34 @@ def get_debug_server_pipe(self):
         self.addTearDownHook(lambda: pipe.close())
         pipe.finish_connection(self.default_timeout)
         return pipe
-        
+
     @skipIfWindows
     @skipIfNetBSD
     def test_by_port(self):
         """
         Tests attaching to a process by port.
         """
-        
         self.build_and_create_debug_adaptor()
         program = self.getBuildArtifact("a.out")
-        
+
         debug_server_tool = self.getBuiltinDebugServerTool()
 
         pipe = self.get_debug_server_pipe()
         args = self.get_debug_server_command_line_args()
         args += [program]
         args += ["--named-pipe", pipe.name]
-        
+
         self.process = self.spawnSubprocess(
             debug_server_tool, args, install_remote=False
         )
-        
+
         # Read the port number from the debug server pipe.
-        port = pipe.read(10, 30)
+        port = pipe.read(10, self.default_timeout)
         # Trim null byte, convert to int
         port = int(port[:-1])
-        self.assertIsNotNone(port, " Failed to read the port number from debug server pipe")
+        self.assertIsNotNone(
+            port, " Failed to read the port number from debug server pipe"
+        )
 
         self.attach(program=program, gdbRemotePort=port, sourceInitFile=True)
         self.set_and_hit_breakpoint(continueToExit=True)
@@ -118,19 +121,21 @@ def test_by_port_and_pid(self):
         args = self.get_debug_server_command_line_args()
         args += [program]
         args += ["--named-pipe", pipe.name]
-        
+
         self.process = self.spawnSubprocess(
             debug_server_tool, args, install_remote=False
         )
-        
+
         # Read the port number from the debug server pipe.
-        port = pipe.read(10, 30)
+        port = pipe.read(10, self.default_timeout)
         # Trim null byte, convert to int
         port = int(port[:-1])
-        self.assertIsNotNone(port, " Failed to read the port number from debug server pipe")
-        
+        self.assertIsNotNone(
+            port, " Failed to read the port number from debug server pipe"
+        )
+
         pid = self.process.pid
-        
+
         response = self.attach(
             program=program,
             pid=pid,
diff --git a/lldb/tools/lldb-dap/lldb-dap.cpp b/lldb/tools/lldb-dap/lldb-dap.cpp
index b852a470f6d4b..ab2b9ced1f33b 100644
--- a/lldb/tools/lldb-dap/lldb-dap.cpp
+++ b/lldb/tools/lldb-dap/lldb-dap.cpp
@@ -676,8 +676,10 @@ void request_attach(const llvm::json::Object &request) {
   auto arguments = request.getObject("arguments");
   const lldb::pid_t pid =
       GetUnsigned(arguments, "pid", LLDB_INVALID_PROCESS_ID);
-  const auto gdb_remote_port = GetUnsigned(arguments, "gdb-remote-port", invalid_port);
-  llvm::StringRef gdb_remote_hostname = GetString(arguments, "gdb-remote-hostname", "localhost");
+  const auto gdb_remote_port =
+      GetUnsigned(arguments, "gdb-remote-port", invalid_port);
+  llvm::StringRef gdb_remote_hostname =
+      GetString(arguments, "gdb-remote-hostname", "localhost");
   if (pid != LLDB_INVALID_PROCESS_ID)
     attach_info.SetProcessID(pid);
   const auto wait_for = GetBoolean(arguments, "waitFor", false);
@@ -739,7 +741,8 @@ void request_attach(const llvm::json::Object &request) {
     return;
   }
 
-  if ((pid == LLDB_INVALID_PROCESS_ID || gdb_remote_port == invalid_port) && wait_for) {
+  if ((pid == LLDB_INVALID_PROCESS_ID || gdb_remote_port == invalid_port) &&
+      wait_for) {
     char attach_msg[256];
     auto attach_msg_len = snprintf(attach_msg, sizeof(attach_msg),
                                    "Waiting to attach to \"%s\"...",
@@ -753,7 +756,8 @@ void request_attach(const llvm::json::Object &request) {
     // the launch call and the launch will happen synchronously
     g_dap.debugger.SetAsync(false);
     if (core_file.empty()) {
-      if ((pid != LLDB_INVALID_PROCESS_ID) && (gdb_remote_port != invalid_port)) {
+      if ((pid != LLDB_INVALID_PROCESS_ID) &&
+          (gdb_remote_port != invalid_port)) {
         // If both pid and port numbers are specified.
         error.SetErrorString("The user can't specify both pid and port");
       } else if (gdb_remote_port != invalid_port) {

>From 08f40aaa5975fd2cab6e7fd8c69b66c0ab97dd59 Mon Sep 17 00:00:00 2001
From: Santhosh Kumar Ellendula <sellendu at hu-sellendu-lv.qualcomm.com>
Date: Mon, 10 Jun 2024 05:27:50 -0700
Subject: [PATCH 15/15]  [lldb-dap] Added "port" property to vscode "attach"
 command - fixed review comments.

---
 .../API/tools/lldb-dap/attach/TestDAP_attachByPortNum.py   | 7 -------
 lldb/tools/lldb-dap/lldb-dap.cpp                           | 4 ++--
 2 files changed, 2 insertions(+), 9 deletions(-)

diff --git a/lldb/test/API/tools/lldb-dap/attach/TestDAP_attachByPortNum.py b/lldb/test/API/tools/lldb-dap/attach/TestDAP_attachByPortNum.py
index e49c2eabeb50d..12c41be3bc6e0 100644
--- a/lldb/test/API/tools/lldb-dap/attach/TestDAP_attachByPortNum.py
+++ b/lldb/test/API/tools/lldb-dap/attach/TestDAP_attachByPortNum.py
@@ -159,12 +159,6 @@ def test_by_invalid_port(self):
         program = self.getBuildArtifact("a.out")
 
         port = 0
-        args = [program]
-        debug_server_tool = self.getBuiltinDebugServerTool()
-        self.process = self.spawnSubprocess(
-            debug_server_tool, args, install_remote=False
-        )
-
         response = self.attach(
             program=program, gdbRemotePort=port, sourceInitFile=True, expectFailure=True
         )
@@ -173,7 +167,6 @@ def test_by_invalid_port(self):
                 response["success"],
                 "The user can't attach with invalid port (%s)" % port,
             )
-        self.process.terminate()
 
     @skipIfWindows
     @skipIfNetBSD
diff --git a/lldb/tools/lldb-dap/lldb-dap.cpp b/lldb/tools/lldb-dap/lldb-dap.cpp
index ab2b9ced1f33b..408356350dc21 100644
--- a/lldb/tools/lldb-dap/lldb-dap.cpp
+++ b/lldb/tools/lldb-dap/lldb-dap.cpp
@@ -678,7 +678,7 @@ void request_attach(const llvm::json::Object &request) {
       GetUnsigned(arguments, "pid", LLDB_INVALID_PROCESS_ID);
   const auto gdb_remote_port =
       GetUnsigned(arguments, "gdb-remote-port", invalid_port);
-  llvm::StringRef gdb_remote_hostname =
+  const auto gdb_remote_hostname =
       GetString(arguments, "gdb-remote-hostname", "localhost");
   if (pid != LLDB_INVALID_PROCESS_ID)
     attach_info.SetProcessID(pid);
@@ -767,7 +767,7 @@ void request_attach(const llvm::json::Object &request) {
         // If the user hasn't provided the hostname property, default localhost
         // being used.
         std::string connect_url =
-            llvm::formatv("connect://{0}:", gdb_remote_hostname.data());
+            llvm::formatv("connect://{0}:", gdb_remote_hostname);
         connect_url += std::to_string(gdb_remote_port);
         g_dap.target.ConnectRemote(listener, connect_url.c_str(), "gdb-remote",
                                    error);



More information about the lldb-commits mailing list