[Lldb-commits] [lldb] [lldb-dap] Test gardening, enabling tests and improving doc comments. (PR #140777)
John Harrison via lldb-commits
lldb-commits at lists.llvm.org
Thu May 22 16:05:50 PDT 2025
https://github.com/ashgti updated https://github.com/llvm/llvm-project/pull/140777
>From e50ea7d279adcb181f68a7156b5fc12d1047f402 Mon Sep 17 00:00:00 2001
From: John Harrison <harjohn at google.com>
Date: Tue, 20 May 2025 11:09:35 -0700
Subject: [PATCH 1/3] [lldb-dap] Test gardening, enabling tests and improving
doc comments.
A bit of test gardenining. Enabling tests that were marked as skipped as part of https://github.com/llvm/llvm-project/issues/137660.
Fixed up some comments and doc comments and fixed some test helpers.
---
.../Python/lldbsuite/test/decorators.py | 26 ++++++++
.../attach/TestDAP_attachByPortNum.py | 61 ++++++++-----------
.../breakpoint/TestDAP_setBreakpoints.py | 1 -
.../TestDAP_setExceptionBreakpoints.py | 1 -
.../TestDAP_setFunctionBreakpoints.py | 1 -
.../tools/lldb-dap/cancel/TestDAP_cancel.py | 2 -
.../tools/lldb-dap/console/TestDAP_console.py | 25 ++++----
.../lldb-dap/coreFile/TestDAP_coreFile.py | 2 -
.../TestDAP_setDataBreakpoints.py | 2 +-
.../disassemble/TestDAP_disassemble.py | 2 -
.../lldb-dap/disconnect/TestDAP_disconnect.py | 1 -
.../lldb-dap/evaluate/TestDAP_evaluate.py | 3 -
.../TestDAP_instruction_breakpoint.py | 37 +++++------
.../tools/lldb-dap/launch/TestDAP_launch.py | 19 +++---
.../lldb-dap/locations/TestDAP_locations.py | 5 +-
.../tools/lldb-dap/memory/TestDAP_memory.py | 2 -
.../module-event/TestDAP_module_event.py | 7 ++-
.../tools/lldb-dap/module/TestDAP_module.py | 4 +-
.../lldb-dap/optimized/TestDAP_optimized.py | 4 +-
.../tools/lldb-dap/output/TestDAP_output.py | 2 +-
.../lldb-dap/progress/TestDAP_Progress.py | 7 +--
.../repl-mode/TestDAP_repl_mode_detection.py | 2 -
.../tools/lldb-dap/restart/TestDAP_restart.py | 2 +-
.../restart/TestDAP_restart_runInTerminal.py | 22 +------
.../runInTerminal/TestDAP_runInTerminal.py | 47 ++------------
.../tools/lldb-dap/source/TestDAP_source.py | 3 -
.../subtleFrames/TestDAP_subtleFrames.py | 10 ++-
.../TestDAP_stackTraceDisassemblyDisplay.py | 2 +-
.../TestDAP_stackTraceMissingFunctionName.py | 2 +-
.../TestDAP_stackTraceMissingModule.py | 2 +-
.../API/tools/lldb-dap/step/TestDAP_step.py | 4 +-
.../stepInTargets/TestDAP_stepInTargets.py | 9 +--
.../TestDAP_terminatedEvent.py | 3 -
.../tools/lldb-dap/threads/TestDAP_threads.py | 3 +-
.../lldb-dap/variables/TestDAP_variables.py | 5 +-
.../children/TestDAP_variables_children.py | 6 +-
36 files changed, 124 insertions(+), 212 deletions(-)
diff --git a/lldb/packages/Python/lldbsuite/test/decorators.py b/lldb/packages/Python/lldbsuite/test/decorators.py
index 895f2a82547a9..5e14dfeda48a8 100644
--- a/lldb/packages/Python/lldbsuite/test/decorators.py
+++ b/lldb/packages/Python/lldbsuite/test/decorators.py
@@ -1,5 +1,6 @@
# System modules
from functools import wraps
+from typing import Optional
from packaging import version
import ctypes
import locale
@@ -1102,3 +1103,28 @@ def is_feature_enabled():
return "%s is not supported on this system." % feature
return skipTestIfFn(is_feature_enabled)
+
+
+def skipIfBinaryToLarge(path: Optional[str], maxSize: int):
+ """Skip the test if a binary is to large.
+
+ We skip this test for debug builds because it takes too long
+ parsing lldb's own debug info. Release builds are fine.
+ Checking the size of the lldb-dap binary seems to be a decent
+ proxy for a quick detection. It should be far less than 1 MB in
+ Release builds.
+ """
+
+ def check_binary_size():
+ if not path or not os.path.exists(path):
+ return "invalid path"
+
+ try:
+ size = os.path.getsize(path)
+ if size <= maxSize:
+ return None
+ return f"binary {path} (size = {size} is to larger than {maxSize}"
+ except:
+ return f"failed to read size of {path}"
+
+ return skipTestIfFn(check_binary_size)
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 7c2b540195d15..edb87a9314d78 100644
--- a/lldb/test/API/tools/lldb-dap/attach/TestDAP_attachByPortNum.py
+++ b/lldb/test/API/tools/lldb-dap/attach/TestDAP_attachByPortNum.py
@@ -2,26 +2,16 @@
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
from lldbsuite.test import lldbplatformutil
from lldbgdbserverutils import Pipe
import lldbdap_testcase
-import os
-import shutil
-import subprocess
-import tempfile
-import threading
-import sys
-import socket
+import lldb
- at skip("https://github.com/llvm/llvm-project/issues/138803")
+ at skip(bugnumber="https://github.com/llvm/llvm-project/issues/138803")
class TestDAP_attachByPortNum(lldbdap_testcase.DAPTestCaseBase):
- default_timeout = 20
-
def set_and_hit_breakpoint(self, continueToExit=True):
self.dap_server.wait_for_stopped()
@@ -50,7 +40,7 @@ def get_debug_server_command_line_args(self):
def get_debug_server_pipe(self):
pipe = Pipe(self.getBuildDir())
self.addTearDownHook(lambda: pipe.close())
- pipe.finish_connection(self.default_timeout)
+ pipe.finish_connection(self.DEFAULT_TIMEOUT)
return pipe
@skipIfWindows
@@ -73,28 +63,33 @@ def test_by_port(self):
)
# Read the port number from the debug server pipe.
- port = pipe.read(10, self.default_timeout)
+ 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.attach(program=program, gdbRemotePort=port, sourceInitFile=True)
+ self.attach(
+ program=program,
+ gdbRemotePort=port,
+ sourceInitFile=True,
+ stopOnEntry=True,
+ )
self.set_and_hit_breakpoint(continueToExit=True)
- self.process.terminate()
@skipIfWindows
@skipIfNetBSD
- def test_by_port_and_pid(self):
+ def test_fails_if_both_port_and_pid_are_set(self):
"""
Tests attaching to a process by process ID and port number.
"""
program = self.build_and_create_debug_adapter_for_attach()
- # It is not necessary to launch "lldb-server" to obtain the actual port and pid for attaching.
- # However, when providing the port number and pid directly, "lldb-dap" throws an error message, which is expected.
- # So, used random pid and port numbers here.
+ # It is not necessary to launch "lldb-server" to obtain the actual port
+ # and pid for attaching. However, when providing the port number and pid
+ # directly, "lldb-dap" throws an error message, which is expected. So,
+ # used random pid and port numbers here.
pid = 1354
port = 1234
@@ -106,10 +101,9 @@ def test_by_port_and_pid(self):
sourceInitFile=True,
expectFailure=True,
)
- if not (response and response["success"]):
- self.assertFalse(
- response["success"], "The user can't specify both pid and port"
- )
+ self.assertFalse(
+ response["success"], "The user can't specify both pid and port"
+ )
@skipIfWindows
@skipIfNetBSD
@@ -123,11 +117,10 @@ def test_by_invalid_port(self):
response = self.attach(
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.assertFalse(
+ response["success"],
+ "The user can't attach with invalid port (%s)" % port,
+ )
@skipIfWindows
@skipIfNetBSD
@@ -147,9 +140,7 @@ def test_by_illegal_port(self):
response = self.attach(
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.terminate()
+ self.assertFalse(
+ response["success"],
+ "The user can't attach with illegal port (%s)" % port,
+ )
diff --git a/lldb/test/API/tools/lldb-dap/breakpoint/TestDAP_setBreakpoints.py b/lldb/test/API/tools/lldb-dap/breakpoint/TestDAP_setBreakpoints.py
index aae1251b17c93..26df2573555df 100644
--- a/lldb/test/API/tools/lldb-dap/breakpoint/TestDAP_setBreakpoints.py
+++ b/lldb/test/API/tools/lldb-dap/breakpoint/TestDAP_setBreakpoints.py
@@ -12,7 +12,6 @@
import os
- at skip("Temporarily disable the breakpoint tests")
class TestDAP_setBreakpoints(lldbdap_testcase.DAPTestCaseBase):
def setUp(self):
lldbdap_testcase.DAPTestCaseBase.setUp(self)
diff --git a/lldb/test/API/tools/lldb-dap/breakpoint/TestDAP_setExceptionBreakpoints.py b/lldb/test/API/tools/lldb-dap/breakpoint/TestDAP_setExceptionBreakpoints.py
index 4dc8c5b3c7ded..92ac66cd44c5d 100644
--- a/lldb/test/API/tools/lldb-dap/breakpoint/TestDAP_setExceptionBreakpoints.py
+++ b/lldb/test/API/tools/lldb-dap/breakpoint/TestDAP_setExceptionBreakpoints.py
@@ -10,7 +10,6 @@
import lldbdap_testcase
- at skip("Temporarily disable the breakpoint tests")
class TestDAP_setExceptionBreakpoints(lldbdap_testcase.DAPTestCaseBase):
@skipIfWindows
def test_functionality(self):
diff --git a/lldb/test/API/tools/lldb-dap/breakpoint/TestDAP_setFunctionBreakpoints.py b/lldb/test/API/tools/lldb-dap/breakpoint/TestDAP_setFunctionBreakpoints.py
index baaca4d974d5d..946595f639edc 100644
--- a/lldb/test/API/tools/lldb-dap/breakpoint/TestDAP_setFunctionBreakpoints.py
+++ b/lldb/test/API/tools/lldb-dap/breakpoint/TestDAP_setFunctionBreakpoints.py
@@ -10,7 +10,6 @@
import lldbdap_testcase
- at skip("Temporarily disable the breakpoint tests")
class TestDAP_setFunctionBreakpoints(lldbdap_testcase.DAPTestCaseBase):
@skipIfWindows
def test_set_and_clear(self):
diff --git a/lldb/test/API/tools/lldb-dap/cancel/TestDAP_cancel.py b/lldb/test/API/tools/lldb-dap/cancel/TestDAP_cancel.py
index 824ed8fe3bb97..a239664f9eef7 100644
--- a/lldb/test/API/tools/lldb-dap/cancel/TestDAP_cancel.py
+++ b/lldb/test/API/tools/lldb-dap/cancel/TestDAP_cancel.py
@@ -2,8 +2,6 @@
Test lldb-dap cancel request
"""
-import time
-
from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
import lldbdap_testcase
diff --git a/lldb/test/API/tools/lldb-dap/console/TestDAP_console.py b/lldb/test/API/tools/lldb-dap/console/TestDAP_console.py
index 7b4d1adbb2071..9f02d2f951d27 100644
--- a/lldb/test/API/tools/lldb-dap/console/TestDAP_console.py
+++ b/lldb/test/API/tools/lldb-dap/console/TestDAP_console.py
@@ -1,26 +1,23 @@
"""
-Test lldb-dap setBreakpoints request
+Test lldb-dap console output
"""
-import dap_server
import lldbdap_testcase
-from lldbsuite.test import lldbutil
from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
-def get_subprocess(root_process, process_name):
- queue = [root_process]
- while queue:
- process = queue.pop()
- if process.name() == process_name:
- return process
- queue.extend(process.children())
-
- self.assertTrue(False, "No subprocess with name %s found" % process_name)
+class TestDAP_console(lldbdap_testcase.DAPTestCaseBase):
+ def get_subprocess(self, root_process, process_name):
+ queue = [root_process]
+ while queue:
+ process = queue.pop()
+ if process.name() == process_name:
+ return process
+ queue.extend(process.children())
+ self.assertTrue(False, "No subprocess with name %s found" % process_name)
-class TestDAP_console(lldbdap_testcase.DAPTestCaseBase):
def check_lldb_command(
self, lldb_command, contains_string, assert_msg, command_escape_prefix="`"
):
@@ -134,7 +131,7 @@ def test_exit_status_message_sigterm(self):
file=sys.stderr,
)
return
- process = get_subprocess(psutil.Process(os.getpid()), process_name)
+ process = self.get_subprocess(psutil.Process(os.getpid()), process_name)
process.terminate()
process.wait()
diff --git a/lldb/test/API/tools/lldb-dap/coreFile/TestDAP_coreFile.py b/lldb/test/API/tools/lldb-dap/coreFile/TestDAP_coreFile.py
index db43dbaf515cf..72d7171b7c5fc 100644
--- a/lldb/test/API/tools/lldb-dap/coreFile/TestDAP_coreFile.py
+++ b/lldb/test/API/tools/lldb-dap/coreFile/TestDAP_coreFile.py
@@ -2,10 +2,8 @@
Test lldb-dap coreFile attaching
"""
-import dap_server
from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
-from lldbsuite.test import lldbutil
import lldbdap_testcase
import os
diff --git a/lldb/test/API/tools/lldb-dap/databreakpoint/TestDAP_setDataBreakpoints.py b/lldb/test/API/tools/lldb-dap/databreakpoint/TestDAP_setDataBreakpoints.py
index a542a318050dd..e3ead1095cba0 100644
--- a/lldb/test/API/tools/lldb-dap/databreakpoint/TestDAP_setDataBreakpoints.py
+++ b/lldb/test/API/tools/lldb-dap/databreakpoint/TestDAP_setDataBreakpoints.py
@@ -9,7 +9,7 @@
class TestDAP_setDataBreakpoints(lldbdap_testcase.DAPTestCaseBase):
def setUp(self):
- lldbdap_testcase.DAPTestCaseBase.setUp(self)
+ super().setUp()
self.accessTypes = ["read", "write", "readWrite"]
@skipIfWindows
diff --git a/lldb/test/API/tools/lldb-dap/disassemble/TestDAP_disassemble.py b/lldb/test/API/tools/lldb-dap/disassemble/TestDAP_disassemble.py
index 9e8ef5b289f2e..a4759084fdb9d 100644
--- a/lldb/test/API/tools/lldb-dap/disassemble/TestDAP_disassemble.py
+++ b/lldb/test/API/tools/lldb-dap/disassemble/TestDAP_disassemble.py
@@ -3,10 +3,8 @@
"""
-import dap_server
from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
-from lldbsuite.test import lldbutil
import lldbdap_testcase
import os
diff --git a/lldb/test/API/tools/lldb-dap/disconnect/TestDAP_disconnect.py b/lldb/test/API/tools/lldb-dap/disconnect/TestDAP_disconnect.py
index 09e3f62f0eead..3c93ec193716f 100644
--- a/lldb/test/API/tools/lldb-dap/disconnect/TestDAP_disconnect.py
+++ b/lldb/test/API/tools/lldb-dap/disconnect/TestDAP_disconnect.py
@@ -3,7 +3,6 @@
"""
-import dap_server
from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
from lldbsuite.test import lldbutil
diff --git a/lldb/test/API/tools/lldb-dap/evaluate/TestDAP_evaluate.py b/lldb/test/API/tools/lldb-dap/evaluate/TestDAP_evaluate.py
index 2166e88151986..923f8f511f1c5 100644
--- a/lldb/test/API/tools/lldb-dap/evaluate/TestDAP_evaluate.py
+++ b/lldb/test/API/tools/lldb-dap/evaluate/TestDAP_evaluate.py
@@ -3,10 +3,7 @@
"""
import re
-
import lldbdap_testcase
-import dap_server
-from lldbsuite.test import lldbutil
from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
diff --git a/lldb/test/API/tools/lldb-dap/instruction-breakpoint/TestDAP_instruction_breakpoint.py b/lldb/test/API/tools/lldb-dap/instruction-breakpoint/TestDAP_instruction_breakpoint.py
index 53b7df9e54af2..3793b1e136ac6 100644
--- a/lldb/test/API/tools/lldb-dap/instruction-breakpoint/TestDAP_instruction_breakpoint.py
+++ b/lldb/test/API/tools/lldb-dap/instruction-breakpoint/TestDAP_instruction_breakpoint.py
@@ -1,32 +1,25 @@
-import dap_server
-import shutil
+"""
+Test lldb-dap setInstructionBreakpoints request
+"""
+
+import os
from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
-from lldbsuite.test import lldbutil
import lldbdap_testcase
-import os
-import lldb
class TestDAP_InstructionBreakpointTestCase(lldbdap_testcase.DAPTestCaseBase):
NO_DEBUG_INFO_TESTCASE = True
def setUp(self):
- lldbdap_testcase.DAPTestCaseBase.setUp(self)
+ super().setUp()
self.main_basename = "main-copy.cpp"
self.main_path = os.path.realpath(self.getBuildArtifact(self.main_basename))
@skipIfWindows
def test_instruction_breakpoint(self):
- self.build()
- self.instruction_breakpoint_test()
-
- def instruction_breakpoint_test(self):
"""Sample test to ensure SBFrame::Disassemble produces SOME output"""
- # Create a target by the debugger.
- target = self.createTestTarget()
-
main_line = line_number("main.cpp", "breakpoint 1")
program = self.getBuildArtifact("a.out")
@@ -49,15 +42,15 @@ def instruction_breakpoint_test(self):
)
other_breakpoint_id = breakpoint["id"]
- # Continue and then verifiy the breakpoint
+ # Continue and then verify the breakpoint
self.dap_server.request_continue()
self.verify_breakpoint_hit([other_breakpoint_id])
# now we check the stack trace making sure that we got mapped source paths
frames = self.dap_server.request_stackTrace()["body"]["stackFrames"]
- intstructionPointerReference = []
- setIntstructionBreakpoints = []
- intstructionPointerReference.append(frames[0]["instructionPointerReference"])
+ instructionPointerReference = []
+ setInstructionBreakpoints = []
+ instructionPointerReference.append(frames[0]["instructionPointerReference"])
self.assertEqual(
frames[0]["source"]["name"], self.main_basename, "incorrect source name"
)
@@ -69,21 +62,21 @@ def instruction_breakpoint_test(self):
instruction = self.disassemble(frameIndex=0)
self.assertEqual(
instruction["address"],
- intstructionPointerReference[0],
- "current breakpoint reference is not in the disaasembly view",
+ instructionPointerReference[0],
+ "current breakpoint reference is not in the disassembly view",
)
# Get next instruction address to set instruction breakpoint
disassembled_instruction_list = self.dap_server.disassembled_instructions
instruction_addr_list = list(disassembled_instruction_list.keys())
- index = instruction_addr_list.index(intstructionPointerReference[0])
+ index = instruction_addr_list.index(instructionPointerReference[0])
if len(instruction_addr_list) >= (index + 1):
next_inst_addr = instruction_addr_list[index + 1]
if len(next_inst_addr) > 2:
- setIntstructionBreakpoints.append(next_inst_addr)
+ setInstructionBreakpoints.append(next_inst_addr)
instruction_breakpoint_response = (
self.dap_server.request_setInstructionBreakpoints(
- setIntstructionBreakpoints
+ setInstructionBreakpoints
)
)
inst_breakpoints = instruction_breakpoint_response["body"][
diff --git a/lldb/test/API/tools/lldb-dap/launch/TestDAP_launch.py b/lldb/test/API/tools/lldb-dap/launch/TestDAP_launch.py
index 8805ce50e6a21..eb3caa9d85583 100644
--- a/lldb/test/API/tools/lldb-dap/launch/TestDAP_launch.py
+++ b/lldb/test/API/tools/lldb-dap/launch/TestDAP_launch.py
@@ -1,15 +1,12 @@
"""
-Test lldb-dap setBreakpoints request
+Test lldb-dap launch request
"""
-import dap_server
+import os
+import re
from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
-from lldbsuite.test import lldbutil
import lldbdap_testcase
-import time
-import os
-import re
# Many tests are skipped on Windows because get_stdout() returns None there.
# Despite the test program printing correctly. See
@@ -339,7 +336,7 @@ def test_commands(self):
launch.
"initCommands" are a list of LLDB commands that get executed
- before the targt is created.
+ before the target is created.
"preRunCommands" are a list of LLDB commands that get executed
after the target has been created and before the launch.
"stopCommands" are a list of LLDB commands that get executed each
@@ -425,7 +422,7 @@ def test_extra_launch_commands(self):
first_line = line_number(source, "// breakpoint 1")
second_line = line_number(source, "// breakpoint 2")
# Set target binary and 2 breakpoints
- # then we can varify the "launchCommands" get run
+ # then we can verify the "launchCommands" get run
# also we can verify that "stopCommands" get run as the
# breakpoints get hit
launchCommands = [
@@ -508,12 +505,12 @@ def test_failing_launch_commands(self):
# Get output from the console. This should contain both the
# "initCommands" and the "preRunCommands".
output = self.get_console()
- # Verify all "initCommands" were found in console output
+ # Verify all "initCommands" are found in console output
self.verify_commands("initCommands", output, initCommands)
- # Verify all "preRunCommands" were found in console output
+ # Verify all "preRunCommands" are found in console output
self.verify_commands("preRunCommands", output, preRunCommands)
- # Verify all "launchCommands" were founc in console output
+ # Verify all "launchCommands" are found in console output
# The launch should fail due to the invalid command.
self.verify_commands("launchCommands", output, launchCommands)
self.assertRegex(output, re.escape(bad_path) + r".*does not exist")
diff --git a/lldb/test/API/tools/lldb-dap/locations/TestDAP_locations.py b/lldb/test/API/tools/lldb-dap/locations/TestDAP_locations.py
index 45f836a2fa3c3..6b348866e44fb 100644
--- a/lldb/test/API/tools/lldb-dap/locations/TestDAP_locations.py
+++ b/lldb/test/API/tools/lldb-dap/locations/TestDAP_locations.py
@@ -1,12 +1,9 @@
"""
-Test lldb-dap locations request
+Test lldb-dap locations request.
"""
-
-import dap_server
from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
-from lldbsuite.test import lldbutil
import lldbdap_testcase
import os
diff --git a/lldb/test/API/tools/lldb-dap/memory/TestDAP_memory.py b/lldb/test/API/tools/lldb-dap/memory/TestDAP_memory.py
index 74062f3ab2164..159dd3bc1fa3a 100644
--- a/lldb/test/API/tools/lldb-dap/memory/TestDAP_memory.py
+++ b/lldb/test/API/tools/lldb-dap/memory/TestDAP_memory.py
@@ -3,10 +3,8 @@
"""
from base64 import b64decode
-import dap_server
from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
-from lldbsuite.test import lldbutil
import lldbdap_testcase
import os
diff --git a/lldb/test/API/tools/lldb-dap/module-event/TestDAP_module_event.py b/lldb/test/API/tools/lldb-dap/module-event/TestDAP_module_event.py
index 1ef2f2a8235a4..023b69f8688dd 100644
--- a/lldb/test/API/tools/lldb-dap/module-event/TestDAP_module_event.py
+++ b/lldb/test/API/tools/lldb-dap/module-event/TestDAP_module_event.py
@@ -1,9 +1,10 @@
-import dap_server
+"""
+Test lldb-dap module events.
+"""
+
from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
-from lldbsuite.test import lldbutil
import lldbdap_testcase
-import re
class TestDAP_module_event(lldbdap_testcase.DAPTestCaseBase):
diff --git a/lldb/test/API/tools/lldb-dap/module/TestDAP_module.py b/lldb/test/API/tools/lldb-dap/module/TestDAP_module.py
index 3fc0f752ee39e..134c9cb1aee18 100644
--- a/lldb/test/API/tools/lldb-dap/module/TestDAP_module.py
+++ b/lldb/test/API/tools/lldb-dap/module/TestDAP_module.py
@@ -1,11 +1,9 @@
"""
-Test lldb-dap setBreakpoints request
+Test lldb-dap modules request.
"""
-import dap_server
from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
-from lldbsuite.test import lldbutil
import lldbdap_testcase
import re
diff --git a/lldb/test/API/tools/lldb-dap/optimized/TestDAP_optimized.py b/lldb/test/API/tools/lldb-dap/optimized/TestDAP_optimized.py
index ae144ebdca46b..d35793c229283 100644
--- a/lldb/test/API/tools/lldb-dap/optimized/TestDAP_optimized.py
+++ b/lldb/test/API/tools/lldb-dap/optimized/TestDAP_optimized.py
@@ -1,10 +1,8 @@
"""
-Test lldb-dap variables/stackTrace request for optimized code
+Test lldb-dap variables/stackTrace request for optimized code.
"""
-import dap_server
import lldbdap_testcase
-from lldbsuite.test import lldbutil
from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
diff --git a/lldb/test/API/tools/lldb-dap/output/TestDAP_output.py b/lldb/test/API/tools/lldb-dap/output/TestDAP_output.py
index 0425b55a5e552..18c7b10be1b82 100644
--- a/lldb/test/API/tools/lldb-dap/output/TestDAP_output.py
+++ b/lldb/test/API/tools/lldb-dap/output/TestDAP_output.py
@@ -1,5 +1,5 @@
"""
-Test lldb-dap output events
+Test lldb-dap output events.
"""
from lldbsuite.test.decorators import *
diff --git a/lldb/test/API/tools/lldb-dap/progress/TestDAP_Progress.py b/lldb/test/API/tools/lldb-dap/progress/TestDAP_Progress.py
index b47d52968f8a1..58a33aaa2d582 100755
--- a/lldb/test/API/tools/lldb-dap/progress/TestDAP_Progress.py
+++ b/lldb/test/API/tools/lldb-dap/progress/TestDAP_Progress.py
@@ -1,14 +1,11 @@
"""
-Test lldb-dap output events
+Test lldb-dap progress events.
"""
from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
-import json
import os
-import time
import re
-
import lldbdap_testcase
@@ -52,7 +49,7 @@ def verify_progress_events(
self.dap_server.progress_events.clear()
@skipIfWindows
- def test(self):
+ def test_progress(self):
program = self.getBuildArtifact("a.out")
self.build_and_launch(program, stopOnEntry=True)
progress_emitter = os.path.join(os.getcwd(), "Progress_emitter.py")
diff --git a/lldb/test/API/tools/lldb-dap/repl-mode/TestDAP_repl_mode_detection.py b/lldb/test/API/tools/lldb-dap/repl-mode/TestDAP_repl_mode_detection.py
index c6f59949d668e..07029c2425cff 100644
--- a/lldb/test/API/tools/lldb-dap/repl-mode/TestDAP_repl_mode_detection.py
+++ b/lldb/test/API/tools/lldb-dap/repl-mode/TestDAP_repl_mode_detection.py
@@ -3,8 +3,6 @@
"""
import lldbdap_testcase
-import dap_server
-from lldbsuite.test import lldbutil
from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
diff --git a/lldb/test/API/tools/lldb-dap/restart/TestDAP_restart.py b/lldb/test/API/tools/lldb-dap/restart/TestDAP_restart.py
index 83faf276852f8..70aa84e8fc210 100644
--- a/lldb/test/API/tools/lldb-dap/restart/TestDAP_restart.py
+++ b/lldb/test/API/tools/lldb-dap/restart/TestDAP_restart.py
@@ -1,5 +1,5 @@
"""
-Test lldb-dap RestartRequest.
+Test lldb-dap restart request.
"""
from lldbsuite.test.decorators import *
diff --git a/lldb/test/API/tools/lldb-dap/restart/TestDAP_restart_runInTerminal.py b/lldb/test/API/tools/lldb-dap/restart/TestDAP_restart_runInTerminal.py
index eed769a5a0cc6..e1338dddea5da 100644
--- a/lldb/test/API/tools/lldb-dap/restart/TestDAP_restart_runInTerminal.py
+++ b/lldb/test/API/tools/lldb-dap/restart/TestDAP_restart_runInTerminal.py
@@ -1,5 +1,5 @@
"""
-Test lldb-dap RestartRequest.
+Test lldb-dap restart request.
"""
import os
@@ -8,18 +8,8 @@
import lldbdap_testcase
+ at skipIfBinaryToLarge(os.getenv("LLDBDAP_EXEC"), 1_000_000)
class TestDAP_restart_runInTerminal(lldbdap_testcase.DAPTestCaseBase):
- def isTestSupported(self):
- try:
- # We skip this test for debug builds because it takes too long
- # parsing lldb's own debug info. Release builds are fine.
- # Checking the size of the lldb-dap binary seems to be a decent
- # proxy for a quick detection. It should be far less than 1 MB in
- # Release builds.
- return os.path.getsize(os.environ["LLDBDAP_EXEC"]) < 1000000
- except:
- return False
-
@skipIfWindows
@skipIf(oslist=["linux"], archs=["arm"]) # Always times out on buildbot
def test_basic_functionality(self):
@@ -27,8 +17,6 @@ def test_basic_functionality(self):
Test basic restarting functionality when the process is running in
a terminal.
"""
- if not self.isTestSupported():
- return
line_A = line_number("main.c", "// breakpoint A")
line_B = line_number("main.c", "// breakpoint B")
@@ -61,16 +49,10 @@ def test_basic_functionality(self):
)
@skipIfWindows
- @skipIf(oslist=["linux"], archs=["arm"]) # Always times out on buildbot
def test_stopOnEntry(self):
"""
Check that stopOnEntry works correctly when using runInTerminal.
"""
- if not self.isTestSupported():
- return
- line_A = line_number("main.c", "// breakpoint A")
- line_B = line_number("main.c", "// breakpoint B")
-
program = self.getBuildArtifact("a.out")
self.build_and_launch(program, runInTerminal=True, stopOnEntry=True)
[bp_main] = self.set_function_breakpoints(["main"])
diff --git a/lldb/test/API/tools/lldb-dap/runInTerminal/TestDAP_runInTerminal.py b/lldb/test/API/tools/lldb-dap/runInTerminal/TestDAP_runInTerminal.py
index 9aab7ca3293db..ec03b86832069 100644
--- a/lldb/test/API/tools/lldb-dap/runInTerminal/TestDAP_runInTerminal.py
+++ b/lldb/test/API/tools/lldb-dap/runInTerminal/TestDAP_runInTerminal.py
@@ -1,21 +1,16 @@
"""
-Test lldb-dap runInTerminal reverse request
+Test lldb-dap runInTerminal reverse request.
"""
-
-import dap_server
from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
-from lldbsuite.test import lldbutil
import lldbdap_testcase
-import time
import os
import subprocess
-import shutil
import json
-from threading import Thread
+ at skipIfBinaryToLarge(os.getenv("LLDBDAP_EXEC"), 1_000_000)
class TestDAP_runInTerminal(lldbdap_testcase.DAPTestCaseBase):
def readPidMessage(self, fifo_file):
with open(fifo_file, "r") as file:
@@ -29,28 +24,12 @@ def readErrorMessage(self, fifo_file):
with open(fifo_file, "r") as file:
return file.readline()
- def isTestSupported(self):
- # For some strange reason, this test fails on python3.6
- if not (sys.version_info.major == 3 and sys.version_info.minor >= 7):
- return False
- try:
- # We skip this test for debug builds because it takes too long parsing lldb's own
- # debug info. Release builds are fine.
- # Checking the size of the lldb-dap binary seems to be a decent proxy for a quick
- # detection. It should be far less than 1 MB in Release builds.
- if os.path.getsize(os.environ["LLDBDAP_EXEC"]) < 1000000:
- return True
- except:
- return False
-
@skipIfWindows
@skipIf(oslist=["linux"], archs=no_match(["x86_64"]))
def test_runInTerminal(self):
- if not self.isTestSupported():
- return
"""
- Tests the "runInTerminal" reverse request. It makes sure that the IDE can
- launch the inferior with the correct environment variables and arguments.
+ Tests the "runInTerminal" reverse request. It makes sure that the IDE can
+ launch the inferior with the correct environment variables and arguments.
"""
program = self.getBuildArtifact("a.out")
source = "main.c"
@@ -92,11 +71,9 @@ def test_runInTerminal(self):
@skipIf(oslist=["linux"], archs=no_match(["x86_64"]))
def test_runInTerminalWithObjectEnv(self):
- if not self.isTestSupported():
- return
"""
- Tests the "runInTerminal" reverse request. It makes sure that the IDE can
- launch the inferior with the correct environment variables using an object.
+ Tests the "runInTerminal" reverse request. It makes sure that the IDE can
+ launch the inferior with the correct environment variables using an object.
"""
program = self.getBuildArtifact("a.out")
self.build_and_launch(program, runInTerminal=True, env={"FOO": "BAR"})
@@ -116,8 +93,6 @@ def test_runInTerminalWithObjectEnv(self):
@skipIfWindows
@skipIf(oslist=["linux"], archs=no_match(["x86_64"]))
def test_runInTerminalInvalidTarget(self):
- if not self.isTestSupported():
- return
self.build_and_create_debug_adapter()
response = self.launch(
"INVALIDPROGRAM",
@@ -135,8 +110,6 @@ def test_runInTerminalInvalidTarget(self):
@skipIfWindows
@skipIf(oslist=["linux"], archs=no_match(["x86_64"]))
def test_missingArgInRunInTerminalLauncher(self):
- if not self.isTestSupported():
- return
proc = subprocess.run(
[self.lldbDAPExec, "--launch-target", "INVALIDPROGRAM"],
capture_output=True,
@@ -150,8 +123,6 @@ def test_missingArgInRunInTerminalLauncher(self):
@skipIfWindows
@skipIf(oslist=["linux"], archs=no_match(["x86_64"]))
def test_FakeAttachedRunInTerminalLauncherWithInvalidProgram(self):
- if not self.isTestSupported():
- return
comm_file = os.path.join(self.getBuildDir(), "comm-file")
os.mkfifo(comm_file)
@@ -177,8 +148,6 @@ def test_FakeAttachedRunInTerminalLauncherWithInvalidProgram(self):
@skipIfWindows
@skipIf(oslist=["linux"], archs=no_match(["x86_64"]))
def test_FakeAttachedRunInTerminalLauncherWithValidProgram(self):
- if not self.isTestSupported():
- return
comm_file = os.path.join(self.getBuildDir(), "comm-file")
os.mkfifo(comm_file)
@@ -204,8 +173,6 @@ def test_FakeAttachedRunInTerminalLauncherWithValidProgram(self):
@skipIfWindows
@skipIf(oslist=["linux"], archs=no_match(["x86_64"]))
def test_FakeAttachedRunInTerminalLauncherAndCheckEnvironment(self):
- if not self.isTestSupported():
- return
comm_file = os.path.join(self.getBuildDir(), "comm-file")
os.mkfifo(comm_file)
@@ -225,8 +192,6 @@ def test_FakeAttachedRunInTerminalLauncherAndCheckEnvironment(self):
@skipIfWindows
@skipIf(oslist=["linux"], archs=no_match(["x86_64"]))
def test_NonAttachedRunInTerminalLauncher(self):
- if not self.isTestSupported():
- return
comm_file = os.path.join(self.getBuildDir(), "comm-file")
os.mkfifo(comm_file)
diff --git a/lldb/test/API/tools/lldb-dap/source/TestDAP_source.py b/lldb/test/API/tools/lldb-dap/source/TestDAP_source.py
index edf0af0bba2ba..93f3a9a5b5c3f 100644
--- a/lldb/test/API/tools/lldb-dap/source/TestDAP_source.py
+++ b/lldb/test/API/tools/lldb-dap/source/TestDAP_source.py
@@ -2,9 +2,6 @@
Test lldb-dap source request
"""
-
-import os
-
import lldbdap_testcase
from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
diff --git a/lldb/test/API/tools/lldb-dap/stackTrace/subtleFrames/TestDAP_subtleFrames.py b/lldb/test/API/tools/lldb-dap/stackTrace/subtleFrames/TestDAP_subtleFrames.py
index 1e41e841e39bc..7cce6cdf6a993 100644
--- a/lldb/test/API/tools/lldb-dap/stackTrace/subtleFrames/TestDAP_subtleFrames.py
+++ b/lldb/test/API/tools/lldb-dap/stackTrace/subtleFrames/TestDAP_subtleFrames.py
@@ -1,12 +1,9 @@
"""
-Test lldb-dap stack trace response
+Test lldb-dap stackTrace request for frames without sources.
"""
-
-import dap_server
-from lldbsuite.test.decorators import *
-
import lldbdap_testcase
+from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
@@ -14,7 +11,8 @@ class TestDAP_subtleFrames(lldbdap_testcase.DAPTestCaseBase):
@add_test_categories(["libc++"])
def test_subtleFrames(self):
"""
- Internal stack frames (such as the ones used by `std::function`) are marked as "subtle".
+ Test that internal stack frames (such as the ones used by
+ `std::function`) are marked as "subtle".
"""
program = self.getBuildArtifact("a.out")
self.build_and_launch(program)
diff --git a/lldb/test/API/tools/lldb-dap/stackTraceDisassemblyDisplay/TestDAP_stackTraceDisassemblyDisplay.py b/lldb/test/API/tools/lldb-dap/stackTraceDisassemblyDisplay/TestDAP_stackTraceDisassemblyDisplay.py
index 08c225b3cada4..adf18104d7620 100644
--- a/lldb/test/API/tools/lldb-dap/stackTraceDisassemblyDisplay/TestDAP_stackTraceDisassemblyDisplay.py
+++ b/lldb/test/API/tools/lldb-dap/stackTraceDisassemblyDisplay/TestDAP_stackTraceDisassemblyDisplay.py
@@ -1,5 +1,5 @@
"""
-Test lldb-dap stack trace when some of the source paths are missing
+Test lldb-dap stackTrace when some of the source paths are missing.
"""
from lldbsuite.test.lldbtest import line_number
diff --git a/lldb/test/API/tools/lldb-dap/stackTraceMissingFunctionName/TestDAP_stackTraceMissingFunctionName.py b/lldb/test/API/tools/lldb-dap/stackTraceMissingFunctionName/TestDAP_stackTraceMissingFunctionName.py
index f2131d6a82121..30a286f665dbd 100644
--- a/lldb/test/API/tools/lldb-dap/stackTraceMissingFunctionName/TestDAP_stackTraceMissingFunctionName.py
+++ b/lldb/test/API/tools/lldb-dap/stackTraceMissingFunctionName/TestDAP_stackTraceMissingFunctionName.py
@@ -1,5 +1,5 @@
"""
-Test lldb-dap stack trace response
+Test lldb-dap stackTrace request for functions without a name.
"""
from lldbsuite.test.decorators import *
diff --git a/lldb/test/API/tools/lldb-dap/stackTraceMissingModule/TestDAP_stackTraceMissingModule.py b/lldb/test/API/tools/lldb-dap/stackTraceMissingModule/TestDAP_stackTraceMissingModule.py
index 1eb00f9935a22..6ca9a90faa86b 100644
--- a/lldb/test/API/tools/lldb-dap/stackTraceMissingModule/TestDAP_stackTraceMissingModule.py
+++ b/lldb/test/API/tools/lldb-dap/stackTraceMissingModule/TestDAP_stackTraceMissingModule.py
@@ -1,5 +1,5 @@
"""
-Test lldb-dap stack trace when module is missing
+Test lldb-dap stackTrace when module is missing.
"""
from lldbsuite.test.decorators import skipUnlessPlatform
diff --git a/lldb/test/API/tools/lldb-dap/step/TestDAP_step.py b/lldb/test/API/tools/lldb-dap/step/TestDAP_step.py
index 42a39e3c8c080..e553c23d7e0ba 100644
--- a/lldb/test/API/tools/lldb-dap/step/TestDAP_step.py
+++ b/lldb/test/API/tools/lldb-dap/step/TestDAP_step.py
@@ -1,12 +1,10 @@
"""
-Test lldb-dap setBreakpoints request
+Test lldb-dap step request.
"""
-import dap_server
from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
-from lldbsuite.test import lldbutil
import lldbdap_testcase
diff --git a/lldb/test/API/tools/lldb-dap/stepInTargets/TestDAP_stepInTargets.py b/lldb/test/API/tools/lldb-dap/stepInTargets/TestDAP_stepInTargets.py
index 07acfe07c9ffc..83d8cf73e24c8 100644
--- a/lldb/test/API/tools/lldb-dap/stepInTargets/TestDAP_stepInTargets.py
+++ b/lldb/test/API/tools/lldb-dap/stepInTargets/TestDAP_stepInTargets.py
@@ -2,19 +2,20 @@
Test lldb-dap stepInTargets request
"""
-import dap_server
from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
import lldbdap_testcase
-from lldbsuite.test import lldbutil
class TestDAP_stepInTargets(lldbdap_testcase.DAPTestCaseBase):
- @expectedFailureAll(oslist=["windows"])
- @skipIf(archs=no_match(["x86_64"]))
# InstructionControlFlowKind for ARM is not supported yet.
# On Windows, lldb-dap seems to ignore targetId when stepping into functions.
# For more context, see https://github.com/llvm/llvm-project/issues/98509.
+ @expectedFailureAll(oslist=["windows"])
+ @skipIf(
+ archs=no_match(["x86_64"]),
+ bugnumber="github.com/llvm/llvm-project/issues/98509",
+ )
def test_basic(self):
"""
Tests the basic stepping in targets with directly calls.
diff --git a/lldb/test/API/tools/lldb-dap/terminated-event/TestDAP_terminatedEvent.py b/lldb/test/API/tools/lldb-dap/terminated-event/TestDAP_terminatedEvent.py
index b0abe2a38dac4..1984fce4c0524 100644
--- a/lldb/test/API/tools/lldb-dap/terminated-event/TestDAP_terminatedEvent.py
+++ b/lldb/test/API/tools/lldb-dap/terminated-event/TestDAP_terminatedEvent.py
@@ -2,12 +2,9 @@
Test lldb-dap terminated event
"""
-import dap_server
from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
-from lldbsuite.test import lldbutil
import lldbdap_testcase
-import re
import json
diff --git a/lldb/test/API/tools/lldb-dap/threads/TestDAP_threads.py b/lldb/test/API/tools/lldb-dap/threads/TestDAP_threads.py
index a4658da58ac94..15676744ffd7a 100644
--- a/lldb/test/API/tools/lldb-dap/threads/TestDAP_threads.py
+++ b/lldb/test/API/tools/lldb-dap/threads/TestDAP_threads.py
@@ -1,10 +1,9 @@
"""
-Test lldb-dap setBreakpoints request
+Test lldb-dap threads request.
"""
from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
-from lldbsuite.test import lldbutil
import lldbdap_testcase
diff --git a/lldb/test/API/tools/lldb-dap/variables/TestDAP_variables.py b/lldb/test/API/tools/lldb-dap/variables/TestDAP_variables.py
index 340be0b39010d..8976670f9c458 100644
--- a/lldb/test/API/tools/lldb-dap/variables/TestDAP_variables.py
+++ b/lldb/test/API/tools/lldb-dap/variables/TestDAP_variables.py
@@ -1,12 +1,9 @@
"""
-Test lldb-dap setBreakpoints request
+Test lldb-dap variables request.
"""
import os
-
-import dap_server
import lldbdap_testcase
-from lldbsuite.test import lldbutil
from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
diff --git a/lldb/test/API/tools/lldb-dap/variables/children/TestDAP_variables_children.py b/lldb/test/API/tools/lldb-dap/variables/children/TestDAP_variables_children.py
index 75e75c4ad7c69..9454542a83f75 100644
--- a/lldb/test/API/tools/lldb-dap/variables/children/TestDAP_variables_children.py
+++ b/lldb/test/API/tools/lldb-dap/variables/children/TestDAP_variables_children.py
@@ -1,8 +1,8 @@
-import os
+"""
+Test lldb-dap variables request with nested items.
+"""
-import dap_server
import lldbdap_testcase
-from lldbsuite.test import lldbutil
from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
>From ad51c73c4a00203646b4f80a939be19f25b7ba75 Mon Sep 17 00:00:00 2001
From: John Harrison <harjohn at google.com>
Date: Thu, 22 May 2025 12:36:09 -0700
Subject: [PATCH 2/3] Fix 'disassemble' test on macOS.
---
lldb/test/API/tools/lldb-dap/disassemble/main.c | 4 +---
lldb/tools/lldb-dap/Handler/DisassembleRequestHandler.cpp | 5 ++---
2 files changed, 3 insertions(+), 6 deletions(-)
diff --git a/lldb/test/API/tools/lldb-dap/disassemble/main.c b/lldb/test/API/tools/lldb-dap/disassemble/main.c
index 9da119ef70262..b4927db10e949 100644
--- a/lldb/test/API/tools/lldb-dap/disassemble/main.c
+++ b/lldb/test/API/tools/lldb-dap/disassemble/main.c
@@ -6,9 +6,7 @@ int compare_ints(const void *a, const void *b) {
int arg1 = *(const int *)a;
int arg2 = *(const int *)b;
- // breakpoint 1
-
- if (arg1 < arg2)
+ if (arg1 < arg2) // breakpoint 1
return -1;
if (arg1 > arg2)
return 1;
diff --git a/lldb/tools/lldb-dap/Handler/DisassembleRequestHandler.cpp b/lldb/tools/lldb-dap/Handler/DisassembleRequestHandler.cpp
index 9aa6995e5d668..fa596a842ba4f 100644
--- a/lldb/tools/lldb-dap/Handler/DisassembleRequestHandler.cpp
+++ b/lldb/tools/lldb-dap/Handler/DisassembleRequestHandler.cpp
@@ -134,9 +134,8 @@ static DisassembledInstruction ConvertSBInstructionToDisassembledInstruction(
auto line_entry = addr.GetLineEntry();
// If the line number is 0 then the entry represents a compiler generated
// location.
-
- if (line_entry.GetStartAddress() == addr && line_entry.IsValid() &&
- line_entry.GetFileSpec().IsValid() && line_entry.GetLine() != 0) {
+ if (line_entry.IsValid() && line_entry.GetFileSpec().IsValid() &&
+ line_entry.GetLine() != 0) {
auto source = CreateSource(line_entry);
disassembled_inst.location = std::move(source);
>From 10d97704b781be733f31c75a52dd92d7ae7586f4 Mon Sep 17 00:00:00 2001
From: John Harrison <harjohn at google.com>
Date: Thu, 22 May 2025 16:04:09 -0700
Subject: [PATCH 3/3] Adding a `skipIfBuildType` helper to skip tests that may
fail or be unstable in certain build configuraitons.
This revealed a number of tests that were unstable, so I also included fixes for those tests as well.
---
.../Python/lldbsuite/test/configuration.py | 3 ++
.../Python/lldbsuite/test/decorators.py | 31 ++++++-------------
lldb/packages/Python/lldbsuite/test/dotest.py | 1 +
.../Python/lldbsuite/test/dotest_args.py | 6 ++++
.../test/tools/lldb-dap/dap_server.py | 19 +++++++-----
lldb/test/API/lit.cfg.py | 3 ++
lldb/test/API/lit.site.cfg.py.in | 1 +
.../restart/TestDAP_restart_runInTerminal.py | 4 +--
.../runInTerminal/TestDAP_runInTerminal.py | 12 +++++--
.../tools/lldb-dap/server/TestDAP_server.py | 9 +++---
lldb/tools/lldb-dap/DAP.cpp | 18 +++++++++--
lldb/tools/lldb-dap/DAP.h | 7 +++--
.../Handler/DisconnectRequestHandler.cpp | 12 ++++---
lldb/tools/lldb-dap/Handler/RequestHandler.h | 3 +-
lldb/tools/lldb-dap/JSONUtils.cpp | 4 +--
lldb/tools/lldb-dap/JSONUtils.h | 2 +-
.../lldb-dap/Protocol/ProtocolRequests.h | 4 +--
lldb/tools/lldb-dap/tool/lldb-dap.cpp | 2 +-
18 files changed, 85 insertions(+), 56 deletions(-)
diff --git a/lldb/packages/Python/lldbsuite/test/configuration.py b/lldb/packages/Python/lldbsuite/test/configuration.py
index 18c1566176331..b2d91fd211477 100644
--- a/lldb/packages/Python/lldbsuite/test/configuration.py
+++ b/lldb/packages/Python/lldbsuite/test/configuration.py
@@ -137,6 +137,9 @@
# A plugin whose tests will be enabled, like intel-pt.
enabled_plugins = []
+# the build type of lldb
+# Typical values include Debug, Release, RelWithDebInfo and MinSizeRel
+cmake_build_type = None
def shouldSkipBecauseOfCategories(test_categories):
if use_categories:
diff --git a/lldb/packages/Python/lldbsuite/test/decorators.py b/lldb/packages/Python/lldbsuite/test/decorators.py
index 5e14dfeda48a8..991064538c175 100644
--- a/lldb/packages/Python/lldbsuite/test/decorators.py
+++ b/lldb/packages/Python/lldbsuite/test/decorators.py
@@ -1105,26 +1105,13 @@ def is_feature_enabled():
return skipTestIfFn(is_feature_enabled)
-def skipIfBinaryToLarge(path: Optional[str], maxSize: int):
- """Skip the test if a binary is to large.
-
- We skip this test for debug builds because it takes too long
- parsing lldb's own debug info. Release builds are fine.
- Checking the size of the lldb-dap binary seems to be a decent
- proxy for a quick detection. It should be far less than 1 MB in
- Release builds.
- """
-
- def check_binary_size():
- if not path or not os.path.exists(path):
- return "invalid path"
-
- try:
- size = os.path.getsize(path)
- if size <= maxSize:
- return None
- return f"binary {path} (size = {size} is to larger than {maxSize}"
- except:
- return f"failed to read size of {path}"
+def skipIfBuildType(types: list[str]):
+ """Skip tests if built in a specific CMAKE_BUILD_TYPE.
- return skipTestIfFn(check_binary_size)
+ Supported types include 'Release', 'RelWithDebInfo', 'Debug', 'MinSizeRel'.
+ """
+ types = [name.lower() for name in types]
+ return unittest.skipIf(
+ configuration.cmake_build_type.lower() in types,
+ "skip on {} build type(s)".format(", ".join(types)),
+ )
diff --git a/lldb/packages/Python/lldbsuite/test/dotest.py b/lldb/packages/Python/lldbsuite/test/dotest.py
index 7cc8f2985043e..d7f274ac4f60e 100644
--- a/lldb/packages/Python/lldbsuite/test/dotest.py
+++ b/lldb/packages/Python/lldbsuite/test/dotest.py
@@ -297,6 +297,7 @@ def parseOptionsAndInitTestdirs():
configuration.libcxx_include_dir = args.libcxx_include_dir
configuration.libcxx_include_target_dir = args.libcxx_include_target_dir
configuration.libcxx_library_dir = args.libcxx_library_dir
+ configuration.cmake_build_type = args.cmake_build_type.lower()
if args.channels:
lldbtest_config.channels = args.channels
diff --git a/lldb/packages/Python/lldbsuite/test/dotest_args.py b/lldb/packages/Python/lldbsuite/test/dotest_args.py
index 98210b7102e1b..e9c21388bc213 100644
--- a/lldb/packages/Python/lldbsuite/test/dotest_args.py
+++ b/lldb/packages/Python/lldbsuite/test/dotest_args.py
@@ -300,6 +300,12 @@ def create_parser():
metavar="platform-available-ports",
help="Ports available for connection to a lldb server on the remote platform",
)
+ group.add_argument(
+ "--cmake-build-type",
+ dest="cmake_build_type",
+ metavar="cmake-build-type",
+ help="Specifies the build type on single-configuration",
+ )
# Test-suite behaviour
group = parser.add_argument_group("Runtime behaviour options")
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 a028381a0a4f9..5daec41a0ad0e 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
@@ -164,6 +164,7 @@ def __init__(
self.output: dict[str, list[str]] = {}
self.configuration_done_sent = False
self.initialized = False
+ self.terminated = False
self.frame_scopes = {}
self.init_commands = init_commands
@@ -271,6 +272,10 @@ def _handle_recv_packet(self, packet: Optional[ProtocolMessage]) -> bool:
# When a new process is attached or launched, remember the
# details that are available in the body of the event
self.process_event_body = body
+ elif event == "terminated":
+ # If we get the 'terminated' event then lldb-dap has exited
+ # itself.
+ self.terminated = True
elif event == "exited":
# Process exited, mark the status to indicate the process is not
# alive.
@@ -388,7 +393,7 @@ def send_recv(self, command):
if response_or_request["command"] == "runInTerminal":
subprocess.Popen(
response_or_request["arguments"]["args"],
- env=response_or_request["arguments"]["env"],
+ env=response_or_request["arguments"].get("env", {}),
)
self.send_packet(
{
@@ -749,13 +754,11 @@ def request_restart(self, restartArguments=None):
# Caller must still call wait_for_stopped.
return response
- def request_disconnect(self, terminateDebuggee=None):
- args_dict = {}
- if terminateDebuggee is not None:
- if terminateDebuggee:
- args_dict["terminateDebuggee"] = True
- else:
- args_dict["terminateDebuggee"] = False
+ def request_disconnect(self, terminateDebuggee=False, suspendDebuggee=False):
+ args_dict = {
+ "terminateDebuggee": terminateDebuggee,
+ "suspendDebuggee": suspendDebuggee,
+ }
command_dict = {
"command": "disconnect",
"type": "request",
diff --git a/lldb/test/API/lit.cfg.py b/lldb/test/API/lit.cfg.py
index 08cf11c8a68db..646a446c86fdb 100644
--- a/lldb/test/API/lit.cfg.py
+++ b/lldb/test/API/lit.cfg.py
@@ -271,6 +271,9 @@ def delete_module_cache(path):
if is_configured("lldb_framework_dir"):
dotest_cmd += ["--framework", config.lldb_framework_dir]
+if is_configured("cmake_build_type"):
+ dotest_cmd += ["--cmake-build-type", config.cmake_build_type]
+
if "lldb-simulator-ios" in config.available_features:
dotest_cmd += ["--apple-sdk", "iphonesimulator", "--platform-name", "ios-simulator"]
elif "lldb-simulator-watchos" in config.available_features:
diff --git a/lldb/test/API/lit.site.cfg.py.in b/lldb/test/API/lit.site.cfg.py.in
index 54807de8819d2..ee31e35d257e7 100644
--- a/lldb/test/API/lit.site.cfg.py.in
+++ b/lldb/test/API/lit.site.cfg.py.in
@@ -40,6 +40,7 @@ config.has_libcxx = @LLDB_HAS_LIBCXX@
config.libcxx_libs_dir = "@LIBCXX_LIBRARY_DIR@"
config.libcxx_include_dir = "@LIBCXX_GENERATED_INCLUDE_DIR@"
config.libcxx_include_target_dir = "@LIBCXX_GENERATED_INCLUDE_TARGET_DIR@"
+config.cmake_build_type = "@CMAKE_BUILD_TYPE@"
# The API tests use their own module caches.
config.lldb_module_cache = os.path.join("@LLDB_TEST_MODULE_CACHE_LLDB@", "lldb-api")
config.clang_module_cache = os.path.join("@LLDB_TEST_MODULE_CACHE_CLANG@", "lldb-api")
diff --git a/lldb/test/API/tools/lldb-dap/restart/TestDAP_restart_runInTerminal.py b/lldb/test/API/tools/lldb-dap/restart/TestDAP_restart_runInTerminal.py
index e1338dddea5da..46cbf7532c5f7 100644
--- a/lldb/test/API/tools/lldb-dap/restart/TestDAP_restart_runInTerminal.py
+++ b/lldb/test/API/tools/lldb-dap/restart/TestDAP_restart_runInTerminal.py
@@ -2,13 +2,12 @@
Test lldb-dap restart request.
"""
-import os
from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import line_number
import lldbdap_testcase
- at skipIfBinaryToLarge(os.getenv("LLDBDAP_EXEC"), 1_000_000)
+ at skipIfBuildType(["debug"])
class TestDAP_restart_runInTerminal(lldbdap_testcase.DAPTestCaseBase):
@skipIfWindows
@skipIf(oslist=["linux"], archs=["arm"]) # Always times out on buildbot
@@ -56,6 +55,7 @@ def test_stopOnEntry(self):
program = self.getBuildArtifact("a.out")
self.build_and_launch(program, runInTerminal=True, stopOnEntry=True)
[bp_main] = self.set_function_breakpoints(["main"])
+ self.dap_server.request_configurationDone()
# When using stopOnEntry, configurationDone doesn't result in a running
# process, we should immediately get a stopped event instead.
diff --git a/lldb/test/API/tools/lldb-dap/runInTerminal/TestDAP_runInTerminal.py b/lldb/test/API/tools/lldb-dap/runInTerminal/TestDAP_runInTerminal.py
index ec03b86832069..a2fe2e19c6c85 100644
--- a/lldb/test/API/tools/lldb-dap/runInTerminal/TestDAP_runInTerminal.py
+++ b/lldb/test/API/tools/lldb-dap/runInTerminal/TestDAP_runInTerminal.py
@@ -10,7 +10,7 @@
import json
- at skipIfBinaryToLarge(os.getenv("LLDBDAP_EXEC"), 1_000_000)
+ at skipIfBuildType(["debug"])
class TestDAP_runInTerminal(lldbdap_testcase.DAPTestCaseBase):
def readPidMessage(self, fifo_file):
with open(fifo_file, "r") as file:
@@ -90,6 +90,12 @@ def test_runInTerminalWithObjectEnv(self):
self.assertIn("FOO", request_envs)
self.assertEqual("BAR", request_envs["FOO"])
+ # Ensure we can continue to a breakpoint.
+ source = "main.c"
+ breakpoint_line = line_number(source, "// breakpoint")
+ self.set_source_breakpoints(source, [breakpoint_line])
+ self.continue_to_next_stop()
+
@skipIfWindows
@skipIf(oslist=["linux"], archs=no_match(["x86_64"]))
def test_runInTerminalInvalidTarget(self):
@@ -103,8 +109,8 @@ def test_runInTerminalInvalidTarget(self):
)
self.assertFalse(response["success"])
self.assertIn(
- "Could not create a target for a program 'INVALIDPROGRAM': 'INVALIDPROGRAM' does not exist",
- response["message"],
+ "'INVALIDPROGRAM' does not exist",
+ response["body"]["error"]["format"],
)
@skipIfWindows
diff --git a/lldb/test/API/tools/lldb-dap/server/TestDAP_server.py b/lldb/test/API/tools/lldb-dap/server/TestDAP_server.py
index 7a9a4f434e04b..071b60aca355e 100644
--- a/lldb/test/API/tools/lldb-dap/server/TestDAP_server.py
+++ b/lldb/test/API/tools/lldb-dap/server/TestDAP_server.py
@@ -98,11 +98,12 @@ def test_server_interrupt(self):
self.set_source_breakpoints(source, [breakpoint_line])
self.continue_to_next_stop()
- # Interrupt the server which should disconnect all clients.
- process.send_signal(signal.SIGINT)
-
- self.dap_server.wait_for_terminated()
self.assertIsNone(
self.dap_server.exit_status,
"Process exited before interrupting lldb-dap server",
)
+
+ # Interrupt the server which should disconnect all clients.
+ process.send_signal(signal.SIGINT)
+
+ self.dap_server.wait_for_terminated()
diff --git a/lldb/tools/lldb-dap/DAP.cpp b/lldb/tools/lldb-dap/DAP.cpp
index 394e8f0e6c851..1bd5a2b6188f3 100644
--- a/lldb/tools/lldb-dap/DAP.cpp
+++ b/lldb/tools/lldb-dap/DAP.cpp
@@ -250,7 +250,9 @@ llvm::Error DAP::ConfigureIO(std::FILE *overrideOut, std::FILE *overrideErr) {
void DAP::StopEventHandlers() {
if (event_thread.joinable()) {
+ DAP_LOG(log, "Sending eBroadcastBitStopEventThread");
broadcaster.BroadcastEventByType(eBroadcastBitStopEventThread);
+ DAP_LOG(log, "Waiting for join...");
event_thread.join();
}
if (progress_event_thread.joinable()) {
@@ -820,9 +822,9 @@ void DAP::SendTerminatedEvent() {
});
}
-llvm::Error DAP::Disconnect() { return Disconnect(is_attach); }
+llvm::Error DAP::Disconnect() { return Disconnect(!is_attach, false); }
-llvm::Error DAP::Disconnect(bool terminateDebuggee) {
+llvm::Error DAP::Disconnect(bool terminate_debuggee, bool keep_stopped) {
lldb::SBError error;
lldb::SBProcess process = target.GetProcess();
auto state = process.GetState();
@@ -841,7 +843,7 @@ llvm::Error DAP::Disconnect(bool terminateDebuggee) {
case lldb::eStateStopped:
case lldb::eStateRunning: {
ScopeSyncMode scope_sync_mode(debugger);
- error = terminateDebuggee ? process.Kill() : process.Detach();
+ error = terminate_debuggee ? process.Kill() : process.Detach(keep_stopped);
break;
}
}
@@ -886,6 +888,8 @@ llvm::Error DAP::Loop() {
std::async(std::launch::async, [&]() -> lldb::SBError {
llvm::set_thread_name(transport.GetClientName() + ".transport_handler");
auto cleanup = llvm::make_scope_exit([&]() {
+ DAP_LOG(log, "({0}) Loop queue_reader has exited",
+ transport.GetClientName());
// Ensure we're marked as disconnecting when the reader exits.
disconnecting = true;
m_queue_cv.notify_all();
@@ -950,9 +954,12 @@ llvm::Error DAP::Loop() {
});
auto cleanup = llvm::make_scope_exit([&]() {
+ DAP_LOG(log, "({0}) Starting Loop cleanup...", transport.GetClientName());
out.Stop();
err.Stop();
StopEventHandlers();
+ DAP_LOG(log, "({0}) Finished with Loop cleanup...",
+ transport.GetClientName());
});
while (true) {
@@ -1219,7 +1226,12 @@ void DAP::EventThread() {
listener, lldb::eBroadcastBitError | lldb::eBroadcastBitWarning);
bool done = false;
while (!done) {
+ DAP_LOG(log, "({0}) EventThread waiting....", transport.GetClientName());
if (listener.WaitForEvent(1, event)) {
+ lldb::SBStream desc;
+ event.GetDescription(desc);
+ DAP_LOG(log, "({0}) EventThread, got event {1}",
+ transport.GetClientName(), desc.GetData());
const auto event_mask = event.GetType();
if (lldb::SBProcess::EventIsProcessEvent(event)) {
lldb::SBProcess process = lldb::SBProcess::GetProcessFromEvent(event);
diff --git a/lldb/tools/lldb-dap/DAP.h b/lldb/tools/lldb-dap/DAP.h
index 1bd94fab402ca..8c3e7b28fb9c3 100644
--- a/lldb/tools/lldb-dap/DAP.h
+++ b/lldb/tools/lldb-dap/DAP.h
@@ -279,7 +279,7 @@ struct DAP {
lldb::SBTarget CreateTarget(lldb::SBError &error);
/// Set given target object as a current target for lldb-dap and start
- /// listeing for its breakpoint events.
+ /// listening for its breakpoint events.
void SetTarget(const lldb::SBTarget target);
bool HandleObject(const protocol::Message &M);
@@ -287,8 +287,9 @@ struct DAP {
/// Disconnect the DAP session.
llvm::Error Disconnect();
- /// Disconnect the DAP session and optionally terminate the debuggee.
- llvm::Error Disconnect(bool terminateDebuggee);
+ /// Disconnect the DAP session and determine how to handle the target, if it
+ /// is still running.
+ llvm::Error Disconnect(bool terminateDebuggee, bool suspendDebuggee);
/// Send a "terminated" event to indicate the process is done being debugged.
void SendTerminatedEvent();
diff --git a/lldb/tools/lldb-dap/Handler/DisconnectRequestHandler.cpp b/lldb/tools/lldb-dap/Handler/DisconnectRequestHandler.cpp
index 81e94c7551836..87767398c27e3 100644
--- a/lldb/tools/lldb-dap/Handler/DisconnectRequestHandler.cpp
+++ b/lldb/tools/lldb-dap/Handler/DisconnectRequestHandler.cpp
@@ -7,6 +7,7 @@
//===----------------------------------------------------------------------===//
#include "DAP.h"
+#include "LLDBUtils.h"
#include "Protocol/ProtocolRequests.h"
#include "RequestHandler.h"
#include "llvm/Support/Error.h"
@@ -20,12 +21,15 @@ namespace lldb_dap {
/// Disconnect request; value of command field is 'disconnect'.
Error DisconnectRequestHandler::Run(
const std::optional<DisconnectArguments> &arguments) const {
- bool terminateDebuggee = dap.is_attach ? false : true;
+ bool terminate_debuggee = dap.is_attach ? false : true;
+ bool keep_suspend = false;
- if (arguments && arguments->terminateDebuggee)
- terminateDebuggee = *arguments->terminateDebuggee;
+ if (arguments) {
+ terminate_debuggee = arguments->terminateDebuggee;
+ keep_suspend = !arguments->suspendDebuggee;
+ }
- if (Error error = dap.Disconnect(terminateDebuggee))
+ if (Error error = dap.Disconnect(terminate_debuggee, keep_suspend))
return error;
return Error::success();
diff --git a/lldb/tools/lldb-dap/Handler/RequestHandler.h b/lldb/tools/lldb-dap/Handler/RequestHandler.h
index 3a965bcc87a5e..e01b08eba86e6 100644
--- a/lldb/tools/lldb-dap/Handler/RequestHandler.h
+++ b/lldb/tools/lldb-dap/Handler/RequestHandler.h
@@ -283,7 +283,8 @@ class DisconnectRequestHandler
using RequestHandler::RequestHandler;
static llvm::StringLiteral GetCommand() { return "disconnect"; }
FeatureSet GetSupportedFeatures() const override {
- return {protocol::eAdapterFeatureTerminateDebuggee};
+ return {protocol::eAdapterFeatureTerminateDebuggee,
+ protocol::eAdapterFeatureSuspendDebuggee};
}
llvm::Error
Run(const std::optional<protocol::DisconnectArguments> &args) const override;
diff --git a/lldb/tools/lldb-dap/JSONUtils.cpp b/lldb/tools/lldb-dap/JSONUtils.cpp
index dcc25c9212432..c9c6f4554c325 100644
--- a/lldb/tools/lldb-dap/JSONUtils.cpp
+++ b/lldb/tools/lldb-dap/JSONUtils.cpp
@@ -1335,7 +1335,7 @@ llvm::json::Value CreateCompileUnit(lldb::SBCompileUnit &unit) {
/// https://microsoft.github.io/debug-adapter-protocol/specification#Reverse_Requests_RunInTerminal
llvm::json::Object CreateRunInTerminalReverseRequest(
llvm::StringRef program, const std::vector<std::string> &args,
- const llvm::StringMap<std::string> env, llvm::StringRef cwd,
+ const llvm::StringMap<std::string> &env, llvm::StringRef cwd,
llvm::StringRef comm_file, lldb::pid_t debugger_pid) {
llvm::json::Object run_in_terminal_args;
// This indicates the IDE to open an embedded terminal, instead of opening
@@ -1352,7 +1352,7 @@ llvm::json::Object CreateRunInTerminalReverseRequest(
req_args.push_back("--launch-target");
req_args.push_back(program.str());
req_args.insert(req_args.end(), args.begin(), args.end());
- run_in_terminal_args.try_emplace("args", args);
+ run_in_terminal_args.try_emplace("args", req_args);
if (!cwd.empty())
run_in_terminal_args.try_emplace("cwd", cwd);
diff --git a/lldb/tools/lldb-dap/JSONUtils.h b/lldb/tools/lldb-dap/JSONUtils.h
index ac9b39739104f..5758c3d56ec90 100644
--- a/lldb/tools/lldb-dap/JSONUtils.h
+++ b/lldb/tools/lldb-dap/JSONUtils.h
@@ -544,7 +544,7 @@ llvm::json::Value CreateCompileUnit(lldb::SBCompileUnit &unit);
/// Microsoft.
llvm::json::Object CreateRunInTerminalReverseRequest(
llvm::StringRef program, const std::vector<std::string> &args,
- const llvm::StringMap<std::string> env, llvm::StringRef cwd,
+ const llvm::StringMap<std::string> &env, llvm::StringRef cwd,
llvm::StringRef comm_file, lldb::pid_t debugger_pid);
/// Create a "Terminated" JSON object that contains statistics
diff --git a/lldb/tools/lldb-dap/Protocol/ProtocolRequests.h b/lldb/tools/lldb-dap/Protocol/ProtocolRequests.h
index 7c774e50d6e56..4998c9b72c79d 100644
--- a/lldb/tools/lldb-dap/Protocol/ProtocolRequests.h
+++ b/lldb/tools/lldb-dap/Protocol/ProtocolRequests.h
@@ -65,13 +65,13 @@ struct DisconnectArguments {
/// disconnected. If unspecified, the debug adapter is free to do whatever it
/// thinks is best. The attribute is only honored by a debug adapter if the
/// corresponding capability `supportTerminateDebuggee` is true.
- std::optional<bool> terminateDebuggee;
+ bool terminateDebuggee = false;
/// Indicates whether the debuggee should stay suspended when the debugger is
/// disconnected. If unspecified, the debuggee should resume execution. The
/// attribute is only honored by a debug adapter if the corresponding
/// capability `supportSuspendDebuggee` is true.
- std::optional<bool> suspendDebuggee;
+ bool suspendDebuggee = false;
};
bool fromJSON(const llvm::json::Value &, DisconnectArguments &,
llvm::json::Path);
diff --git a/lldb/tools/lldb-dap/tool/lldb-dap.cpp b/lldb/tools/lldb-dap/tool/lldb-dap.cpp
index 7a4cc70902a56..9b9de5e21a742 100644
--- a/lldb/tools/lldb-dap/tool/lldb-dap.cpp
+++ b/lldb/tools/lldb-dap/tool/lldb-dap.cpp
@@ -542,7 +542,7 @@ int main(int argc, char *argv[]) {
lldb::IOObjectSP output = std::make_shared<NativeFile>(
stdout_fd, File::eOpenOptionWriteOnly, NativeFile::Unowned);
- constexpr llvm::StringLiteral client_name = "stdin/stdout";
+ constexpr llvm::StringLiteral client_name = "stdio";
Transport transport(client_name, log.get(), input, output);
DAP dap(log.get(), default_repl_mode, pre_init_commands, transport);
More information about the lldb-commits
mailing list