summaryrefslogtreecommitdiff
path: root/lldb/test/API
diff options
context:
space:
mode:
Diffstat (limited to 'lldb/test/API')
-rw-r--r--lldb/test/API/commands/expression/diagnostics/TestExprDiagnostics.py18
-rw-r--r--lldb/test/API/commands/expression/import-std-module/array/TestArrayFromStdModule.py3
-rw-r--r--lldb/test/API/commands/expression/import-std-module/deque-basic/TestDequeFromStdModule.py3
-rw-r--r--lldb/test/API/commands/expression/import-std-module/deque-dbg-info-content/TestDbgInfoContentDequeFromStdModule.py3
-rw-r--r--lldb/test/API/commands/expression/import-std-module/forward_list/TestForwardListFromStdModule.py3
-rw-r--r--lldb/test/API/commands/expression/import-std-module/list-dbg-info-content/TestDbgInfoContentListFromStdModule.py3
-rw-r--r--lldb/test/API/commands/expression/import-std-module/list/TestListFromStdModule.py3
-rw-r--r--lldb/test/API/commands/protocol/TestMCPUnixSocket.py13
-rw-r--r--lldb/test/API/driver/quit_speed/TestQuitWithProcess.py25
-rw-r--r--lldb/test/API/functionalities/breakpoint/scripted_bkpt/resolver.py1
-rw-r--r--lldb/test/API/functionalities/breakpoint/scripted_bkpt/was_hit/Makefile4
-rw-r--r--lldb/test/API/functionalities/breakpoint/scripted_bkpt/was_hit/TestWasHit.py102
-rw-r--r--lldb/test/API/functionalities/breakpoint/scripted_bkpt/was_hit/bkpt_resolver.py49
-rw-r--r--lldb/test/API/functionalities/breakpoint/scripted_bkpt/was_hit/main.c14
-rw-r--r--lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic-simulators/invalid-atomic/Makefile3
-rw-r--r--lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic-simulators/invalid-atomic/TestDataFormatterInvalidAtomic.py45
-rw-r--r--lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic-simulators/invalid-atomic/main.cpp23
-rw-r--r--lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/unordered_map-iterator/TestDataFormatterStdUnorderedMap.py5
-rw-r--r--lldb/test/API/functionalities/json/symbol-file/Makefile1
-rw-r--r--lldb/test/API/functionalities/stats_api/TestStatisticsAPI.py28
-rw-r--r--lldb/test/API/functionalities/stats_api/arm64-minidump-build-ids.yaml19
-rw-r--r--lldb/test/API/functionalities/thread/step_out_line0/Makefile3
-rw-r--r--lldb/test/API/functionalities/thread/step_out_line0/TestThreadStepOutLine0.py35
-rw-r--r--lldb/test/API/functionalities/thread/step_out_line0/main.c11
-rw-r--r--lldb/test/API/functionalities/unwind/cortex-m-exception/TestCortexMExceptionUnwind.py26
-rw-r--r--lldb/test/API/functionalities/unwind/cortex-m-exception/armv7m-nofpu-exception.yaml29
-rw-r--r--lldb/test/API/functionalities/unwind/cortex-m-exception/binary.json6
-rw-r--r--lldb/test/API/lang/cpp/abi_tag_structors/TestAbiTagStructors.py33
-rw-r--r--lldb/test/API/lang/cpp/expr-definition-in-dylib/TestExprDefinitionInDylib.py20
-rw-r--r--lldb/test/API/lang/cpp/floating-types-specialization/Makefile3
-rw-r--r--lldb/test/API/lang/cpp/floating-types-specialization/TestCppFloatingTypesSpecialization.py37
-rw-r--r--lldb/test/API/lang/cpp/floating-types-specialization/main.cpp11
-rw-r--r--lldb/test/API/lang/cpp/function-call-from-object-file/Makefile3
-rw-r--r--lldb/test/API/lang/cpp/function-call-from-object-file/TestFunctionCallFromObjectFile.py29
-rw-r--r--lldb/test/API/lang/cpp/function-call-from-object-file/common.h8
-rw-r--r--lldb/test/API/lang/cpp/function-call-from-object-file/lib1.cpp8
-rw-r--r--lldb/test/API/lang/cpp/function-call-from-object-file/lib2.cpp6
-rw-r--r--lldb/test/API/lang/cpp/function-call-from-object-file/main.cpp10
-rw-r--r--lldb/test/API/lang/cpp/structured-binding/TestStructuredBinding.py31
-rw-r--r--lldb/test/API/lang/cpp/template-arguments/TestCppTemplateArguments.py9
-rw-r--r--lldb/test/API/lang/objc/ivar-in-framework-base/Makefile6
-rw-r--r--lldb/test/API/lang/objc/ivar-in-framework-base/TestIvarInFrameworkBase.py39
-rw-r--r--lldb/test/API/lang/objc/ivar-in-framework-base/lib.h6
-rw-r--r--lldb/test/API/lang/objc/ivar-in-framework-base/lib.m8
-rw-r--r--lldb/test/API/lang/objc/ivar-in-framework-base/main.m22
-rw-r--r--lldb/test/API/macosx/debugserver-multimemread/Makefile3
-rw-r--r--lldb/test/API/macosx/debugserver-multimemread/TestDebugserverMultiMemRead.py102
-rw-r--r--lldb/test/API/macosx/debugserver-multimemread/main.c14
-rw-r--r--lldb/test/API/macosx/mte/Makefile15
-rw-r--r--lldb/test/API/macosx/mte/TestDarwinMTE.py122
-rw-r--r--lldb/test/API/macosx/mte/main.c28
-rw-r--r--lldb/test/API/macosx/mte/mte-entitlements.plist10
-rw-r--r--lldb/test/API/python_api/debugger/TestDebuggerAPI.py147
-rw-r--r--lldb/test/API/python_api/default-constructor/sb_filespec.py2
-rw-r--r--lldb/test/API/python_api/interpreter/TestCommandInterpreterAPI.py50
-rw-r--r--lldb/test/API/python_api/sbtype_basic_type/TestSBTypeBasicType.py8
-rw-r--r--lldb/test/API/tools/lldb-dap/attach-commands/Makefile3
-rw-r--r--lldb/test/API/tools/lldb-dap/attach-commands/TestDAP_attachCommands.py145
-rw-r--r--lldb/test/API/tools/lldb-dap/attach-commands/main.c30
-rw-r--r--lldb/test/API/tools/lldb-dap/attach/TestDAP_attach.py205
-rw-r--r--lldb/test/API/tools/lldb-dap/attach/main.c11
-rw-r--r--lldb/test/API/tools/lldb-dap/breakpoint-events/TestDAP_breakpointEvents.py4
-rw-r--r--lldb/test/API/tools/lldb-dap/cancel/TestDAP_cancel.py2
-rw-r--r--lldb/test/API/tools/lldb-dap/commands/TestDAP_commands.py2
-rw-r--r--lldb/test/API/tools/lldb-dap/io/TestDAP_io.py10
-rw-r--r--lldb/test/API/tools/lldb-dap/launch/TestDAP_launch.py22
-rw-r--r--lldb/test/API/tools/lldb-dap/module-event/TestDAP_module_event.py12
-rw-r--r--lldb/test/API/tools/lldb-dap/module/TestDAP_module.py4
-rw-r--r--lldb/test/API/tools/lldb-dap/output/TestDAP_output.py2
-rw-r--r--lldb/test/API/tools/lldb-dap/restart/TestDAP_restart_console.py2
-rw-r--r--lldb/test/API/tools/lldb-dap/stackTraceDisassemblyDisplay/TestDAP_stackTraceDisassemblyDisplay.py3
-rw-r--r--lldb/test/API/tools/lldb-dap/variables/TestDAP_variables.py35
-rw-r--r--lldb/test/API/tools/lldb-server/TestGdbRemoteFork.py1
-rw-r--r--lldb/test/API/tools/lldb-server/TestLldbGdbServer.py4
-rw-r--r--lldb/test/API/tools/lldb-server/main.cpp7
75 files changed, 1480 insertions, 292 deletions
diff --git a/lldb/test/API/commands/expression/diagnostics/TestExprDiagnostics.py b/lldb/test/API/commands/expression/diagnostics/TestExprDiagnostics.py
index 0cc505aedc4b..759b620105c4 100644
--- a/lldb/test/API/commands/expression/diagnostics/TestExprDiagnostics.py
+++ b/lldb/test/API/commands/expression/diagnostics/TestExprDiagnostics.py
@@ -215,8 +215,20 @@ note: candidate function not viable: requires single argument 'x', but 2 argumen
details = diags.GetValueForKey("details")
- # Detail 1/2: undeclared 'a'
+ # Detail 1/3: note: requested expression language
diag = details.GetItemAtIndex(0)
+ self.assertEqual(str(diag.GetValueForKey("severity")), "note")
+ self.assertIn("Ran expression as 'C++", str(diag.GetValueForKey("message")))
+ self.assertIn(
+ "Ran expression as 'C++", str(diag.GetValueForKey("rendered"))
+ )
+ self.assertEqual(str(diag.GetValueForKey("source_location")), "")
+ self.assertEqual(str(diag.GetValueForKey("file")), "")
+ self.assertFalse(diag.GetValueForKey("hidden").GetBooleanValue())
+ self.assertFalse(diag.GetValueForKey("in_user_input").GetBooleanValue())
+
+ # Detail 2/3: undeclared 'a'
+ diag = details.GetItemAtIndex(1)
severity = diag.GetValueForKey("severity")
message = diag.GetValueForKey("message")
@@ -234,8 +246,8 @@ note: candidate function not viable: requires single argument 'x', but 2 argumen
self.assertFalse(hidden.GetBooleanValue())
self.assertTrue(in_user_input.GetBooleanValue())
- # Detail 1/2: undeclared 'b'
- diag = details.GetItemAtIndex(1)
+ # Detail 3/3: undeclared 'b'
+ diag = details.GetItemAtIndex(2)
message = diag.GetValueForKey("message")
self.assertIn("undeclared identifier 'b'", str(message))
diff --git a/lldb/test/API/commands/expression/import-std-module/array/TestArrayFromStdModule.py b/lldb/test/API/commands/expression/import-std-module/array/TestArrayFromStdModule.py
index ed028a1a4ea3..4aea8009058b 100644
--- a/lldb/test/API/commands/expression/import-std-module/array/TestArrayFromStdModule.py
+++ b/lldb/test/API/commands/expression/import-std-module/array/TestArrayFromStdModule.py
@@ -11,6 +11,9 @@ class TestCase(TestBase):
@add_test_categories(["libc++"])
@skipIf(compiler=no_match("clang"))
@skipIf(macos_version=["<", "15.0"])
+ @skipIf(
+ bugnumber="ASTImport of lambdas not supported: https://github.com/llvm/llvm-project/issues/149477"
+ )
def test(self):
self.build()
diff --git a/lldb/test/API/commands/expression/import-std-module/deque-basic/TestDequeFromStdModule.py b/lldb/test/API/commands/expression/import-std-module/deque-basic/TestDequeFromStdModule.py
index 0fb6e883597d..5e819b7f6e16 100644
--- a/lldb/test/API/commands/expression/import-std-module/deque-basic/TestDequeFromStdModule.py
+++ b/lldb/test/API/commands/expression/import-std-module/deque-basic/TestDequeFromStdModule.py
@@ -11,6 +11,9 @@ class TestBasicDeque(TestBase):
@add_test_categories(["libc++"])
@skipIf(compiler=no_match("clang"))
@skipIf(macos_version=["<", "15.0"])
+ @skipIf(
+ bugnumber="ASTImport of lambdas not supported: https://github.com/llvm/llvm-project/issues/149477"
+ )
def test(self):
self.build()
diff --git a/lldb/test/API/commands/expression/import-std-module/deque-dbg-info-content/TestDbgInfoContentDequeFromStdModule.py b/lldb/test/API/commands/expression/import-std-module/deque-dbg-info-content/TestDbgInfoContentDequeFromStdModule.py
index e631a8737637..e8676b21bced 100644
--- a/lldb/test/API/commands/expression/import-std-module/deque-dbg-info-content/TestDbgInfoContentDequeFromStdModule.py
+++ b/lldb/test/API/commands/expression/import-std-module/deque-dbg-info-content/TestDbgInfoContentDequeFromStdModule.py
@@ -12,6 +12,9 @@ class TestDbgInfoContentDeque(TestBase):
@skipIf(compiler=no_match("clang"))
@skipIf(compiler="clang", compiler_version=["<", "18.0"])
@skipIf(macos_version=["<", "15.0"])
+ @skipIf(
+ bugnumber="ASTImport of lambdas not supported: https://github.com/llvm/llvm-project/issues/149477"
+ )
def test(self):
self.build()
diff --git a/lldb/test/API/commands/expression/import-std-module/forward_list/TestForwardListFromStdModule.py b/lldb/test/API/commands/expression/import-std-module/forward_list/TestForwardListFromStdModule.py
index a6ba0810e68e..9581155be204 100644
--- a/lldb/test/API/commands/expression/import-std-module/forward_list/TestForwardListFromStdModule.py
+++ b/lldb/test/API/commands/expression/import-std-module/forward_list/TestForwardListFromStdModule.py
@@ -11,6 +11,9 @@ class TestBasicForwardList(TestBase):
@add_test_categories(["libc++"])
@skipIf(compiler=no_match("clang"))
@skipIf(macos_version=["<", "15.0"])
+ @skipIf(
+ bugnumber="ASTImport of lambdas not supported: https://github.com/llvm/llvm-project/issues/149477"
+ )
def test(self):
self.build()
diff --git a/lldb/test/API/commands/expression/import-std-module/list-dbg-info-content/TestDbgInfoContentListFromStdModule.py b/lldb/test/API/commands/expression/import-std-module/list-dbg-info-content/TestDbgInfoContentListFromStdModule.py
index b26bd7dedda8..923551ca64c3 100644
--- a/lldb/test/API/commands/expression/import-std-module/list-dbg-info-content/TestDbgInfoContentListFromStdModule.py
+++ b/lldb/test/API/commands/expression/import-std-module/list-dbg-info-content/TestDbgInfoContentListFromStdModule.py
@@ -13,6 +13,9 @@ class TestDbgInfoContentList(TestBase):
@skipIf(compiler=no_match("clang"))
@skipIf(compiler="clang", compiler_version=["<", "12.0"])
@skipIf(macos_version=["<", "15.0"])
+ @skipIf(
+ bugnumber="ASTImport of lambdas not supported: https://github.com/llvm/llvm-project/issues/149477"
+ )
def test(self):
self.build()
diff --git a/lldb/test/API/commands/expression/import-std-module/list/TestListFromStdModule.py b/lldb/test/API/commands/expression/import-std-module/list/TestListFromStdModule.py
index 6253a35e926d..d6c88926e3e4 100644
--- a/lldb/test/API/commands/expression/import-std-module/list/TestListFromStdModule.py
+++ b/lldb/test/API/commands/expression/import-std-module/list/TestListFromStdModule.py
@@ -11,6 +11,9 @@ class TestBasicList(TestBase):
@add_test_categories(["libc++"])
@skipIf(compiler=no_match("clang"))
@skipIf(macos_version=["<", "15.0"])
+ @skipIf(
+ bugnumber="ASTImport of lambdas not supported: https://github.com/llvm/llvm-project/issues/149477"
+ )
def test(self):
self.build()
diff --git a/lldb/test/API/commands/protocol/TestMCPUnixSocket.py b/lldb/test/API/commands/protocol/TestMCPUnixSocket.py
index ea9255cc60ef..9edb97eb791b 100644
--- a/lldb/test/API/commands/protocol/TestMCPUnixSocket.py
+++ b/lldb/test/API/commands/protocol/TestMCPUnixSocket.py
@@ -32,3 +32,16 @@ class MCPUnixSocketCommandTestCase(TestBase):
startstr="MCP server started with connection listeners:",
substrs=[f"unix-connect://{socket_file}"],
)
+
+ self.expect(
+ "protocol-server get MCP",
+ startstr="MCP server connection listeners:",
+ substrs=[f"unix-connect://{socket_file}"],
+ )
+
+ self.runCmd("protocol-server stop MCP", check=False)
+ self.expect(
+ "protocol-server get MCP",
+ error=True,
+ substrs=["MCP server is not running"],
+ )
diff --git a/lldb/test/API/driver/quit_speed/TestQuitWithProcess.py b/lldb/test/API/driver/quit_speed/TestQuitWithProcess.py
index 2412b295bfb5..305e3cc397cf 100644
--- a/lldb/test/API/driver/quit_speed/TestQuitWithProcess.py
+++ b/lldb/test/API/driver/quit_speed/TestQuitWithProcess.py
@@ -33,3 +33,28 @@ class DriverQuitSpeedTest(PExpectTest):
child.sendline("quit")
print("sent quit")
child.expect(pexpect.EOF, timeout=15)
+
+ @skipIfAsan
+ def test_run_quit_with_prompt(self):
+ """Test that the lldb driver's batch mode works correctly with trailing space in confimation."""
+ import pexpect
+
+ self.build()
+
+ exe = self.getBuildArtifact("a.out")
+
+ self.launch(executable=exe)
+ child = self.child
+
+ # Launch the process without a TTY so we don't have to interrupt:
+ child.sendline("process launch -n")
+ print("launched process")
+ child.expect(r"Process ([\d]*) launched:")
+ print("Got launch message")
+ child.sendline("quit")
+ print("sent quit")
+
+ child.expect(r".*LLDB will kill one or more processes.*")
+ # add trailing space to the confirmation.
+ child.sendline("yEs ")
+ child.expect(pexpect.EOF, timeout=15)
diff --git a/lldb/test/API/functionalities/breakpoint/scripted_bkpt/resolver.py b/lldb/test/API/functionalities/breakpoint/scripted_bkpt/resolver.py
index 85c734012761..95868486b8cb 100644
--- a/lldb/test/API/functionalities/breakpoint/scripted_bkpt/resolver.py
+++ b/lldb/test/API/functionalities/breakpoint/scripted_bkpt/resolver.py
@@ -51,7 +51,6 @@ class Resolver:
def get_short_help(self):
return "I am a python breakpoint resolver"
-
class ResolverModuleDepth(Resolver):
def __get_depth__(self):
return lldb.eSearchDepthModule
diff --git a/lldb/test/API/functionalities/breakpoint/scripted_bkpt/was_hit/Makefile b/lldb/test/API/functionalities/breakpoint/scripted_bkpt/was_hit/Makefile
new file mode 100644
index 000000000000..695335e068c0
--- /dev/null
+++ b/lldb/test/API/functionalities/breakpoint/scripted_bkpt/was_hit/Makefile
@@ -0,0 +1,4 @@
+C_SOURCES := main.c
+CFLAGS_EXTRAS := -std=c99
+
+include Makefile.rules
diff --git a/lldb/test/API/functionalities/breakpoint/scripted_bkpt/was_hit/TestWasHit.py b/lldb/test/API/functionalities/breakpoint/scripted_bkpt/was_hit/TestWasHit.py
new file mode 100644
index 000000000000..2e176239facf
--- /dev/null
+++ b/lldb/test/API/functionalities/breakpoint/scripted_bkpt/was_hit/TestWasHit.py
@@ -0,0 +1,102 @@
+"""
+Test the WasHit feature of scripted breakpoints
+"""
+
+import os
+import lldb
+import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+
+
+class TestWasHit(TestBase):
+ NO_DEBUG_INFO_TESTCASE = True
+
+ @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24528")
+ def test_was_hit_resolver(self):
+ """Use facade breakpoints to emulate hitting some locations"""
+ self.build()
+ self.do_test()
+
+ def make_target_and_import(self):
+ target = lldbutil.run_to_breakpoint_make_target(self)
+ self.import_resolver_script()
+ return target
+
+ def import_resolver_script(self):
+ interp = self.dbg.GetCommandInterpreter()
+ error = lldb.SBError()
+
+ script_name = os.path.join(self.getSourceDir(), "bkpt_resolver.py")
+
+ command = "command script import " + script_name
+ self.runCmd(command)
+
+ def make_extra_args(self, sym_name, num_locs, loc_to_miss):
+ return f" -k symbol -v {sym_name} -k num_locs -v {num_locs} -k loc_to_miss -v {loc_to_miss} "
+
+ def do_test(self):
+ """This reads in a python file and sets a breakpoint using it."""
+
+ target = self.make_target_and_import()
+ extra_args = self.make_extra_args("stop_symbol", 4, 2)
+
+ bkpt_no = lldbutil.run_break_set_by_script(
+ self, "bkpt_resolver.FacadeExample", extra_args, 4
+ )
+
+ # Make sure the help text shows up in the "break list" output:
+ self.expect(
+ "break list",
+ substrs=["I am a facade resolver - sym: stop_symbol - num_locs: 4"],
+ msg="Help is listed in break list",
+ )
+
+ bkpt = target.FindBreakpointByID(bkpt_no)
+ self.assertTrue(bkpt.IsValid(), "Found the right breakpoint")
+
+ # Now continue. We should hit locations 1, 3 and 4:
+ (target, process, thread, bkpt) = lldbutil.run_to_breakpoint_do_run(
+ self, target, bkpt
+ )
+ # This location should be bkpt_no.1:
+ self.assertEqual(
+ thread.stop_reason_data[0], bkpt_no, "Hit the right breakpoint"
+ )
+ self.assertEqual(thread.stop_reason_data[1], 1, "First location hit is 1")
+
+ for loc in [3, 4]:
+ process.Continue()
+ self.assertEqual(
+ thread.stop_reason, lldb.eStopReasonBreakpoint, "Hit breakpoint"
+ )
+ self.assertEqual(
+ thread.stop_reason_data[0], bkpt_no, "Hit the right breakpoint"
+ )
+ self.assertEqual(
+ thread.stop_reason_data[1], loc, f"Hit the right location: {loc}"
+ )
+
+ # At this point we should have hit three of the four locations, and not location 1.2.
+ # Check that that is true, and that the descriptions for the location are the ones
+ # the resolver provided.
+ self.assertEqual(bkpt.hit_count, 3, "Hit three locations")
+ for loc_id in range(1, 4):
+ bkpt_loc = bkpt.FindLocationByID(loc_id)
+ self.assertTrue(bkpt_loc.IsValid(), f"{loc_id} was invalid.")
+ if loc_id != 2:
+ self.assertEqual(
+ bkpt_loc.hit_count, 1, f"Loc {loc_id} hit count was wrong"
+ )
+ else:
+ self.assertEqual(bkpt_loc.hit_count, 0, "We didn't skip loc 2")
+ stream = lldb.SBStream()
+ self.assertTrue(
+ bkpt_loc.GetDescription(stream, lldb.eDescriptionLevelFull),
+ f"Didn't get description for {loc_id}",
+ )
+ self.assertIn(
+ f"Location index: {loc_id}",
+ stream.GetData(),
+ f"Wrong desciption for {loc_id}",
+ )
diff --git a/lldb/test/API/functionalities/breakpoint/scripted_bkpt/was_hit/bkpt_resolver.py b/lldb/test/API/functionalities/breakpoint/scripted_bkpt/was_hit/bkpt_resolver.py
new file mode 100644
index 000000000000..acc8513e3e3e
--- /dev/null
+++ b/lldb/test/API/functionalities/breakpoint/scripted_bkpt/was_hit/bkpt_resolver.py
@@ -0,0 +1,49 @@
+import lldb
+
+
+class FacadeExample:
+ def __init__(self, bkpt, extra_args, dict):
+ self.bkpt = bkpt
+ self.extra_args = extra_args
+ self.base_sym = None
+ self.facade_locs = []
+ self.facade_locs_desc = []
+ self.cur_facade_loc = 1
+
+ self.sym_name = extra_args.GetValueForKey("symbol").GetStringValue(100)
+ self.num_locs = extra_args.GetValueForKey("num_locs").GetIntegerValue(5)
+ self.loc_to_miss = extra_args.GetValueForKey("loc_to_miss").GetIntegerValue(
+ 10000
+ )
+
+ def __callback__(self, sym_ctx):
+ self.base_sym = sym_ctx.module.FindSymbol(self.sym_name, lldb.eSymbolTypeCode)
+ if self.base_sym.IsValid():
+ self.bkpt.AddLocation(self.base_sym.GetStartAddress())
+ # Locations are 1 based, so to keep things simple, I'm making
+ # the array holding locations 1 based as well:
+ self.facade_locs_desc.append(
+ "This is the zero index, you shouldn't see this"
+ )
+ self.facade_locs.append(None)
+ for i in range(1, self.num_locs + 1):
+ self.facade_locs_desc.append(f"Location index: {i}")
+ self.facade_locs.append(self.bkpt.AddFacadeLocation())
+
+ def get_short_help(self):
+ return f"I am a facade resolver - sym: {self.sym_name} - num_locs: {self.num_locs} - locs_to_miss: {self.loc_to_miss}"
+
+ def was_hit(self, frame, bp_loc):
+ tmp_loc = self.cur_facade_loc
+
+ self.cur_facade_loc = self.cur_facade_loc + 1
+ if self.cur_facade_loc == self.num_locs + 1:
+ self.cur_facade_loc = 1
+
+ if tmp_loc == self.loc_to_miss:
+ return None
+
+ return self.facade_locs[tmp_loc]
+
+ def get_location_description(self, bp_loc, desc_level):
+ return self.facade_locs_desc[bp_loc.id]
diff --git a/lldb/test/API/functionalities/breakpoint/scripted_bkpt/was_hit/main.c b/lldb/test/API/functionalities/breakpoint/scripted_bkpt/was_hit/main.c
new file mode 100644
index 000000000000..b8f977e49351
--- /dev/null
+++ b/lldb/test/API/functionalities/breakpoint/scripted_bkpt/was_hit/main.c
@@ -0,0 +1,14 @@
+#include <stdio.h>
+
+int stop_symbol() {
+ static int s_cnt = 0;
+ printf("I am in the stop symbol: %d\n", s_cnt++);
+ return s_cnt;
+}
+
+int main() {
+ for (int i = 0; i < 100; i++) {
+ stop_symbol();
+ }
+ return 0;
+}
diff --git a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic-simulators/invalid-atomic/Makefile b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic-simulators/invalid-atomic/Makefile
new file mode 100644
index 000000000000..99998b20bcb0
--- /dev/null
+++ b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic-simulators/invalid-atomic/Makefile
@@ -0,0 +1,3 @@
+CXX_SOURCES := main.cpp
+
+include Makefile.rules
diff --git a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic-simulators/invalid-atomic/TestDataFormatterInvalidAtomic.py b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic-simulators/invalid-atomic/TestDataFormatterInvalidAtomic.py
new file mode 100644
index 000000000000..76b8e7b40f44
--- /dev/null
+++ b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic-simulators/invalid-atomic/TestDataFormatterInvalidAtomic.py
@@ -0,0 +1,45 @@
+"""
+Test formatting of `std::atomic`s not from any STL
+"""
+
+import lldb
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
+
+
+class InvalidAtomicDataFormatterTestCase(TestBase):
+ def test(self):
+ self.build()
+ lldbutil.run_to_source_breakpoint(
+ self, "Set break point at this line.", lldb.SBFileSpec("main.cpp")
+ )
+
+ self.expect_expr(
+ "a",
+ result_children=[
+ ValueCheck(name="foo", value="1"),
+ ValueCheck(name="bar", value="2"),
+ ],
+ )
+ self.expect_expr(
+ "b",
+ result_children=[
+ ValueCheck(name="foo", value="3"),
+ ValueCheck(name="bar", value="4"),
+ ],
+ )
+
+ self.expect_expr(
+ "c",
+ result_children=[
+ ValueCheck(name="foo", value="5"),
+ ValueCheck(name="bar", value="6"),
+ ],
+ )
+ self.expect_expr(
+ "d",
+ result_children=[
+ ValueCheck(name="foo", value="7"),
+ ValueCheck(name="bar", value="8"),
+ ],
+ )
diff --git a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic-simulators/invalid-atomic/main.cpp b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic-simulators/invalid-atomic/main.cpp
new file mode 100644
index 000000000000..7b4c51c921a9
--- /dev/null
+++ b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic-simulators/invalid-atomic/main.cpp
@@ -0,0 +1,23 @@
+namespace std {
+template <typename T> struct atomic {
+ int foo;
+ int bar;
+};
+
+namespace __1 {
+template <typename T> struct atomic {
+ int foo;
+ int bar;
+};
+} // namespace __1
+} // namespace std
+
+int main() {
+ std::atomic<int> a{1, 2};
+ std::atomic<void> b{3, 4};
+
+ std::__1::atomic<int> c{5, 6};
+ std::__1::atomic<void> d{7, 8};
+
+ return 0; // Set break point at this line.
+}
diff --git a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/unordered_map-iterator/TestDataFormatterStdUnorderedMap.py b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/unordered_map-iterator/TestDataFormatterStdUnorderedMap.py
index 1e920faab639..45f7b5be465c 100644
--- a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/unordered_map-iterator/TestDataFormatterStdUnorderedMap.py
+++ b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/unordered_map-iterator/TestDataFormatterStdUnorderedMap.py
@@ -124,11 +124,6 @@ class StdUnorderedMapDataFormatterTestCase(TestBase):
self.check_ptr_ptr("ptr5")
self.check_ptr_ptr("ptr6")
- @expectedFailureAll(
- bugnumber="https://github.com/llvm/llvm-project/issues/146040",
- compiler="clang",
- compiler_version=["<", "21"],
- )
@add_test_categories(["libc++"])
def test_ptr_libcxx(self):
self.build(dictionary={"USE_LIBCPP": 1})
diff --git a/lldb/test/API/functionalities/json/symbol-file/Makefile b/lldb/test/API/functionalities/json/symbol-file/Makefile
index 13bc164582ee..5d05d95fc842 100644
--- a/lldb/test/API/functionalities/json/symbol-file/Makefile
+++ b/lldb/test/API/functionalities/json/symbol-file/Makefile
@@ -1,4 +1,5 @@
C_SOURCES := main.c
+CFLAGS_EXTRAS := -no-pie
all: stripped.out
diff --git a/lldb/test/API/functionalities/stats_api/TestStatisticsAPI.py b/lldb/test/API/functionalities/stats_api/TestStatisticsAPI.py
index f06c9ae14bb7..d7249df350fc 100644
--- a/lldb/test/API/functionalities/stats_api/TestStatisticsAPI.py
+++ b/lldb/test/API/functionalities/stats_api/TestStatisticsAPI.py
@@ -1,6 +1,7 @@
# Test the SBAPI for GetStatistics()
import json
+
import lldb
from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
@@ -54,6 +55,11 @@ class TestStatsAPI(TestBase):
stats_json,
'Make sure the "frameVariable" key in in target.GetStatistics()["targets"][0]',
)
+ self.assertNotIn(
+ "loadCoreTime",
+ stats_json,
+ "LoadCoreTime should not be present in a live, non-coredump target",
+ )
expressionEvaluation = stats_json["expressionEvaluation"]
self.assertIn(
"successes",
@@ -157,3 +163,25 @@ class TestStatsAPI(TestBase):
stats_force.GetAsJSON(stream_force)
debug_stats_force = json.loads(stream_force.GetData())
self.assertEqual(debug_stats_force["totalDebugInfoByteSize"], 445)
+
+ def test_core_load_time(self):
+ """
+ Test to see if the coredump path is included in statistics dump.
+ """
+ yaml_file = "arm64-minidump-build-ids.yaml"
+ src_dir = self.getSourceDir()
+ minidump_path = self.getBuildArtifact(os.path.basename(yaml_file) + ".dmp")
+ self.yaml2obj(os.path.join(src_dir, yaml_file), minidump_path)
+ target = self.dbg.CreateTarget(None)
+ process = target.LoadCore(minidump_path)
+ self.assertTrue(process.IsValid())
+
+ stats_options = lldb.SBStatisticsOptions()
+ stats = target.GetStatistics(stats_options)
+ stream = lldb.SBStream()
+ stats.GetAsJSON(stream)
+ debug_stats = json.loads(stream.GetData())
+ self.assertTrue("targets" in debug_stats)
+ target_info = debug_stats["targets"][0]
+ self.assertTrue("loadCoreTime" in target_info)
+ self.assertTrue(float(target_info["loadCoreTime"]) > 0.0)
diff --git a/lldb/test/API/functionalities/stats_api/arm64-minidump-build-ids.yaml b/lldb/test/API/functionalities/stats_api/arm64-minidump-build-ids.yaml
new file mode 100644
index 000000000000..4acbc409d808
--- /dev/null
+++ b/lldb/test/API/functionalities/stats_api/arm64-minidump-build-ids.yaml
@@ -0,0 +1,19 @@
+--- !minidump
+Streams:
+ - Type: SystemInfo
+ Processor Arch: ARM
+ Platform ID: Linux
+ CSD Version: '15E216'
+ CPU:
+ CPUID: 0x00000000
+ - Type: ModuleList
+ Modules:
+ - Base of Image: 0x0000000000001000
+ Size of Image: 0x00001000
+ Module Name: '/tmp/a'
+ CodeView Record: 4C4570420102030405060708090A0B0C0D0E0F1011121314
+ - Base of Image: 0x0000000000001000
+ Size of Image: 0x00001000
+ Module Name: '/tmp/b'
+ CodeView Record: 4C4570420A141E28323C46505A646E78828C96A0AAB4BEC8
+...
diff --git a/lldb/test/API/functionalities/thread/step_out_line0/Makefile b/lldb/test/API/functionalities/thread/step_out_line0/Makefile
new file mode 100644
index 000000000000..10495940055b
--- /dev/null
+++ b/lldb/test/API/functionalities/thread/step_out_line0/Makefile
@@ -0,0 +1,3 @@
+C_SOURCES := main.c
+
+include Makefile.rules
diff --git a/lldb/test/API/functionalities/thread/step_out_line0/TestThreadStepOutLine0.py b/lldb/test/API/functionalities/thread/step_out_line0/TestThreadStepOutLine0.py
new file mode 100644
index 000000000000..2707ca852f66
--- /dev/null
+++ b/lldb/test/API/functionalities/thread/step_out_line0/TestThreadStepOutLine0.py
@@ -0,0 +1,35 @@
+"""
+Test stepping out of a function when the return location is an unsuitable
+stopping point.
+"""
+
+
+import lldb
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
+
+
+class ThreadStepOutLine0TestCase(TestBase):
+ def test(self):
+ self.build()
+ target, process, thread, _ = lldbutil.run_to_source_breakpoint(
+ self, "// Set breakpoint here", lldb.SBFileSpec("main.c")
+ )
+ correct_stepped_out_line = line_number("main.c", "// Should stop here")
+ return_statement_line = line_number("main.c", "// Ran too far")
+ safety_bp = target.BreakpointCreateByLocation(
+ lldb.SBFileSpec("main.c"), return_statement_line
+ )
+ self.assertTrue(safety_bp.IsValid())
+
+ error = lldb.SBError()
+ thread.StepOut(error)
+ self.assertTrue(error.Success())
+
+ frame = thread.GetSelectedFrame()
+ self.assertEqual(
+ frame.line_entry.GetLine(),
+ correct_stepped_out_line,
+ "Step-out lost control of execution, ran too far",
+ )
diff --git a/lldb/test/API/functionalities/thread/step_out_line0/main.c b/lldb/test/API/functionalities/thread/step_out_line0/main.c
new file mode 100644
index 000000000000..ad0c1c05d695
--- /dev/null
+++ b/lldb/test/API/functionalities/thread/step_out_line0/main.c
@@ -0,0 +1,11 @@
+int step_out_of_here(int a) {
+ return a + 5; // Set breakpoint here
+}
+
+int main() {
+#line 0
+ int v = step_out_of_here(3) + 7;
+#line 9
+ v += 11; // Should stop here
+ return v; // Ran too far
+}
diff --git a/lldb/test/API/functionalities/unwind/cortex-m-exception/TestCortexMExceptionUnwind.py b/lldb/test/API/functionalities/unwind/cortex-m-exception/TestCortexMExceptionUnwind.py
index 768dd6fe6867..50ea17370524 100644
--- a/lldb/test/API/functionalities/unwind/cortex-m-exception/TestCortexMExceptionUnwind.py
+++ b/lldb/test/API/functionalities/unwind/cortex-m-exception/TestCortexMExceptionUnwind.py
@@ -12,21 +12,7 @@ from lldbsuite.test import lldbutil
class TestCortexMExceptionUnwind(TestBase):
NO_DEBUG_INFO_TESTCASE = True
- # on the lldb-remote-linux-ubuntu CI, the binary.json's triple of
- # armv7m-apple is not being set in the Target triple, and we're
- # picking the wrong ABI plugin, ABISysV_arm.
- # ABISysV_arm::CreateDefaultUnwindPlan() doesn't have a way to detect
- # arm/thumb for a stack frame, or even the Target's triple for a
- # Cortex-M part that is always thumb. It hardcodes r11 as the frame
- # pointer register, which is correct for arm code but not thumb.
- # It is never correct # on a Cortex-M target.
- # The Darwin ABIMacOSX_arm diverges from AAPCS and always uses r7 for
- # the frame pointer -- the thumb convention -- whether executing arm or
- # thumb. So its CreateDefaultUnwindPlan picks the correct register for
- # the frame pointer, and we can walk the stack.
- # ABISysV_arm::CreateDefaultUnwindPlan will only get one frame and
- # not be able to continue.
- @skipIfRemote
+ @skipIfLLVMTargetMissing("ARM")
def test_no_fpu(self):
"""Test that we can backtrace correctly through an ARM Cortex-M Exception return stack"""
@@ -42,6 +28,9 @@ class TestCortexMExceptionUnwind(TestBase):
core = self.getBuildArtifact("core")
self.yaml2macho_core("armv7m-nofpu-exception.yaml", core, exe_uuid)
+ if self.TraceOn():
+ self.runCmd("log enable lldb unwind")
+
process = target.LoadCore(core)
self.assertTrue(process.IsValid())
@@ -55,14 +44,9 @@ class TestCortexMExceptionUnwind(TestBase):
thread = process.GetThreadAtIndex(0)
self.assertTrue(thread.IsValid())
- # We have 4 named stack frames and two unnamed
- # frames above that. The topmost two stack frames
- # were not interesting for this test, so I didn't
- # create symbols for them.
- self.assertEqual(thread.GetNumFrames(), 6)
+ self.assertEqual(thread.GetNumFrames(), 3)
stackframe_names = [
"exception_catcher",
- "exception_catcher",
"exception_thrower",
"main",
]
diff --git a/lldb/test/API/functionalities/unwind/cortex-m-exception/armv7m-nofpu-exception.yaml b/lldb/test/API/functionalities/unwind/cortex-m-exception/armv7m-nofpu-exception.yaml
index 9ce5ff49d9b6..0b4e1f8fac3e 100644
--- a/lldb/test/API/functionalities/unwind/cortex-m-exception/armv7m-nofpu-exception.yaml
+++ b/lldb/test/API/functionalities/unwind/cortex-m-exception/armv7m-nofpu-exception.yaml
@@ -2,8 +2,8 @@ cpu: armv7m
threads:
- regsets:
- flavor: gpr
- registers: [{name: sp, value: 0x2000fe70}, {name: r7, value: 0x2000fe80},
- {name: pc, value: 0x0020392c}, {name: lr, value: 0x0020392d}]
+ registers: [{name: sp, value: 0x2000fe88}, {name: r7, value: 0x2000fe88},
+ {name: pc, value: 0x00203916}, {name: lr, value: 0x0020392d}]
memory-regions:
# stack memory fetched via
# (lldb) p/x $sp
@@ -14,7 +14,7 @@ memory-regions:
0x0000002a, 0x20010e58, 0x00203923, 0x00000001,
0x2000fe88, 0x00203911, 0x2000ffdc, 0xfffffff9,
0x00000102, 0x00000002, 0x000003f0, 0x0000002a,
- 0x20012620, 0x00203215, 0x00203366, 0x81000200,
+ 0x20012620, 0x00203215, 0x00202a92, 0x81000200,
0x00203215, 0x200128b0, 0x0024928d, 0x2000fecc,
0x002491ed, 0x20010e58, 0x20010e4c, 0x2000ffa0,
0x200107a0, 0x0000003c, 0x200116e8, 0x200108b0,
@@ -62,3 +62,26 @@ memory-regions:
0x98, 0xae, 0x28, 0x00
]
+ # exception_thrower
+ # (lldb) disass -b -c 12 -n exception_thrower
+ # 0x202a88 <+0>: 0xb5f0 push {r4, r5, r6, r7, lr}
+ # 0x202a8a <+2>: 0xaf03 add r7, sp, #0xc
+ # 0x202a8c <+4>: 0xe92d0f00 push.w {r8, r9, r10, r11}
+ # 0x202a90 <+8>: 0xb0c3 sub sp, #0x10c
+ # 0x202a92 <+10>: 0xf7ffffd9 bl 0x202a48
+ - addr: 0x202a88
+ UInt8: [
+ 0xf0, 0xb5, 0x03, 0xaf, 0x2d, 0xe9, 0x00, 0x0f,
+ 0xc3, 0xb0, 0xff, 0xf7, 0xd9, 0xff, 0xff, 0xf7
+ ]
+
+ # main:
+ # 0x202a7e <+0>: push {r7, lr}
+ # 0x202a80 <+2>: mov r7, sp
+ # 0x202a82 <+4>: bl 0x202a88 ; exception_thrower
+ # 0x202a86 <+8>: nop
+ - addr: 0x202a7e
+ UInt8: [
+ 0x80, 0xb5, 0x6f, 0x46, 0x00, 0xf0, 0x01, 0xf8,
+ 0x00, 0xbf
+ ]
diff --git a/lldb/test/API/functionalities/unwind/cortex-m-exception/binary.json b/lldb/test/API/functionalities/unwind/cortex-m-exception/binary.json
index 8fcd5307ff82..0de0169f7adb 100644
--- a/lldb/test/API/functionalities/unwind/cortex-m-exception/binary.json
+++ b/lldb/test/API/functionalities/unwind/cortex-m-exception/binary.json
@@ -1,5 +1,5 @@
{
- "triple": "armv7m-apple",
+ "triple": "armv7m--",
"uuid": "2D157DBA-53C9-3AC7-B5A1-9D336EC831CB",
"type": "executable",
"sections": [
@@ -28,13 +28,13 @@
{
"name": "exception_catcher",
"type": "code",
- "size": 44,
+ "size": 32,
"address": 2111760
},
{
"name": "exception_thrower",
"type": "code",
- "size": 2652,
+ "size": 16,
"address": 2108040
}
]
diff --git a/lldb/test/API/lang/cpp/abi_tag_structors/TestAbiTagStructors.py b/lldb/test/API/lang/cpp/abi_tag_structors/TestAbiTagStructors.py
index 87d8adb42b82..2d3e4f7cdd47 100644
--- a/lldb/test/API/lang/cpp/abi_tag_structors/TestAbiTagStructors.py
+++ b/lldb/test/API/lang/cpp/abi_tag_structors/TestAbiTagStructors.py
@@ -10,6 +10,11 @@ from lldbsuite.test import lldbutil
class AbiTagStructorsTestCase(TestBase):
+ @skipIf(
+ compiler="clang",
+ compiler_version=["<", "22"],
+ bugnumber="Required Clang flag not supported",
+ )
@expectedFailureAll(oslist=["windows"])
def test_with_structor_linkage_names(self):
self.build(dictionary={"CXXFLAGS_EXTRAS": "-gstructor-decl-linkage-names"})
@@ -73,7 +78,16 @@ class AbiTagStructorsTestCase(TestBase):
Test that without linkage names on structor declarations we can't call
ABI-tagged structors.
"""
- self.build(dictionary={"CXXFLAGS_EXTRAS": "-gno-structor-decl-linkage-names"})
+ # In older versions of Clang the -gno-structor-decl-linkage-names
+ # behaviour was the default.
+ if self.expectedCompiler(["clang"]) and self.expectedCompilerVersion(
+ [">=", "22.0"]
+ ):
+ self.build(
+ dictionary={"CXXFLAGS_EXTRAS": "-gno-structor-decl-linkage-names"}
+ )
+ else:
+ self.build()
lldbutil.run_to_source_breakpoint(
self, "Break here", lldb.SBFileSpec("main.cpp", False)
@@ -105,12 +119,23 @@ class AbiTagStructorsTestCase(TestBase):
"expression TaggedLocal()", error=True, substrs=["Couldn't look up symbols"]
)
+ @skipIf(compiler="clang", compiler_version=["<", "22"])
@expectedFailureAll(oslist=["windows"])
- def test_nested_no_structor_linkage_names(self):
+ def test_nested_with_structor_linkage_names(self):
self.build(dictionary={"CXXFLAGS_EXTRAS": "-gstructor-decl-linkage-names"})
self.do_nested_structor_test()
@expectedFailureAll(oslist=["windows"])
- def test_nested_with_structor_linkage_names(self):
- self.build(dictionary={"CXXFLAGS_EXTRAS": "-gno-structor-decl-linkage-names"})
+ def test_nested_no_structor_linkage_names(self):
+ # In older versions of Clang the -gno-structor-decl-linkage-names
+ # behaviour was the default.
+ if self.expectedCompiler(["clang"]) and self.expectedCompilerVersion(
+ [">=", "22.0"]
+ ):
+ self.build(
+ dictionary={"CXXFLAGS_EXTRAS": "-gno-structor-decl-linkage-names"}
+ )
+ else:
+ self.build()
+
self.do_nested_structor_test()
diff --git a/lldb/test/API/lang/cpp/expr-definition-in-dylib/TestExprDefinitionInDylib.py b/lldb/test/API/lang/cpp/expr-definition-in-dylib/TestExprDefinitionInDylib.py
index c0545c70c84e..b3bed43c7587 100644
--- a/lldb/test/API/lang/cpp/expr-definition-in-dylib/TestExprDefinitionInDylib.py
+++ b/lldb/test/API/lang/cpp/expr-definition-in-dylib/TestExprDefinitionInDylib.py
@@ -6,6 +6,11 @@ from lldbsuite.test import lldbutil
class ExprDefinitionInDylibTestCase(TestBase):
+ @skipIf(
+ compiler="clang",
+ compiler_version=["<", "22"],
+ bugnumber="Required Clang flag not supported",
+ )
@skipIfWindows
def test_with_structor_linkage_names(self):
"""
@@ -74,7 +79,16 @@ class ExprDefinitionInDylibTestCase(TestBase):
Tests that if structor declarations don't have linkage names, we can't
call ABI-tagged constructors. But non-tagged ones are fine.
"""
- self.build(dictionary={"CXXFLAGS_EXTRAS": "-gno-structor-decl-linkage-names"})
+ # In older versions of Clang the -gno-structor-decl-linkage-names
+ # behaviour was the default.
+ if self.expectedCompiler(["clang"]) and self.expectedCompilerVersion(
+ [">=", "22.0"]
+ ):
+ self.build(
+ dictionary={"CXXFLAGS_EXTRAS": "-gno-structor-decl-linkage-names"}
+ )
+ else:
+ self.build()
target = self.dbg.CreateTarget(self.getBuildArtifact("a.out"))
self.assertTrue(target, VALID_TARGET)
@@ -95,6 +109,6 @@ class ExprDefinitionInDylibTestCase(TestBase):
self.expect_expr("Foo(10)", result_type="Foo")
- self.expect("Base()", error=True)
+ self.expect("expr Base()", error=True)
- self.expect("Bar()", error=True)
+ self.expect("expr Bar()", error=True)
diff --git a/lldb/test/API/lang/cpp/floating-types-specialization/Makefile b/lldb/test/API/lang/cpp/floating-types-specialization/Makefile
new file mode 100644
index 000000000000..99998b20bcb0
--- /dev/null
+++ b/lldb/test/API/lang/cpp/floating-types-specialization/Makefile
@@ -0,0 +1,3 @@
+CXX_SOURCES := main.cpp
+
+include Makefile.rules
diff --git a/lldb/test/API/lang/cpp/floating-types-specialization/TestCppFloatingTypesSpecialization.py b/lldb/test/API/lang/cpp/floating-types-specialization/TestCppFloatingTypesSpecialization.py
new file mode 100644
index 000000000000..979391f3681f
--- /dev/null
+++ b/lldb/test/API/lang/cpp/floating-types-specialization/TestCppFloatingTypesSpecialization.py
@@ -0,0 +1,37 @@
+import lldb
+import lldbsuite.test.lldbplatformutil as lldbplatformutil
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
+
+
+class TestCase(TestBase):
+ @skipIf(compiler="clang", compiler_version=["<", "17.0"])
+ def test(self):
+ self.build()
+ lldbutil.run_to_source_breakpoint(
+ self, "// break here", lldb.SBFileSpec("main.cpp", False)
+ )
+
+ # On 32-bit Arm, you have to have the bfloat16 extension, or an FPU while
+ # not using the soft float mode. The target we assume has none of that
+ # so instead of __bf16 we get __fp16.
+ is_arm_32_bit = lldbplatformutil.getArchitecture() == "arm"
+
+ self.expect_expr(
+ "f0", result_type=("Foo<__fp16>" if is_arm_32_bit else "Foo<__bf16>")
+ )
+
+ # When __bf16 is actually __fp16, f1 looks like it inherits from itself.
+ # Which clang allows but LLDB fails to evaluate.
+ if not is_arm_32_bit:
+ self.expect_expr("f1", result_type="Foo<__fp16>")
+
+ # Test sizeof to ensure while computing layout we don't do
+ # infinite recursion.
+ v = self.frame().EvaluateExpression("sizeof(f0)")
+ self.assertEqual(v.GetValueAsUnsigned() > 0, True)
+
+ if not is_arm_32_bit:
+ v = self.frame().EvaluateExpression("sizeof(f1)")
+ self.assertEqual(v.GetValueAsUnsigned() > 0, True)
diff --git a/lldb/test/API/lang/cpp/floating-types-specialization/main.cpp b/lldb/test/API/lang/cpp/floating-types-specialization/main.cpp
new file mode 100644
index 000000000000..e3e8a3767fef
--- /dev/null
+++ b/lldb/test/API/lang/cpp/floating-types-specialization/main.cpp
@@ -0,0 +1,11 @@
+template <typename T> struct Foo;
+
+template <> struct Foo<__bf16> {};
+
+template <> struct Foo<_Float16> : Foo<__bf16> {};
+
+int main() {
+ Foo<__bf16> f0;
+ Foo<_Float16> f1;
+ return 0; // break here
+}
diff --git a/lldb/test/API/lang/cpp/function-call-from-object-file/Makefile b/lldb/test/API/lang/cpp/function-call-from-object-file/Makefile
new file mode 100644
index 000000000000..285bbfbbca4f
--- /dev/null
+++ b/lldb/test/API/lang/cpp/function-call-from-object-file/Makefile
@@ -0,0 +1,3 @@
+CXX_SOURCES := main.cpp lib1.cpp lib2.cpp
+
+include Makefile.rules
diff --git a/lldb/test/API/lang/cpp/function-call-from-object-file/TestFunctionCallFromObjectFile.py b/lldb/test/API/lang/cpp/function-call-from-object-file/TestFunctionCallFromObjectFile.py
new file mode 100644
index 000000000000..f0a7aef182a6
--- /dev/null
+++ b/lldb/test/API/lang/cpp/function-call-from-object-file/TestFunctionCallFromObjectFile.py
@@ -0,0 +1,29 @@
+"""
+Tests that we can call functions that have definitions in multiple
+CUs in the debug-info (which is the case for functions defined in headers).
+The linker will most likely de-duplicate the functiond definitions when linking
+the final executable. On Darwin, this will create a debug-map that LLDB will use
+to fix up object file addresses to addresses in the linked executable. However,
+if we parsed the DIE from the object file whose functiond definition got stripped
+by the linker, LLDB needs to ensure it can still resolve the function symbol it
+got for it.
+"""
+
+import lldb
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
+
+
+class TestFunctionCallFromObjectFile(TestBase):
+ def test_lib1(self):
+ self.build()
+ lldbutil.run_to_name_breakpoint(self, "lib1_func")
+
+ self.expect_expr("Foo{}.foo()", result_type="int", result_value="15")
+
+ def test_lib2(self):
+ self.build()
+ lldbutil.run_to_name_breakpoint(self, "lib2_func")
+
+ self.expect_expr("Foo{}.foo()", result_type="int", result_value="15")
diff --git a/lldb/test/API/lang/cpp/function-call-from-object-file/common.h b/lldb/test/API/lang/cpp/function-call-from-object-file/common.h
new file mode 100644
index 000000000000..76e23be6b97a
--- /dev/null
+++ b/lldb/test/API/lang/cpp/function-call-from-object-file/common.h
@@ -0,0 +1,8 @@
+#ifndef COMMON_H_IN
+#define COMMON_H_IN
+
+struct Foo {
+ int foo() { return 15; }
+};
+
+#endif // COMMON_H_IN
diff --git a/lldb/test/API/lang/cpp/function-call-from-object-file/lib1.cpp b/lldb/test/API/lang/cpp/function-call-from-object-file/lib1.cpp
new file mode 100644
index 000000000000..b97bcc1b712b
--- /dev/null
+++ b/lldb/test/API/lang/cpp/function-call-from-object-file/lib1.cpp
@@ -0,0 +1,8 @@
+#include "common.h"
+
+// Parameter "Foo*" forces LLDB to parse "Foo" from the object
+// file that it is stopped in.
+void lib1_func(Foo *) {
+ // Force definition into lib1.o debug-info.
+ Foo{}.foo();
+}
diff --git a/lldb/test/API/lang/cpp/function-call-from-object-file/lib2.cpp b/lldb/test/API/lang/cpp/function-call-from-object-file/lib2.cpp
new file mode 100644
index 000000000000..2f9d81a8bdf4
--- /dev/null
+++ b/lldb/test/API/lang/cpp/function-call-from-object-file/lib2.cpp
@@ -0,0 +1,6 @@
+#include "common.h"
+
+void lib2_func(Foo *) {
+ // Force definition into lib2.o debug-info.
+ Foo{}.foo();
+}
diff --git a/lldb/test/API/lang/cpp/function-call-from-object-file/main.cpp b/lldb/test/API/lang/cpp/function-call-from-object-file/main.cpp
new file mode 100644
index 000000000000..61ca798daf1d
--- /dev/null
+++ b/lldb/test/API/lang/cpp/function-call-from-object-file/main.cpp
@@ -0,0 +1,10 @@
+struct Foo;
+
+extern void lib1_func(Foo *);
+extern void lib2_func(Foo *);
+
+int main() {
+ lib1_func(nullptr);
+ lib2_func(nullptr);
+ return 0;
+}
diff --git a/lldb/test/API/lang/cpp/structured-binding/TestStructuredBinding.py b/lldb/test/API/lang/cpp/structured-binding/TestStructuredBinding.py
index 5f939ecfbef2..882c91d1ce8c 100644
--- a/lldb/test/API/lang/cpp/structured-binding/TestStructuredBinding.py
+++ b/lldb/test/API/lang/cpp/structured-binding/TestStructuredBinding.py
@@ -99,16 +99,21 @@ class TestStructuredBinding(TestBase):
self.expect_expr("ty2", result_value="'z'")
self.expect_expr("tz2", result_value="10")
- self.expect(
- "frame variable",
- substrs=[
- "tx1 =",
- "ty1 =",
- "tz1 =",
- "tx2 =",
- "ty2 =",
- "tz2 =",
- "mp1 =",
- "mp2 =",
- ],
- )
+ # Older versions of Clang marked structured binding variables
+ # as artificial, and thus LLDB wouldn't display them.
+ if self.expectedCompiler(["clang"]) and self.expectedCompilerVersion(
+ [">=", "22.0"]
+ ):
+ self.expect(
+ "frame variable",
+ substrs=[
+ "tx1 =",
+ "ty1 =",
+ "tz1 =",
+ "tx2 =",
+ "ty2 =",
+ "tz2 =",
+ "mp1 =",
+ "mp2 =",
+ ],
+ )
diff --git a/lldb/test/API/lang/cpp/template-arguments/TestCppTemplateArguments.py b/lldb/test/API/lang/cpp/template-arguments/TestCppTemplateArguments.py
index eac7b5ef1099..83c057220410 100644
--- a/lldb/test/API/lang/cpp/template-arguments/TestCppTemplateArguments.py
+++ b/lldb/test/API/lang/cpp/template-arguments/TestCppTemplateArguments.py
@@ -1,4 +1,5 @@
import lldb
+import lldbsuite.test.lldbplatformutil as lldbplatformutil
from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
from lldbsuite.test import lldbutil
@@ -82,8 +83,12 @@ class TestCase(TestBase):
value = self.expect_expr("temp7", result_type="Foo<__fp16, __fp16>")
self.assertFalse(value.GetType().GetTemplateArgumentValue(target, 1))
- value = self.expect_expr("temp8", result_type="Foo<__fp16, __fp16>")
- self.assertFalse(value.GetType().GetTemplateArgumentValue(target, 1))
+ # The target we use when evaluating these expressions for Arm leads to there
+ # not being a __bf16 type in the AST so we fall back to __fp16 and evaluating
+ # this fails.
+ if lldbplatformutil.getArchitecture() != "arm":
+ value = self.expect_expr("temp8", result_type="Foo<__bf16, __bf16>")
+ self.assertFalse(value.GetType().GetTemplateArgumentValue(target, 1))
value = self.expect_expr("temp9", result_type="Bar<double, 1.200000e+00>")
template_param_value = value.GetType().GetTemplateArgumentValue(target, 1)
diff --git a/lldb/test/API/lang/objc/ivar-in-framework-base/Makefile b/lldb/test/API/lang/objc/ivar-in-framework-base/Makefile
new file mode 100644
index 000000000000..c7947fc138c1
--- /dev/null
+++ b/lldb/test/API/lang/objc/ivar-in-framework-base/Makefile
@@ -0,0 +1,6 @@
+OBJC_SOURCES := main.m lib.m
+LD_EXTRAS = -framework Foundation
+
+include Makefile.rules
+
+lib.o: CFLAGS = $(CFLAGS_NO_DEBUG)
diff --git a/lldb/test/API/lang/objc/ivar-in-framework-base/TestIvarInFrameworkBase.py b/lldb/test/API/lang/objc/ivar-in-framework-base/TestIvarInFrameworkBase.py
new file mode 100644
index 000000000000..40fc6b7a6899
--- /dev/null
+++ b/lldb/test/API/lang/objc/ivar-in-framework-base/TestIvarInFrameworkBase.py
@@ -0,0 +1,39 @@
+import lldb
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
+
+
+class TestIvarInFrameworkBase(TestBase):
+ """
+ Tests whether LLDB's data inspection commands can correctly retrieve
+ information about ivars from the Objective-C runtime.
+ In this test-case we have a base class type for which we don't have access
+ to the debug-info of the implementation (mimicking the scenario of subclassing
+ a type from a system framework). LLDB won't be able to see the backing ivar for
+ 'fooProp' from just debug-info, but it will fall back on the runtime to get the
+ necessary information.
+ """
+
+ def test_frame_var(self):
+ self.build()
+ lldbutil.run_to_source_breakpoint(self, "break here", lldb.SBFileSpec("main.m"))
+ self.expect("frame variable *bar", substrs=["_fooProp = 10", "_barProp = 15"])
+
+ def test_expr(self):
+ self.build()
+ lldbutil.run_to_source_breakpoint(self, "break here", lldb.SBFileSpec("main.m"))
+ self.expect_expr(
+ "*bar",
+ result_type="Bar",
+ result_children=[
+ ValueCheck(
+ name="Foo",
+ children=[
+ ValueCheck(name="NSObject"),
+ ValueCheck(name="_fooProp", value="10"),
+ ],
+ ),
+ ValueCheck(name="_barProp", value="15"),
+ ],
+ )
diff --git a/lldb/test/API/lang/objc/ivar-in-framework-base/lib.h b/lldb/test/API/lang/objc/ivar-in-framework-base/lib.h
new file mode 100644
index 000000000000..31ceb53dc688
--- /dev/null
+++ b/lldb/test/API/lang/objc/ivar-in-framework-base/lib.h
@@ -0,0 +1,6 @@
+#import <Foundation/Foundation.h>
+
+@interface Foo : NSObject
+@property int fooProp;
+- (id)init;
+@end
diff --git a/lldb/test/API/lang/objc/ivar-in-framework-base/lib.m b/lldb/test/API/lang/objc/ivar-in-framework-base/lib.m
new file mode 100644
index 000000000000..e1bf80ac4bd4
--- /dev/null
+++ b/lldb/test/API/lang/objc/ivar-in-framework-base/lib.m
@@ -0,0 +1,8 @@
+#import "lib.h"
+
+@implementation Foo
+- (id)init {
+ self.fooProp = 10;
+ return self;
+}
+@end
diff --git a/lldb/test/API/lang/objc/ivar-in-framework-base/main.m b/lldb/test/API/lang/objc/ivar-in-framework-base/main.m
new file mode 100644
index 000000000000..1fd352ec92c5
--- /dev/null
+++ b/lldb/test/API/lang/objc/ivar-in-framework-base/main.m
@@ -0,0 +1,22 @@
+#import "lib.h"
+#include <stdio.h>
+
+@interface Bar : Foo
+@property int barProp;
+- (id)init;
+@end
+
+@implementation Bar
+
+- (id)init {
+ self = [super init];
+ self.barProp = 15;
+ return self;
+}
+@end
+
+int main() {
+ Bar *bar = [Bar new];
+ puts("break here");
+ return 0;
+}
diff --git a/lldb/test/API/macosx/debugserver-multimemread/Makefile b/lldb/test/API/macosx/debugserver-multimemread/Makefile
new file mode 100644
index 000000000000..10495940055b
--- /dev/null
+++ b/lldb/test/API/macosx/debugserver-multimemread/Makefile
@@ -0,0 +1,3 @@
+C_SOURCES := main.c
+
+include Makefile.rules
diff --git a/lldb/test/API/macosx/debugserver-multimemread/TestDebugserverMultiMemRead.py b/lldb/test/API/macosx/debugserver-multimemread/TestDebugserverMultiMemRead.py
new file mode 100644
index 000000000000..6caa5f85c284
--- /dev/null
+++ b/lldb/test/API/macosx/debugserver-multimemread/TestDebugserverMultiMemRead.py
@@ -0,0 +1,102 @@
+"""
+Tests debugserver support for MultiMemRead.
+"""
+
+import lldb
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
+
+
+@skipUnlessDarwin
+@skipIfOutOfTreeDebugserver
+class TestCase(TestBase):
+ def send_process_packet(self, packet_str):
+ self.runCmd(f"proc plugin packet send {packet_str}", check=False)
+ # The output is of the form:
+ # packet: <packet_str>
+ # response: <response>
+ reply = self.res.GetOutput().split("\n")
+ packet = reply[0].strip()
+ response = reply[1].strip()
+
+ self.assertTrue(packet.startswith("packet: "))
+ self.assertTrue(response.startswith("response: "))
+ return response[len("response: ") :]
+
+ def check_invalid_packet(self, packet_str):
+ reply = self.send_process_packet("packet_str")
+ self.assertEqual(reply, "E03")
+
+ def test_packets(self):
+ self.build()
+ source_file = lldb.SBFileSpec("main.c")
+ target, process, thread, bkpt = lldbutil.run_to_source_breakpoint(
+ self, "break here", source_file
+ )
+
+ reply = self.send_process_packet("qSupported")
+ self.assertIn("MultiMemRead+", reply)
+
+ mem_address_var = thread.frames[0].FindVariable("memory")
+ self.assertTrue(mem_address_var)
+ mem_address = mem_address_var.GetValueAsUnsigned() + 42
+
+ # no ":"
+ self.check_invalid_packet("MultiMemRead")
+ # missing ranges
+ self.check_invalid_packet("MultiMemRead:")
+ # needs at least one range
+ self.check_invalid_packet("MultiMemRead:ranges:")
+ # needs at least one range
+ self.check_invalid_packet("MultiMemRead:ranges:,")
+ # a range is a pair of numbers
+ self.check_invalid_packet("MultiMemRead:ranges:10")
+ # a range is a pair of numbers
+ self.check_invalid_packet("MultiMemRead:ranges:10,")
+ # range list must end with ;
+ self.check_invalid_packet("MultiMemRead:ranges:10,2")
+ self.check_invalid_packet("MultiMemRead:ranges:10,2,")
+ self.check_invalid_packet("MultiMemRead:ranges:10,2,3")
+ # ranges are pairs of numbers.
+ self.check_invalid_packet("MultiMemRead:ranges:10,2,3;")
+ # unrecognized field
+ self.check_invalid_packet("MultiMemRead:ranges:10,2;blah:;")
+ # unrecognized field
+ self.check_invalid_packet("MultiMemRead:blah:;ranges:10,2;")
+
+ # Zero-length reads are ok.
+ reply = self.send_process_packet("MultiMemRead:ranges:0,0;")
+ self.assertEqual(reply, "0;")
+
+ # Debugserver is permissive with trailing commas.
+ reply = self.send_process_packet("MultiMemRead:ranges:10,2,;")
+ self.assertEqual(reply, "0;")
+ reply = self.send_process_packet(f"MultiMemRead:ranges:{mem_address:x},2,;")
+ self.assertEqual(reply, "2;ab")
+
+ reply = self.send_process_packet("MultiMemRead:ranges:10,2;")
+ self.assertEqual(reply, "0;")
+ reply = self.send_process_packet(f"MultiMemRead:ranges:{mem_address:x},0;")
+ self.assertEqual(reply, "0;")
+ reply = self.send_process_packet(f"MultiMemRead:ranges:{mem_address:x},2;")
+ self.assertEqual(reply, "2;ab")
+ reply = self.send_process_packet(
+ f"MultiMemRead:ranges:{mem_address:x},2,{mem_address+2:x},4;"
+ )
+ self.assertEqual(reply, "2,4;abcdef")
+ reply = self.send_process_packet(
+ f"MultiMemRead:ranges:{mem_address:x},2,{mem_address+2:x},4,{mem_address+6:x},8;"
+ )
+ self.assertEqual(reply, "2,4,8;abcdefghijklmn")
+
+ # Test zero length in the middle.
+ reply = self.send_process_packet(
+ f"MultiMemRead:ranges:{mem_address:x},2,{mem_address+2:x},0,{mem_address+6:x},8;"
+ )
+ self.assertEqual(reply, "2,0,8;abghijklmn")
+ # Test zero length in the end.
+ reply = self.send_process_packet(
+ f"MultiMemRead:ranges:{mem_address:x},2,{mem_address+2:x},4,{mem_address+6:x},0;"
+ )
+ self.assertEqual(reply, "2,4,0;abcdef")
diff --git a/lldb/test/API/macosx/debugserver-multimemread/main.c b/lldb/test/API/macosx/debugserver-multimemread/main.c
new file mode 100644
index 000000000000..44cdd475b550
--- /dev/null
+++ b/lldb/test/API/macosx/debugserver-multimemread/main.c
@@ -0,0 +1,14 @@
+#include <stdlib.h>
+#include <string.h>
+
+int main(int argc, char **argv) {
+ char *memory = malloc(1024);
+ memset(memory, '-', 1024);
+ // Write "interesting" characters at an offset from the memory filled with
+ // `-`. This way, if we read outside the range in either direction, we should
+ // find `-`s`.
+ int offset = 42;
+ for (int i = offset; i < offset + 14; i++)
+ memory[i] = 'a' + (i - offset);
+ return 0; // break here
+}
diff --git a/lldb/test/API/macosx/mte/Makefile b/lldb/test/API/macosx/mte/Makefile
new file mode 100644
index 000000000000..d614e0f0a3bc
--- /dev/null
+++ b/lldb/test/API/macosx/mte/Makefile
@@ -0,0 +1,15 @@
+C_SOURCES := main.c
+
+EXE := uaf
+
+binary-plain: uaf
+binary-entitled: uaf sign
+
+all: binary-entitled
+
+include Makefile.rules
+
+sign: mte-entitlements.plist uaf
+ifeq ($(OS),Darwin)
+ codesign -s - -f --entitlements $^
+endif
diff --git a/lldb/test/API/macosx/mte/TestDarwinMTE.py b/lldb/test/API/macosx/mte/TestDarwinMTE.py
new file mode 100644
index 000000000000..a70b4b4aed26
--- /dev/null
+++ b/lldb/test/API/macosx/mte/TestDarwinMTE.py
@@ -0,0 +1,122 @@
+"""Test MTE Memory Tagging on Apple platforms"""
+
+import lldb
+import re
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
+import lldbsuite.test.cpu_feature as cpu_feature
+
+exe_name = "uaf" # Must match Makefile
+
+
+class TestDarwinMTE(TestBase):
+ NO_DEBUG_INFO_TESTCASE = True
+
+ @skipUnlessFeature(cpu_feature.AArch64.MTE)
+ def test_process_launch_memory_tagging(self):
+ self.build(make_targets=["binary-plain"])
+ self.createTestTarget(self.getBuildArtifact(exe_name))
+
+ self.expect("process launch", substrs=["exited with status = 0"])
+
+ self.expect(
+ "process launch --memory-tagging",
+ substrs=["stopped", "stop reason = EXC_ARM_MTE_TAG_FAULT"],
+ )
+
+ @skipUnlessFeature(cpu_feature.AArch64.MTE)
+ def test_tag_fault(self):
+ self.build()
+ exe = self.getBuildArtifact(exe_name)
+
+ target = self.dbg.CreateTarget(exe)
+ self.assertTrue(target, VALID_TARGET)
+
+ process = target.LaunchSimple(None, None, None)
+ self.assertState(process.GetState(), lldb.eStateStopped, PROCESS_STOPPED)
+
+ self.expect(
+ "thread info",
+ substrs=[
+ "stop reason = EXC_ARM_MTE_TAG_FAULT",
+ "MTE tag mismatch detected",
+ ],
+ )
+
+ @skipUnlessFeature(cpu_feature.AArch64.MTE)
+ def test_memory_region(self):
+ self.build()
+ lldbutil.run_to_source_breakpoint(
+ self, "// before free", lldb.SBFileSpec("main.c"), exe_name=exe_name
+ )
+
+ # (lldb) memory region ptr
+ # [0x00000001005ec000-0x00000001009ec000) rw-
+ # memory tagging: enabled
+ # Modified memory (dirty) page list provided, 2 entries.
+ # Dirty pages: 0x1005ec000, 0x1005fc000.
+ self.expect("memory region ptr", substrs=["memory tagging: enabled"])
+
+ @skipUnlessFeature(cpu_feature.AArch64.MTE)
+ def test_memory_read_show_tags(self):
+ self.build()
+ lldbutil.run_to_source_breakpoint(
+ self, "// before free", lldb.SBFileSpec("main.c"), exe_name=exe_name
+ )
+
+ # (lldb) memory read ptr-16 ptr+48 --show-tags
+ # 0x7d2c00930: 00 00 00 00 00 00 00 00 d0 e3 a5 0a 02 00 00 00 ................ (tag: 0x3)
+ # 0x7d2c00940: 48 65 6c 6c 6f 00 00 00 00 00 00 00 00 00 00 00 Hello........... (tag: 0xb)
+ # 0x7d2c00950: 57 6f 72 6c 64 00 00 00 00 00 00 00 00 00 00 00 World........... (tag: 0xb)
+ # 0x7d2c00960: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ (tag: 0x9)
+ self.expect(
+ "memory read ptr-16 ptr+48 --show-tags",
+ substrs=[" Hello...........", " World..........."],
+ patterns=[r"(.*\(tag: 0x[0-9a-f]\)\n){4}"],
+ )
+
+ def _parse_pointer_tag(self, output):
+ return re.search(r"Logical tag: (0x[0-9a-f])", output).group(1)
+
+ def _parse_memory_tags(self, output, expected_tag_count):
+ tags = re.findall(r"\): (0x[0-9a-f])", output)
+ self.assertEqual(len(tags), expected_tag_count)
+ return tags
+
+ @skipUnlessFeature(cpu_feature.AArch64.MTE)
+ def test_memory_tag_read(self):
+ self.build()
+ lldbutil.run_to_source_breakpoint(
+ self, "// before free", lldb.SBFileSpec("main.c"), exe_name=exe_name
+ )
+
+ # (lldb) memory tag read ptr-1 ptr+33
+ # Logical tag: 0x5
+ # Allocation tags:
+ # [0x100a65a40, 0x100a65a50): 0xf (mismatch)
+ # [0x100a65a50, 0x100a65a60): 0x5
+ # [0x100a65a60, 0x100a65a70): 0x5
+ # [0x100a65a70, 0x100a65a80): 0x2 (mismatch)
+ self.expect(
+ "memory tag read ptr-1 ptr+33",
+ substrs=["Logical tag: 0x", "Allocation tags:", "(mismatch)"],
+ patterns=[r"(\[.*\): 0x[0-9a-f].*\n){4}"],
+ )
+ output = self.res.GetOutput()
+ self.assertEqual(output.count("(mismatch)"), 2)
+ ptr_tag = self._parse_pointer_tag(output)
+ tags = self._parse_memory_tags(output, 4)
+ self.assertEqual(tags[1], ptr_tag)
+ self.assertEqual(tags[2], ptr_tag)
+ self.assertNotEqual(tags[0], ptr_tag) # Memory that comes before/after
+ self.assertNotEqual(tags[3], ptr_tag) # allocation has different tag.
+
+ # Continue running until MTE fault
+ self.expect("process continue", substrs=["stop reason = EXC_ARM_MTE_TAG_FAULT"])
+
+ self.runCmd("memory tag read ptr-1 ptr+33")
+ output = self.res.GetOutput()
+ self.assertEqual(output.count("(mismatch)"), 4)
+ tags = self._parse_memory_tags(output, 4)
+ self.assertTrue(all(t != ptr_tag for t in tags))
diff --git a/lldb/test/API/macosx/mte/main.c b/lldb/test/API/macosx/mte/main.c
new file mode 100644
index 000000000000..f9f6b1594ef4
--- /dev/null
+++ b/lldb/test/API/macosx/mte/main.c
@@ -0,0 +1,28 @@
+#include <malloc/malloc.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+// Produce some names on the trace
+const size_t tag_granule = 16;
+static uint8_t *my_malloc(void) { return malloc(2 * tag_granule); }
+static uint8_t *allocate(void) { return my_malloc(); }
+
+static void my_free(void *ptr) { free(ptr); }
+static void deallocate(void *ptr) { my_free(ptr); }
+
+static void touch_memory(uint8_t *ptr) { ptr[7] = 1; } // invalid access
+static void modify(uint8_t *ptr) { touch_memory(ptr); }
+
+int main() {
+ uint8_t *ptr = allocate();
+
+ strncpy((char *)ptr, "Hello", 16);
+ strncpy((char *)ptr + 16, "World", 16);
+
+ deallocate(ptr); // before free
+
+ modify(ptr); // use-after-free
+
+ return 0;
+}
diff --git a/lldb/test/API/macosx/mte/mte-entitlements.plist b/lldb/test/API/macosx/mte/mte-entitlements.plist
new file mode 100644
index 000000000000..6de5d5634d87
--- /dev/null
+++ b/lldb/test/API/macosx/mte/mte-entitlements.plist
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>com.apple.security.hardened-process</key>
+ <true/>
+ <key>com.apple.security.hardened-process.checked-allocations</key>
+ <true/>
+</dict>
+</plist>
diff --git a/lldb/test/API/python_api/debugger/TestDebuggerAPI.py b/lldb/test/API/python_api/debugger/TestDebuggerAPI.py
index 43f45f330ee2..44b118328801 100644
--- a/lldb/test/API/python_api/debugger/TestDebuggerAPI.py
+++ b/lldb/test/API/python_api/debugger/TestDebuggerAPI.py
@@ -294,3 +294,150 @@ class DebuggerAPITestCase(TestBase):
self.assertEqual(instance_str, class_str)
self.assertEqual(class_str, property_str)
+
+ def test_find_target_with_unique_id(self):
+ """Test SBDebugger.FindTargetByGloballyUniqueID() functionality."""
+
+ # Test with invalid ID - should return invalid target
+ invalid_target = self.dbg.FindTargetByGloballyUniqueID(999999)
+ self.assertFalse(invalid_target.IsValid())
+
+ # Test with ID 0 - should return invalid target
+ zero_target = self.dbg.FindTargetByGloballyUniqueID(0)
+ self.assertFalse(zero_target.IsValid())
+
+ # Build a real executable and create target with it
+ self.build()
+ exe = self.getBuildArtifact("a.out")
+ target = self.dbg.CreateTarget(exe)
+ self.assertTrue(target.IsValid())
+
+ # Find the target using its unique ID
+ unique_id = target.GetGloballyUniqueID()
+ self.assertNotEqual(unique_id, lldb.LLDB_INVALID_GLOBALLY_UNIQUE_TARGET_ID)
+ found_target = self.dbg.FindTargetByGloballyUniqueID(unique_id)
+ self.assertTrue(found_target.IsValid())
+ self.assertEqual(
+ self.dbg.GetIndexOfTarget(target), self.dbg.GetIndexOfTarget(found_target)
+ )
+ self.assertEqual(found_target.GetGloballyUniqueID(), unique_id)
+
+ def test_target_unique_id_uniqueness(self):
+ """Test that Target.GetGloballyUniqueID() returns unique values across multiple targets."""
+
+ # Create multiple targets and verify they all have unique IDs
+ self.build()
+ exe = self.getBuildArtifact("a.out")
+ targets = []
+ unique_ids = set()
+
+ for i in range(10):
+ target = self.dbg.CreateTarget(exe)
+ self.assertTrue(target.IsValid())
+
+ unique_id = target.GetGloballyUniqueID()
+ self.assertNotEqual(unique_id, 0)
+
+ # Verify this ID hasn't been used before
+ self.assertNotIn(
+ unique_id, unique_ids, f"Duplicate unique ID found: {unique_id}"
+ )
+
+ unique_ids.add(unique_id)
+ targets.append(target)
+
+ # Verify all targets can still be found by their IDs
+ for target in targets:
+ unique_id = target.GetGloballyUniqueID()
+ found = self.dbg.FindTargetByGloballyUniqueID(unique_id)
+ self.assertTrue(found.IsValid())
+ self.assertEqual(found.GetGloballyUniqueID(), unique_id)
+
+ def test_target_unique_id_uniqueness_after_deletion(self):
+ """Test finding targets have unique ID after target deletion."""
+ # Create two targets
+ self.build()
+ exe = self.getBuildArtifact("a.out")
+ target1 = self.dbg.CreateTarget(exe)
+ target2 = self.dbg.CreateTarget(exe)
+ self.assertTrue(target1.IsValid())
+ self.assertTrue(target2.IsValid())
+
+ unique_id1 = target1.GetGloballyUniqueID()
+ unique_id2 = target2.GetGloballyUniqueID()
+ self.assertNotEqual(unique_id1, 0)
+ self.assertNotEqual(unique_id2, 0)
+ self.assertNotEqual(unique_id1, unique_id2)
+
+ # Verify we can find them initially
+ found_target1 = self.dbg.FindTargetByGloballyUniqueID(unique_id1)
+ found_target2 = self.dbg.FindTargetByGloballyUniqueID(unique_id2)
+ self.assertTrue(found_target1.IsValid())
+ self.assertTrue(found_target2.IsValid())
+ target2_index = self.dbg.GetIndexOfTarget(target2)
+
+ # Delete target 2
+ deleted = self.dbg.DeleteTarget(target2)
+ self.assertTrue(deleted)
+
+ # Try to find the deleted target - should not be found
+ not_found_target = self.dbg.FindTargetByGloballyUniqueID(unique_id2)
+ self.assertFalse(not_found_target.IsValid())
+
+ # Create a new target
+ target3 = self.dbg.CreateTarget(exe)
+ self.assertTrue(target3.IsValid())
+ # Target list index of target3 should be the same as target2's
+ # since it was deleted, but it should have a distinct unique ID
+ target3_index = self.dbg.GetIndexOfTarget(target3)
+ unique_id3 = target3.GetGloballyUniqueID()
+ self.assertEqual(target3_index, target2_index)
+ self.assertNotEqual(unique_id3, unique_id2)
+ self.assertNotEqual(unique_id3, unique_id1)
+ # Make sure we can find the new target
+ found_target3 = self.dbg.FindTargetByGloballyUniqueID(
+ target3.GetGloballyUniqueID()
+ )
+ self.assertTrue(found_target3.IsValid())
+
+ def test_target_globally_unique_id_across_debuggers(self):
+ """Test that target IDs are globally unique across multiple debuggers."""
+ self.build()
+ exe = self.getBuildArtifact("a.out")
+
+ # Create two debuggers with targets each
+ debugger1 = lldb.SBDebugger.Create()
+ debugger2 = lldb.SBDebugger.Create()
+ self.addTearDownHook(lambda: lldb.SBDebugger.Destroy(debugger1))
+ self.addTearDownHook(lambda: lldb.SBDebugger.Destroy(debugger2))
+
+ # Create 2 targets per debugger
+ targets_d1 = [debugger1.CreateTarget(exe), debugger1.CreateTarget(exe)]
+ targets_d2 = [debugger2.CreateTarget(exe), debugger2.CreateTarget(exe)]
+ targets = targets_d1 + targets_d2
+
+ # Get all IDs and verify they're unique
+ ids = [target.GetGloballyUniqueID() for target in targets]
+ self.assertEqual(
+ len(set(ids)), len(ids), f"IDs should be globally unique: {ids}"
+ )
+ self.assertTrue(
+ all(uid != lldb.LLDB_INVALID_GLOBALLY_UNIQUE_TARGET_ID for uid in ids),
+ "All IDs should be valid",
+ )
+
+ # Verify targets can be found by their IDs in respective debuggers
+ for debugger, target_pair in [
+ (debugger1, targets[:2]),
+ (debugger2, targets[2:]),
+ ]:
+ for target in target_pair:
+ found = debugger.FindTargetByGloballyUniqueID(
+ target.GetGloballyUniqueID()
+ )
+ self.assertTrue(
+ found.IsValid(), "Target should be found by its unique ID"
+ )
+ self.assertEqual(
+ found.GetGloballyUniqueID(), target.GetGloballyUniqueID()
+ )
diff --git a/lldb/test/API/python_api/default-constructor/sb_filespec.py b/lldb/test/API/python_api/default-constructor/sb_filespec.py
index 4ab5c49c37eb..5dd78b1ace98 100644
--- a/lldb/test/API/python_api/default-constructor/sb_filespec.py
+++ b/lldb/test/API/python_api/default-constructor/sb_filespec.py
@@ -10,5 +10,5 @@ def fuzz_obj(obj):
obj.ResolveExecutableLocation()
obj.GetFilename()
obj.GetDirectory()
- obj.GetPath(None, 0)
+ obj.GetPath(1)
obj.GetDescription(lldb.SBStream())
diff --git a/lldb/test/API/python_api/interpreter/TestCommandInterpreterAPI.py b/lldb/test/API/python_api/interpreter/TestCommandInterpreterAPI.py
index 1029bdc3096d..01ed11a5a112 100644
--- a/lldb/test/API/python_api/interpreter/TestCommandInterpreterAPI.py
+++ b/lldb/test/API/python_api/interpreter/TestCommandInterpreterAPI.py
@@ -1,4 +1,4 @@
-"""Test the SBCommandInterpreter APIs."""
+"""tESt the SBCommandInterpreter APIs."""
import json
import lldb
@@ -156,13 +156,15 @@ class CommandInterpreterAPICase(TestBase):
self.assertEqual(transcript[0]["error"], "")
# (lldb) an-unknown-command
- self.assertEqual(transcript[1],
+ self.assertEqual(
+ transcript[1],
{
"command": "an-unknown-command",
# Unresolved commands don't have "commandName"/"commandArguments"
"output": "",
"error": "error: 'an-unknown-command' is not a valid command.\n",
- })
+ },
+ )
# (lldb) br s -f main.c -l <line>
self.assertEqual(transcript[2]["command"], "br s -f main.c -l %d" % self.line)
@@ -175,14 +177,17 @@ class CommandInterpreterAPICase(TestBase):
self.assertEqual(transcript[2]["error"], "")
# (lldb) p a
- self.assertEqual(transcript[3],
+ self.assertEqual(
+ transcript[3],
{
"command": "p a",
"commandName": "dwim-print",
"commandArguments": "-- a",
"output": "",
- "error": "error: <user expression 0>:1:1: use of undeclared identifier 'a'\n 1 | a\n | ^\n",
- })
+ "error": "note: Falling back to default language. Ran expression as 'Objective C++'.\n"
+ "error: <user expression 0>:1:1: use of undeclared identifier 'a'\n 1 | a\n | ^\n",
+ },
+ )
# (lldb) statistics dump
self.assertEqual(transcript[4]["command"], "statistics dump")
@@ -203,7 +208,10 @@ class CommandInterpreterAPICase(TestBase):
self.assertTrue(ci, VALID_COMMAND_INTERPRETER)
# The setting's default value should be "false"
- self.runCmd("settings show interpreter.save-transcript", "interpreter.save-transcript (boolean) = false\n")
+ self.runCmd(
+ "settings show interpreter.save-transcript",
+ "interpreter.save-transcript (boolean) = false\n",
+ )
def test_save_transcript_setting_off(self):
ci = self.dbg.GetCommandInterpreter()
@@ -250,17 +258,37 @@ class CommandInterpreterAPICase(TestBase):
structured_data_1 = ci.GetTranscript()
self.assertTrue(structured_data_1.IsValid())
self.assertEqual(structured_data_1.GetSize(), 1)
- self.assertEqual(structured_data_1.GetItemAtIndex(0).GetValueForKey("command").GetStringValue(100), "version")
+ self.assertEqual(
+ structured_data_1.GetItemAtIndex(0)
+ .GetValueForKey("command")
+ .GetStringValue(100),
+ "version",
+ )
# Run some more commands and get the transcript as structured data again
self.runCmd("help")
structured_data_2 = ci.GetTranscript()
self.assertTrue(structured_data_2.IsValid())
self.assertEqual(structured_data_2.GetSize(), 2)
- self.assertEqual(structured_data_2.GetItemAtIndex(0).GetValueForKey("command").GetStringValue(100), "version")
- self.assertEqual(structured_data_2.GetItemAtIndex(1).GetValueForKey("command").GetStringValue(100), "help")
+ self.assertEqual(
+ structured_data_2.GetItemAtIndex(0)
+ .GetValueForKey("command")
+ .GetStringValue(100),
+ "version",
+ )
+ self.assertEqual(
+ structured_data_2.GetItemAtIndex(1)
+ .GetValueForKey("command")
+ .GetStringValue(100),
+ "help",
+ )
# Now, the first structured data should remain unchanged
self.assertTrue(structured_data_1.IsValid())
self.assertEqual(structured_data_1.GetSize(), 1)
- self.assertEqual(structured_data_1.GetItemAtIndex(0).GetValueForKey("command").GetStringValue(100), "version")
+ self.assertEqual(
+ structured_data_1.GetItemAtIndex(0)
+ .GetValueForKey("command")
+ .GetStringValue(100),
+ "version",
+ )
diff --git a/lldb/test/API/python_api/sbtype_basic_type/TestSBTypeBasicType.py b/lldb/test/API/python_api/sbtype_basic_type/TestSBTypeBasicType.py
index 535d8b900673..f8594dfc6b78 100644
--- a/lldb/test/API/python_api/sbtype_basic_type/TestSBTypeBasicType.py
+++ b/lldb/test/API/python_api/sbtype_basic_type/TestSBTypeBasicType.py
@@ -28,3 +28,11 @@ class TestCase(TestBase):
self.assertEqual(b.GetType().GetBasicType(), int_basic_type)
self.assertEqual(c.GetType().GetBasicType(), int_basic_type)
self.assertEqual(d.GetType().GetBasicType(), int_basic_type)
+
+ # Check the size of the chosen basic types.
+ self.assertEqual(self.target().FindFirstType("__int128").size, 16)
+ self.assertEqual(self.target().FindFirstType("unsigned __int128").size, 16)
+
+ # Check the size of the chosen aliases of basic types.
+ self.assertEqual(self.target().FindFirstType("__int128_t").size, 16)
+ self.assertEqual(self.target().FindFirstType("__uint128_t").size, 16)
diff --git a/lldb/test/API/tools/lldb-dap/attach-commands/Makefile b/lldb/test/API/tools/lldb-dap/attach-commands/Makefile
new file mode 100644
index 000000000000..10495940055b
--- /dev/null
+++ b/lldb/test/API/tools/lldb-dap/attach-commands/Makefile
@@ -0,0 +1,3 @@
+C_SOURCES := main.c
+
+include Makefile.rules
diff --git a/lldb/test/API/tools/lldb-dap/attach-commands/TestDAP_attachCommands.py b/lldb/test/API/tools/lldb-dap/attach-commands/TestDAP_attachCommands.py
new file mode 100644
index 000000000000..9e29f07db80f
--- /dev/null
+++ b/lldb/test/API/tools/lldb-dap/attach-commands/TestDAP_attachCommands.py
@@ -0,0 +1,145 @@
+"""
+Test lldb-dap attach commands
+"""
+
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
+import lldbdap_testcase
+import time
+
+
+class TestDAP_attachCommands(lldbdap_testcase.DAPTestCaseBase):
+ @skipIfNetBSD # Hangs on NetBSD as well
+ def test_commands(self):
+ """
+ Tests the "initCommands", "preRunCommands", "stopCommands",
+ "exitCommands", "terminateCommands" and "attachCommands"
+ that can be passed during attach.
+
+ "initCommands" are a list of LLDB commands that get executed
+ 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
+ time the program stops.
+ "exitCommands" are a list of LLDB commands that get executed when
+ the process exits
+ "attachCommands" are a list of LLDB commands that get executed and
+ must have a valid process in the selected target in LLDB after
+ they are done executing. This allows custom commands to create any
+ kind of debug session.
+ "terminateCommands" are a list of LLDB commands that get executed when
+ the debugger session terminates.
+ """
+ program = self.build_and_create_debug_adapter_for_attach()
+
+ # Here we just create a target and launch the process as a way to test
+ # if we are able to use attach commands to create any kind of a target
+ # and use it for debugging
+ attachCommands = [
+ 'target create -d "%s"' % (program),
+ "process launch --stop-at-entry",
+ ]
+ initCommands = ["target list", "platform list"]
+ preRunCommands = ["image list a.out", "image dump sections a.out"]
+ postRunCommands = ["help trace", "help process trace"]
+ stopCommands = ["frame variable", "thread backtrace"]
+ exitCommands = ["expr 2+3", "expr 3+4"]
+ terminateCommands = ["expr 4+2"]
+ self.attach(
+ program=program,
+ attachCommands=attachCommands,
+ initCommands=initCommands,
+ preRunCommands=preRunCommands,
+ stopCommands=stopCommands,
+ exitCommands=exitCommands,
+ terminateCommands=terminateCommands,
+ postRunCommands=postRunCommands,
+ )
+ # 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
+ self.verify_commands("initCommands", output, initCommands)
+ # Verify all "preRunCommands" were found in console output
+ self.verify_commands("preRunCommands", output, preRunCommands)
+ # Verify all "postRunCommands" were found in console output
+ self.verify_commands("postRunCommands", output, postRunCommands)
+
+ functions = ["main"]
+ breakpoint_ids = self.set_function_breakpoints(functions)
+ self.assertEqual(len(breakpoint_ids), len(functions), "expect one breakpoint")
+ self.continue_to_breakpoints(breakpoint_ids)
+ output = self.collect_console(pattern=stopCommands[-1])
+ self.verify_commands("stopCommands", output, stopCommands)
+
+ # Continue after launch and hit the "pause()" call and stop the target.
+ # Get output from the console. This should contain both the
+ # "stopCommands" that were run after we stop.
+ self.do_continue()
+ time.sleep(0.5)
+ self.dap_server.request_pause()
+ self.dap_server.wait_for_stopped()
+ output = self.collect_console(pattern=stopCommands[-1])
+ self.verify_commands("stopCommands", output, stopCommands)
+
+ # Continue until the program exits
+ self.continue_to_exit()
+ # Get output from the console. This should contain both the
+ # "exitCommands" that were run after the second breakpoint was hit
+ # and the "terminateCommands" due to the debugging session ending
+ output = self.collect_console(
+ pattern=terminateCommands[0],
+ )
+ self.verify_commands("exitCommands", output, exitCommands)
+ self.verify_commands("terminateCommands", output, terminateCommands)
+
+ def test_attach_command_process_failures(self):
+ """
+ Tests that a 'attachCommands' is expected to leave the debugger's
+ selected target with a valid process.
+ """
+ program = self.build_and_create_debug_adapter_for_attach()
+ attachCommands = ['script print("oops, forgot to attach to a process...")']
+ resp = self.attach(
+ program=program,
+ attachCommands=attachCommands,
+ expectFailure=True,
+ )
+ self.assertFalse(resp["success"])
+ self.assertIn(
+ "attachCommands failed to attach to a process",
+ resp["body"]["error"]["format"],
+ )
+
+ @skipIfNetBSD # Hangs on NetBSD as well
+ def test_terminate_commands(self):
+ """
+ Tests that the "terminateCommands", that can be passed during
+ attach, are run when the debugger is disconnected.
+ """
+ program = self.build_and_create_debug_adapter_for_attach()
+
+ # Here we just create a target and launch the process as a way to test
+ # if we are able to use attach commands to create any kind of a target
+ # and use it for debugging
+ attachCommands = [
+ 'target create -d "%s"' % (program),
+ "process launch --stop-at-entry",
+ ]
+ terminateCommands = ["expr 4+2"]
+ self.attach(
+ program=program,
+ attachCommands=attachCommands,
+ terminateCommands=terminateCommands,
+ disconnectAutomatically=False,
+ )
+ self.get_console()
+ # Once it's disconnected the console should contain the
+ # "terminateCommands"
+ self.dap_server.request_disconnect(terminateDebuggee=True)
+ output = self.collect_console(
+ pattern=terminateCommands[0],
+ )
+ self.verify_commands("terminateCommands", output, terminateCommands)
diff --git a/lldb/test/API/tools/lldb-dap/attach-commands/main.c b/lldb/test/API/tools/lldb-dap/attach-commands/main.c
new file mode 100644
index 000000000000..f56d5d53afa0
--- /dev/null
+++ b/lldb/test/API/tools/lldb-dap/attach-commands/main.c
@@ -0,0 +1,30 @@
+#include "attach.h"
+#include <stdio.h>
+#ifdef _WIN32
+#include <process.h>
+#include <windows.h>
+#else
+#include <unistd.h>
+#endif
+
+int main(int argc, char const *argv[]) {
+ lldb_enable_attach();
+
+ if (argc >= 2) {
+ // Create the synchronization token.
+ FILE *f = fopen(argv[1], "wx");
+ if (!f)
+ return 1;
+ fputs("\n", f);
+ fflush(f);
+ fclose(f);
+ }
+
+ printf("pid = %i\n", getpid());
+#ifdef _WIN32
+ Sleep(10 * 1000);
+#else
+ sleep(10);
+#endif
+ return 0; // breakpoint 1
+}
diff --git a/lldb/test/API/tools/lldb-dap/attach/TestDAP_attach.py b/lldb/test/API/tools/lldb-dap/attach/TestDAP_attach.py
index c54e21c1b973..5331a9f94ef1 100644
--- a/lldb/test/API/tools/lldb-dap/attach/TestDAP_attach.py
+++ b/lldb/test/API/tools/lldb-dap/attach/TestDAP_attach.py
@@ -11,50 +11,35 @@ import threading
import time
-def spawn_and_wait(program, delay):
- if delay:
- time.sleep(delay)
- process = subprocess.Popen(
- [program], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE
- )
- process.wait()
-
-
class TestDAP_attach(lldbdap_testcase.DAPTestCaseBase):
- def set_and_hit_breakpoint(self, continueToExit=True):
- source = "main.c"
- breakpoint1_line = line_number(source, "// breakpoint 1")
- lines = [breakpoint1_line]
- # Set breakpoint in the thread function so we can step the threads
- breakpoint_ids = self.set_source_breakpoints(source, lines)
- self.assertEqual(
- len(breakpoint_ids), len(lines), "expect correct number of breakpoints"
- )
- # Test binary will sleep for 10s, offset the breakpoint timeout
- # accordingly.
- timeout_offset = 10
- self.continue_to_breakpoints(
- breakpoint_ids, timeout=timeout_offset + self.DEFAULT_TIMEOUT
+ def spawn(self, args):
+ self.process = subprocess.Popen(
+ args,
+ stdin=subprocess.PIPE,
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE,
+ universal_newlines=True,
)
- if continueToExit:
- self.continue_to_exit()
- @skipIfNetBSD # Hangs on NetBSD as well
+ def spawn_and_wait(self, program, delay):
+ time.sleep(delay)
+ self.spawn([program])
+ self.process.wait()
+
+ def continue_and_verify_pid(self):
+ self.do_continue()
+ out, _ = self.process.communicate("foo")
+ self.assertIn(f"pid = {self.process.pid}", out)
+
def test_by_pid(self):
"""
Tests attaching to a process by process ID.
"""
program = self.build_and_create_debug_adapter_for_attach()
- self.process = subprocess.Popen(
- [program],
- stdin=subprocess.PIPE,
- stdout=subprocess.PIPE,
- stderr=subprocess.PIPE,
- )
+ self.spawn([program])
self.attach(pid=self.process.pid)
- self.set_and_hit_breakpoint(continueToExit=True)
+ self.continue_and_verify_pid()
- @skipIfNetBSD # Hangs on NetBSD as well
def test_by_name(self):
"""
Tests attaching to a process by process name.
@@ -65,24 +50,20 @@ class TestDAP_attach(lldbdap_testcase.DAPTestCaseBase):
pid_file_path = lldbutil.append_to_process_working_directory(
self, "pid_file_%d" % (int(time.time()))
)
-
- popen = self.spawnSubprocess(program, [pid_file_path])
+ self.spawn([program, pid_file_path])
lldbutil.wait_for_file_on_target(self, pid_file_path)
self.attach(program=program)
- self.set_and_hit_breakpoint(continueToExit=True)
+ self.continue_and_verify_pid()
- @skipUnlessDarwin
- @skipIfNetBSD # Hangs on NetBSD as well
def test_by_name_waitFor(self):
"""
- Tests attaching to a process by process name and waiting for the
- next instance of a process to be launched, ignoring all current
- ones.
+ Tests waiting for, and attaching to a process by process name that
+ doesn't exist yet.
"""
program = self.build_and_create_debug_adapter_for_attach()
self.spawn_thread = threading.Thread(
- target=spawn_and_wait,
+ target=self.spawn_and_wait,
args=(
program,
1.0,
@@ -90,140 +71,4 @@ class TestDAP_attach(lldbdap_testcase.DAPTestCaseBase):
)
self.spawn_thread.start()
self.attach(program=program, waitFor=True)
- self.set_and_hit_breakpoint(continueToExit=True)
-
- @skipIfNetBSD # Hangs on NetBSD as well
- def test_commands(self):
- """
- Tests the "initCommands", "preRunCommands", "stopCommands",
- "exitCommands", "terminateCommands" and "attachCommands"
- that can be passed during attach.
-
- "initCommands" are a list of LLDB commands that get executed
- 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
- time the program stops.
- "exitCommands" are a list of LLDB commands that get executed when
- the process exits
- "attachCommands" are a list of LLDB commands that get executed and
- must have a valid process in the selected target in LLDB after
- they are done executing. This allows custom commands to create any
- kind of debug session.
- "terminateCommands" are a list of LLDB commands that get executed when
- the debugger session terminates.
- """
- program = self.build_and_create_debug_adapter_for_attach()
-
- # Here we just create a target and launch the process as a way to test
- # if we are able to use attach commands to create any kind of a target
- # and use it for debugging
- attachCommands = [
- 'target create -d "%s"' % (program),
- "process launch --stop-at-entry",
- ]
- initCommands = ["target list", "platform list"]
- preRunCommands = ["image list a.out", "image dump sections a.out"]
- postRunCommands = ["help trace", "help process trace"]
- stopCommands = ["frame variable", "thread backtrace"]
- exitCommands = ["expr 2+3", "expr 3+4"]
- terminateCommands = ["expr 4+2"]
- self.attach(
- program=program,
- attachCommands=attachCommands,
- initCommands=initCommands,
- preRunCommands=preRunCommands,
- stopCommands=stopCommands,
- exitCommands=exitCommands,
- terminateCommands=terminateCommands,
- postRunCommands=postRunCommands,
- )
- # 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
- self.verify_commands("initCommands", output, initCommands)
- # Verify all "preRunCommands" were found in console output
- self.verify_commands("preRunCommands", output, preRunCommands)
- # Verify all "postRunCommands" were found in console output
- self.verify_commands("postRunCommands", output, postRunCommands)
-
- functions = ["main"]
- breakpoint_ids = self.set_function_breakpoints(functions)
- self.assertEqual(len(breakpoint_ids), len(functions), "expect one breakpoint")
- self.continue_to_breakpoints(breakpoint_ids)
- output = self.collect_console(timeout=10, pattern=stopCommands[-1])
- self.verify_commands("stopCommands", output, stopCommands)
-
- # Continue after launch and hit the "pause()" call and stop the target.
- # Get output from the console. This should contain both the
- # "stopCommands" that were run after we stop.
- self.do_continue()
- time.sleep(0.5)
- self.dap_server.request_pause()
- self.dap_server.wait_for_stopped()
- output = self.collect_console(timeout=10, pattern=stopCommands[-1])
- self.verify_commands("stopCommands", output, stopCommands)
-
- # Continue until the program exits
- self.continue_to_exit()
- # Get output from the console. This should contain both the
- # "exitCommands" that were run after the second breakpoint was hit
- # and the "terminateCommands" due to the debugging session ending
- output = self.collect_console(
- timeout=10.0,
- pattern=terminateCommands[0],
- )
- self.verify_commands("exitCommands", output, exitCommands)
- self.verify_commands("terminateCommands", output, terminateCommands)
-
- def test_attach_command_process_failures(self):
- """
- Tests that a 'attachCommands' is expected to leave the debugger's
- selected target with a valid process.
- """
- program = self.build_and_create_debug_adapter_for_attach()
- attachCommands = ['script print("oops, forgot to attach to a process...")']
- resp = self.attach(
- program=program,
- attachCommands=attachCommands,
- expectFailure=True,
- )
- self.assertFalse(resp["success"])
- self.assertIn(
- "attachCommands failed to attach to a process",
- resp["body"]["error"]["format"],
- )
-
- @skipIfNetBSD # Hangs on NetBSD as well
- def test_terminate_commands(self):
- """
- Tests that the "terminateCommands", that can be passed during
- attach, are run when the debugger is disconnected.
- """
- program = self.build_and_create_debug_adapter_for_attach()
-
- # Here we just create a target and launch the process as a way to test
- # if we are able to use attach commands to create any kind of a target
- # and use it for debugging
- attachCommands = [
- 'target create -d "%s"' % (program),
- "process launch --stop-at-entry",
- ]
- terminateCommands = ["expr 4+2"]
- self.attach(
- program=program,
- attachCommands=attachCommands,
- terminateCommands=terminateCommands,
- disconnectAutomatically=False,
- )
- self.get_console()
- # Once it's disconnected the console should contain the
- # "terminateCommands"
- self.dap_server.request_disconnect(terminateDebuggee=True)
- output = self.collect_console(
- timeout=1.0,
- pattern=terminateCommands[0],
- )
- self.verify_commands("terminateCommands", output, terminateCommands)
+ self.continue_and_verify_pid()
diff --git a/lldb/test/API/tools/lldb-dap/attach/main.c b/lldb/test/API/tools/lldb-dap/attach/main.c
index f56d5d53afa0..e14cf71a7044 100644
--- a/lldb/test/API/tools/lldb-dap/attach/main.c
+++ b/lldb/test/API/tools/lldb-dap/attach/main.c
@@ -2,7 +2,6 @@
#include <stdio.h>
#ifdef _WIN32
#include <process.h>
-#include <windows.h>
#else
#include <unistd.h>
#endif
@@ -20,11 +19,9 @@ int main(int argc, char const *argv[]) {
fclose(f);
}
+ // Wait on input from stdin.
+ getchar();
+
printf("pid = %i\n", getpid());
-#ifdef _WIN32
- Sleep(10 * 1000);
-#else
- sleep(10);
-#endif
- return 0; // breakpoint 1
+ return 0;
}
diff --git a/lldb/test/API/tools/lldb-dap/breakpoint-events/TestDAP_breakpointEvents.py b/lldb/test/API/tools/lldb-dap/breakpoint-events/TestDAP_breakpointEvents.py
index 151ad761a504..beab4d6c1f5a 100644
--- a/lldb/test/API/tools/lldb-dap/breakpoint-events/TestDAP_breakpointEvents.py
+++ b/lldb/test/API/tools/lldb-dap/breakpoint-events/TestDAP_breakpointEvents.py
@@ -82,14 +82,14 @@ class TestDAP_breakpointEvents(lldbdap_testcase.DAPTestCaseBase):
)
# Flush the breakpoint events.
- self.dap_server.wait_for_breakpoint_events(timeout=5)
+ self.dap_server.wait_for_breakpoint_events()
# Continue to the breakpoint
self.continue_to_breakpoints(dap_breakpoint_ids)
verified_breakpoint_ids = []
unverified_breakpoint_ids = []
- for breakpoint_event in self.dap_server.wait_for_breakpoint_events(timeout=5):
+ for breakpoint_event in self.dap_server.wait_for_breakpoint_events():
breakpoint = breakpoint_event["body"]["breakpoint"]
id = breakpoint["id"]
if breakpoint["verified"]:
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 e722fcea9283..14789a669468 100644
--- a/lldb/test/API/tools/lldb-dap/cancel/TestDAP_cancel.py
+++ b/lldb/test/API/tools/lldb-dap/cancel/TestDAP_cancel.py
@@ -46,7 +46,7 @@ class TestDAP_cancel(lldbdap_testcase.DAPTestCaseBase):
# Use a relatively short timeout since this is only to ensure the
# following request is queued.
- blocking_seq = self.async_blocking_request(duration=1.0)
+ blocking_seq = self.async_blocking_request(duration=self.DEFAULT_TIMEOUT / 10)
# Use a longer timeout to ensure we catch if the request was interrupted
# properly.
pending_seq = self.async_blocking_request(duration=self.DEFAULT_TIMEOUT / 2)
diff --git a/lldb/test/API/tools/lldb-dap/commands/TestDAP_commands.py b/lldb/test/API/tools/lldb-dap/commands/TestDAP_commands.py
index e61d2480ea4b..f53813a8a48f 100644
--- a/lldb/test/API/tools/lldb-dap/commands/TestDAP_commands.py
+++ b/lldb/test/API/tools/lldb-dap/commands/TestDAP_commands.py
@@ -23,7 +23,6 @@ class TestDAP_commands(lldbdap_testcase.DAPTestCaseBase):
exitCommands=["?" + command_quiet, command_not_quiet],
)
full_output = self.collect_console(
- timeout=1.0,
pattern=command_not_quiet,
)
self.assertNotIn(command_quiet, full_output)
@@ -51,7 +50,6 @@ class TestDAP_commands(lldbdap_testcase.DAPTestCaseBase):
expectFailure=True,
)
full_output = self.collect_console(
- timeout=1.0,
pattern=command_abort_on_error,
)
self.assertNotIn(command_quiet, full_output)
diff --git a/lldb/test/API/tools/lldb-dap/io/TestDAP_io.py b/lldb/test/API/tools/lldb-dap/io/TestDAP_io.py
index af5c62a8c4eb..9fbe9aaee8c6 100644
--- a/lldb/test/API/tools/lldb-dap/io/TestDAP_io.py
+++ b/lldb/test/API/tools/lldb-dap/io/TestDAP_io.py
@@ -44,7 +44,7 @@ class TestDAP_io(lldbdap_testcase.DAPTestCaseBase):
"""
process = self.launch()
process.stdin.close()
- self.assertEqual(process.wait(timeout=5.0), EXIT_SUCCESS)
+ self.assertEqual(process.wait(timeout=self.DEFAULT_TIMEOUT), EXIT_SUCCESS)
def test_invalid_header(self):
"""
@@ -54,7 +54,7 @@ class TestDAP_io(lldbdap_testcase.DAPTestCaseBase):
process = self.launch()
process.stdin.write(b"not the correct message header")
process.stdin.close()
- self.assertEqual(process.wait(timeout=5.0), EXIT_FAILURE)
+ self.assertEqual(process.wait(timeout=self.DEFAULT_TIMEOUT), EXIT_FAILURE)
def test_partial_header(self):
"""
@@ -64,7 +64,7 @@ class TestDAP_io(lldbdap_testcase.DAPTestCaseBase):
process = self.launch()
process.stdin.write(b"Content-Length: ")
process.stdin.close()
- self.assertEqual(process.wait(timeout=5.0), EXIT_FAILURE)
+ self.assertEqual(process.wait(timeout=self.DEFAULT_TIMEOUT), EXIT_FAILURE)
def test_incorrect_content_length(self):
"""
@@ -74,7 +74,7 @@ class TestDAP_io(lldbdap_testcase.DAPTestCaseBase):
process = self.launch()
process.stdin.write(b"Content-Length: abc")
process.stdin.close()
- self.assertEqual(process.wait(timeout=5.0), EXIT_FAILURE)
+ self.assertEqual(process.wait(timeout=self.DEFAULT_TIMEOUT), EXIT_FAILURE)
def test_partial_content_length(self):
"""
@@ -84,4 +84,4 @@ class TestDAP_io(lldbdap_testcase.DAPTestCaseBase):
process = self.launch()
process.stdin.write(b"Content-Length: 10\r\n\r\n{")
process.stdin.close()
- self.assertEqual(process.wait(timeout=5.0), EXIT_FAILURE)
+ self.assertEqual(process.wait(timeout=self.DEFAULT_TIMEOUT), EXIT_FAILURE)
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 ceef95dfcd0d..8db2316e73fc 100644
--- a/lldb/test/API/tools/lldb-dap/launch/TestDAP_launch.py
+++ b/lldb/test/API/tools/lldb-dap/launch/TestDAP_launch.py
@@ -632,7 +632,27 @@ class TestDAP_launch(lldbdap_testcase.DAPTestCaseBase):
program = self.getBuildArtifact("a.out")
with tempfile.NamedTemporaryFile("rt") as f:
- self.launch(program, stdio=[None, f.name, None])
+ self.launch(program, stdio=[None, f.name])
+ self.continue_to_exit()
+ lines = f.readlines()
+ self.assertIn(
+ program, lines[0], "make sure program path is in first argument"
+ )
+
+ @skipIfAsan
+ @skipIfWindows
+ @skipIf(oslist=["linux"], archs=no_match(["x86_64"]))
+ def test_stdio_redirection_and_console(self):
+ """
+ Test stdio redirection and console.
+ """
+ self.build_and_create_debug_adapter()
+ program = self.getBuildArtifact("a.out")
+
+ with tempfile.NamedTemporaryFile("rt") as f:
+ self.launch(
+ program, console="integratedTerminal", stdio=[None, f.name, None]
+ )
self.continue_to_exit()
lines = f.readlines()
self.assertIn(
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 bb835af12f5e..1f4afabbd161 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
@@ -23,15 +23,15 @@ class TestDAP_module_event(lldbdap_testcase.DAPTestCaseBase):
self.continue_to_breakpoints(breakpoint_ids)
# We're now stopped at breakpoint 1 before the dlopen. Flush all the module events.
- event = self.dap_server.wait_for_event(["module"], 0.25)
+ event = self.dap_server.wait_for_event(["module"])
while event is not None:
- event = self.dap_server.wait_for_event(["module"], 0.25)
+ event = self.dap_server.wait_for_event(["module"])
# Continue to the second breakpoint, before the dlclose.
self.continue_to_breakpoints(breakpoint_ids)
# Make sure we got a module event for libother.
- event = self.dap_server.wait_for_event(["module"], 5)
+ event = self.dap_server.wait_for_event(["module"])
self.assertIsNotNone(event, "didn't get a module event")
module_name = event["body"]["module"]["name"]
module_id = event["body"]["module"]["id"]
@@ -42,7 +42,7 @@ class TestDAP_module_event(lldbdap_testcase.DAPTestCaseBase):
self.continue_to_breakpoints(breakpoint_ids)
# Make sure we got a module event for libother.
- event = self.dap_server.wait_for_event(["module"], 5)
+ event = self.dap_server.wait_for_event(["module"])
self.assertIsNotNone(event, "didn't get a module event")
reason = event["body"]["reason"]
self.assertEqual(reason, "removed")
@@ -55,8 +55,4 @@ class TestDAP_module_event(lldbdap_testcase.DAPTestCaseBase):
self.assertListEqual(list(module_data.keys()), required_keys)
self.assertEqual(module_data["name"], "", "expects empty name.")
- # Make sure we do not send another event
- event = self.dap_server.wait_for_event(["module"], 3)
- self.assertIsNone(event, "expects no events.")
-
self.continue_to_exit()
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 c5a68372d822..0ed53dac5d86 100644
--- a/lldb/test/API/tools/lldb-dap/module/TestDAP_module.py
+++ b/lldb/test/API/tools/lldb-dap/module/TestDAP_module.py
@@ -67,7 +67,7 @@ class TestDAP_module(lldbdap_testcase.DAPTestCaseBase):
# Collect all the module names we saw as events.
module_new_names = []
module_changed_names = []
- module_event = self.dap_server.wait_for_event(["module"], 1)
+ module_event = self.dap_server.wait_for_event(["module"])
while module_event is not None:
reason = module_event["body"]["reason"]
if reason == "new":
@@ -75,7 +75,7 @@ class TestDAP_module(lldbdap_testcase.DAPTestCaseBase):
elif reason == "changed":
module_changed_names.append(module_event["body"]["module"]["name"])
- module_event = self.dap_server.wait_for_event(["module"], 1)
+ module_event = self.dap_server.wait_for_event(["module"])
# Make sure we got an event for every active module.
self.assertNotEqual(len(module_new_names), 0)
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 fe978a9a7335..0065258920ec 100644
--- a/lldb/test/API/tools/lldb-dap/output/TestDAP_output.py
+++ b/lldb/test/API/tools/lldb-dap/output/TestDAP_output.py
@@ -29,7 +29,7 @@ class TestDAP_output(lldbdap_testcase.DAPTestCaseBase):
self.continue_to_breakpoints(breakpoint_ids)
# Ensure partial messages are still sent.
- output = self.collect_stdout(timeout=1.0, pattern="abcdef")
+ output = self.collect_stdout(pattern="abcdef")
self.assertTrue(output and len(output) > 0, "expect program stdout")
self.continue_to_exit()
diff --git a/lldb/test/API/tools/lldb-dap/restart/TestDAP_restart_console.py b/lldb/test/API/tools/lldb-dap/restart/TestDAP_restart_console.py
index 67483798f226..e1ad1425a993 100644
--- a/lldb/test/API/tools/lldb-dap/restart/TestDAP_restart_console.py
+++ b/lldb/test/API/tools/lldb-dap/restart/TestDAP_restart_console.py
@@ -105,7 +105,7 @@ class TestDAP_restart_console(lldbdap_testcase.DAPTestCaseBase):
# Restart and check that we still get a stopped event before reaching
# main.
self.dap_server.request_restart()
- stopped_events = self.dap_server.wait_for_stopped(timeout=20)
+ stopped_events = self.dap_server.wait_for_stopped()
self.verify_stopped_on_entry(stopped_events)
# continue to main
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 08c225b3cada..6008a0cb0237 100644
--- a/lldb/test/API/tools/lldb-dap/stackTraceDisassemblyDisplay/TestDAP_stackTraceDisassemblyDisplay.py
+++ b/lldb/test/API/tools/lldb-dap/stackTraceDisassemblyDisplay/TestDAP_stackTraceDisassemblyDisplay.py
@@ -29,7 +29,7 @@ class TestDAP_stackTraceMissingSourcePath(lldbdap_testcase.DAPTestCaseBase):
"""
Build the program and run until the breakpoint is hit, and return the stack frames.
"""
- other_source_file = "other.c"
+ other_source_file = self.getBuildArtifact("other.c")
with delete_file_on_exit(other_source_file):
with open(other_source_file, "w") as f:
f.write(OTHER_C_SOURCE_CODE)
@@ -169,3 +169,4 @@ class TestDAP_stackTraceMissingSourcePath(lldbdap_testcase.DAPTestCaseBase):
self.verify_frames_source(
frames, main_frame_assembly=False, other_frame_assembly=False
)
+ self.continue_to_exit()
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 13a694602f23..977d6ce9dac8 100644
--- a/lldb/test/API/tools/lldb-dap/variables/TestDAP_variables.py
+++ b/lldb/test/API/tools/lldb-dap/variables/TestDAP_variables.py
@@ -65,6 +65,11 @@ class TestDAP_variables(lldbdap_testcase.DAPTestCaseBase):
self.assertNotIn(
key, actual, 'key "%s" is not expected in %s' % (key, actual)
)
+ isReadOnly = verify_dict.get("readOnly", False)
+ attributes = actual.get("presentationHint", {}).get("attributes", [])
+ self.assertEqual(
+ isReadOnly, "readOnly" in attributes, "%s %s" % (verify_dict, actual)
+ )
hasVariablesReference = "variablesReference" in actual
varRef = None
if hasVariablesReference:
@@ -179,8 +184,9 @@ class TestDAP_variables(lldbdap_testcase.DAPTestCaseBase):
"children": {
"x": {"equals": {"type": "int", "value": "11"}},
"y": {"equals": {"type": "int", "value": "22"}},
- "buffer": {"children": buffer_children},
+ "buffer": {"children": buffer_children, "readOnly": True},
},
+ "readOnly": True,
},
"x": {"equals": {"type": "int"}},
}
@@ -444,8 +450,10 @@ class TestDAP_variables(lldbdap_testcase.DAPTestCaseBase):
"buffer": {
"children": buffer_children,
"equals": {"indexedVariables": 16},
+ "readOnly": True,
},
},
+ "readOnly": True,
},
"x": {
"equals": {"type": "int"},
@@ -528,7 +536,7 @@ class TestDAP_variables(lldbdap_testcase.DAPTestCaseBase):
"children": {
"x": {"equals": {"type": "int", "value": "11"}},
"y": {"equals": {"type": "int", "value": "22"}},
- "buffer": {"children": buffer_children},
+ "buffer": {"children": buffer_children, "readOnly": True},
},
}
@@ -622,11 +630,17 @@ class TestDAP_variables(lldbdap_testcase.DAPTestCaseBase):
# "[raw]" child.
raw_child_count = 1 if enableSyntheticChildDebugging else 0
verify_locals = {
- "small_array": {"equals": {"indexedVariables": 5}},
- "large_array": {"equals": {"indexedVariables": 200}},
- "small_vector": {"equals": {"indexedVariables": 5 + raw_child_count}},
- "large_vector": {"equals": {"indexedVariables": 200 + raw_child_count}},
- "pt": {"missing": ["indexedVariables"]},
+ "small_array": {"equals": {"indexedVariables": 5}, "readOnly": True},
+ "large_array": {"equals": {"indexedVariables": 200}, "readOnly": True},
+ "small_vector": {
+ "equals": {"indexedVariables": 5 + raw_child_count},
+ "readOnly": True,
+ },
+ "large_vector": {
+ "equals": {"indexedVariables": 200 + raw_child_count},
+ "readOnly": True,
+ },
+ "pt": {"missing": ["indexedVariables"], "readOnly": True},
}
self.verify_variables(verify_locals, locals)
@@ -640,7 +654,10 @@ class TestDAP_variables(lldbdap_testcase.DAPTestCaseBase):
"[4]": {"equals": {"type": "int", "value": "0"}},
}
if enableSyntheticChildDebugging:
- verify_children["[raw]"] = ({"contains": {"type": ["vector"]}},)
+ verify_children["[raw]"] = {
+ "contains": {"type": ["vector"]},
+ "readOnly": True,
+ }
children = self.dap_server.request_variables(locals[2]["variablesReference"])[
"body"
@@ -660,7 +677,7 @@ class TestDAP_variables(lldbdap_testcase.DAPTestCaseBase):
return_name: {"equals": {"type": "int", "value": "300"}},
"argc": {},
"argv": {},
- "pt": {},
+ "pt": {"readOnly": True},
"x": {},
"return_result": {"equals": {"type": "int"}},
}
diff --git a/lldb/test/API/tools/lldb-server/TestGdbRemoteFork.py b/lldb/test/API/tools/lldb-server/TestGdbRemoteFork.py
index 13c4a85f51f7..ef1d546cf171 100644
--- a/lldb/test/API/tools/lldb-server/TestGdbRemoteFork.py
+++ b/lldb/test/API/tools/lldb-server/TestGdbRemoteFork.py
@@ -2,6 +2,7 @@ import random
from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
+from lldbsuite.support import seven
from fork_testbase import GdbRemoteForkTestBase
diff --git a/lldb/test/API/tools/lldb-server/TestLldbGdbServer.py b/lldb/test/API/tools/lldb-server/TestLldbGdbServer.py
index c01f6d83fafe..f1c0519ae56d 100644
--- a/lldb/test/API/tools/lldb-server/TestLldbGdbServer.py
+++ b/lldb/test/API/tools/lldb-server/TestLldbGdbServer.py
@@ -22,7 +22,9 @@ from lldbsuite.test.lldbtest import *
from lldbsuite.test.lldbdwarf import *
from lldbsuite.test import lldbutil, lldbplatformutil
-
+# On Linux systems with Yama ptrace_scope = 1 there is a race condition when the
+# debugee enables tracing. See https://github.com/llvm/llvm-project/issues/161510.
+@skipIfLinux
class LldbGdbServerTestCase(
gdbremote_testcase.GdbRemoteTestCaseBase, DwarfOpcodeParser
):
diff --git a/lldb/test/API/tools/lldb-server/main.cpp b/lldb/test/API/tools/lldb-server/main.cpp
index 0e9323cce88c..7e84552b0f25 100644
--- a/lldb/test/API/tools/lldb-server/main.cpp
+++ b/lldb/test/API/tools/lldb-server/main.cpp
@@ -5,6 +5,7 @@
#include <cstdlib>
#include <cstring>
#include <errno.h>
+#include <fstream>
#include <future>
#include <inttypes.h>
#include <memory>
@@ -265,7 +266,11 @@ int main(int argc, char **argv) {
// Process command line args.
for (int i = 1; i < argc; ++i) {
std::string arg = argv[i];
- if (consume_front(arg, "stderr:")) {
+ if (consume_front(arg, "syncfile:")) {
+ // Write to this file to tell test framework that attaching is now
+ // possible.
+ std::ofstream(arg).close();
+ } else if (consume_front(arg, "stderr:")) {
// Treat remainder as text to go to stderr.
fprintf(stderr, "%s\n", arg.c_str());
} else if (consume_front(arg, "retval:")) {