summaryrefslogtreecommitdiff
path: root/lldb/test/API/functionalities
diff options
context:
space:
mode:
Diffstat (limited to 'lldb/test/API/functionalities')
-rw-r--r--lldb/test/API/functionalities/breakpoint/address_breakpoints/TestBadAddressBreakpoints.py2
-rw-r--r--lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/coroutine_handle/Makefile8
-rw-r--r--lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/coroutine_handle/main.cpp27
-rw-r--r--lldb/test/API/functionalities/disassemble/aarch64-adrp-add/TestAArch64AdrpAdd.py2
-rw-r--r--lldb/test/API/functionalities/gdb_remote_client/TestGDBServerNoTargetXML.py79
-rw-r--r--lldb/test/API/functionalities/gdb_remote_client/TestNoWatchpointSupportInfo.py2
-rw-r--r--lldb/test/API/functionalities/gdb_remote_client/TestXMLRegisterFlags.py402
-rw-r--r--lldb/test/API/functionalities/step_scripted/Steps.py4
-rw-r--r--lldb/test/API/functionalities/step_scripted/TestStepScripted.py8
-rw-r--r--lldb/test/API/functionalities/stop-on-sharedlibrary-load/TestStopOnSharedlibraryEvents.py2
-rw-r--r--lldb/test/API/functionalities/target-new-solib-notifications/Makefile26
-rw-r--r--lldb/test/API/functionalities/target-new-solib-notifications/TestModuleLoadedNotifys.py48
-rw-r--r--lldb/test/API/functionalities/target-new-solib-notifications/a.cpp3
-rw-r--r--lldb/test/API/functionalities/target-new-solib-notifications/b.cpp1
-rw-r--r--lldb/test/API/functionalities/target-new-solib-notifications/c.cpp1
-rw-r--r--lldb/test/API/functionalities/target-new-solib-notifications/d.cpp1
-rw-r--r--lldb/test/API/functionalities/target-new-solib-notifications/main.cpp22
-rw-r--r--lldb/test/API/functionalities/thread_plan/wrap_step_over.py2
-rw-r--r--lldb/test/API/functionalities/type_types/Makefile2
-rw-r--r--lldb/test/API/functionalities/type_types/TestFindTypes.py66
-rw-r--r--lldb/test/API/functionalities/type_types/main.cpp15
21 files changed, 652 insertions, 71 deletions
diff --git a/lldb/test/API/functionalities/breakpoint/address_breakpoints/TestBadAddressBreakpoints.py b/lldb/test/API/functionalities/breakpoint/address_breakpoints/TestBadAddressBreakpoints.py
index d120692e4d6e..3674a8c233c8 100644
--- a/lldb/test/API/functionalities/breakpoint/address_breakpoints/TestBadAddressBreakpoints.py
+++ b/lldb/test/API/functionalities/breakpoint/address_breakpoints/TestBadAddressBreakpoints.py
@@ -32,7 +32,7 @@ class BadAddressBreakpointTestCase(TestBase):
for region_idx in range(regions.GetSize()):
region = lldb.SBMemoryRegionInfo()
regions.GetMemoryRegionAtIndex(region_idx, region)
- if illegal_address == None or region.GetRegionEnd() > illegal_address:
+ if illegal_address is None or region.GetRegionEnd() > illegal_address:
illegal_address = region.GetRegionEnd()
if illegal_address is not None:
diff --git a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/coroutine_handle/Makefile b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/coroutine_handle/Makefile
index 6914024392cf..3e5da0ecae66 100644
--- a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/coroutine_handle/Makefile
+++ b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/coroutine_handle/Makefile
@@ -1,4 +1,12 @@
CXX_SOURCES := main.cpp
CFLAGS_EXTRAS := -std=c++20
+ifeq "1" "$(USE_LIBSTDCPP)"
+ CFLAGS_EXTRAS += -DUSE_LIBSTDCPP
+endif
+
+ifeq "1" "$(USE_LIBCPP)"
+ CFLAGS_EXTRAS += -DUSE_LIBCPP
+endif
+
include Makefile.rules
diff --git a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/coroutine_handle/main.cpp b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/coroutine_handle/main.cpp
index 8cb81c3bc9f4..aaf76e0d8d99 100644
--- a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/coroutine_handle/main.cpp
+++ b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/coroutine_handle/main.cpp
@@ -1,13 +1,27 @@
+#if defined(USE_LIBSTDCPP)
+#include <bits/c++config.h>
+// glibc++ >= 11 and c++20
+#if defined(_GLIBCXX_RELEASE) && _GLIBCXX_RELEASE >= 11
#include <coroutine>
+#define HAS_CPP_COROUTINES 1
+#endif
+#endif
+
+// libc++ always has 'coroutine' feature.
+#if defined(USE_LIBCPP)
+#include <coroutine>
+#define HAS_CPP_COROUTINES 1
+#endif
bool is_implementation_supported() {
-#ifdef _GLIBCXX_RELEASE
- return _GLIBCXX_RELEASE >= 11;
-#else
+#ifdef HAS_CPP_COROUTINES
return true;
+#else
+ return false;
#endif
}
+#ifdef HAS_CPP_COROUTINES
// `int_generator` is a stripped down, minimal coroutine generator
// type.
struct int_generator {
@@ -39,8 +53,11 @@ int_generator my_generator_func() { co_yield 42; }
// a place to reliably set a breakpoint on.
void empty_function_so_we_can_set_a_breakpoint() {}
+#endif // HAS_CPP_COROUTINES
+
int main() {
bool is_supported = is_implementation_supported();
+#ifdef HAS_CPP_COROUTINES
int_generator gen = my_generator_func();
std::coroutine_handle<> type_erased_hdl = gen.hdl;
std::coroutine_handle<int> incorrectly_typed_hdl =
@@ -48,4 +65,8 @@ int main() {
gen.hdl.resume(); // Break at initial_suspend
gen.hdl.resume(); // Break after co_yield
empty_function_so_we_can_set_a_breakpoint(); // Break at final_suspend
+ return 0;
+#else
+ return 0; // Break at initial_suspend
+#endif // HAS_CPP_COROUTINES
}
diff --git a/lldb/test/API/functionalities/disassemble/aarch64-adrp-add/TestAArch64AdrpAdd.py b/lldb/test/API/functionalities/disassemble/aarch64-adrp-add/TestAArch64AdrpAdd.py
index da9ce1b87d33..8a3bcf28a211 100644
--- a/lldb/test/API/functionalities/disassemble/aarch64-adrp-add/TestAArch64AdrpAdd.py
+++ b/lldb/test/API/functionalities/disassemble/aarch64-adrp-add/TestAArch64AdrpAdd.py
@@ -57,7 +57,7 @@ class TestAArch64AdrpAdd(TestBase):
found_hi_string = True
if "foo" in i.GetComment(target):
found_foo = True
- if found_hi_string == False or found_foo == False:
+ if not found_hi_string or not found_foo:
print(
'Did not find "HI" string or "foo" in disassembly symbolication in %s'
% binaryname
diff --git a/lldb/test/API/functionalities/gdb_remote_client/TestGDBServerNoTargetXML.py b/lldb/test/API/functionalities/gdb_remote_client/TestGDBServerNoTargetXML.py
index 5f6ed7d537af..8c5bad007f56 100644
--- a/lldb/test/API/functionalities/gdb_remote_client/TestGDBServerNoTargetXML.py
+++ b/lldb/test/API/functionalities/gdb_remote_client/TestGDBServerNoTargetXML.py
@@ -1,3 +1,12 @@
+"""
+Check that lldb falls back to default register layouts when the remote provides
+no target XML.
+
+GPRS are passed to the responder to create register data to send back to lldb.
+Registers in SUPPL are virtual registers based on those general ones. The tests
+pass __file__ to FileCheck so any prefixes in this Python file will be checked.
+"""
+
import lldb
from lldbsuite.test.lldbtest import *
from lldbsuite.test.decorators import *
@@ -6,14 +15,29 @@ from lldbsuite.test.lldbgdbclient import GDBRemoteTestBase
import binascii
-
-class TestGDBServerTargetXML(GDBRemoteTestBase):
+class MyResponder(MockGDBServerResponder):
@staticmethod
def filecheck_to_blob(fc):
for l in fc.strip().splitlines():
val = l.split("0x")[1]
yield binascii.b2a_hex(bytes(reversed(binascii.a2b_hex(val)))).decode()
+ def __init__(self, reg_data, halt_reason):
+ super().__init__()
+ self.reg_data = "".join(self.filecheck_to_blob(reg_data))
+ self.halt_reason = halt_reason
+
+ def readRegister(self, regnum):
+ return ""
+
+ def readRegisters(self):
+ return self.reg_data
+
+ def haltReason(self):
+ return self.halt_reason
+
+
+class TestGDBServerTargetXML(GDBRemoteTestBase):
@skipIfRemote
@skipIfLLVMTargetMissing("X86")
def test_x86_64_regs(self):
@@ -100,19 +124,10 @@ CHECK-AMD64-DAG: r14l = 0xe1
CHECK-AMD64-DAG: r15l = 0xf1
"""
- class MyResponder(MockGDBServerResponder):
- reg_data = "".join(self.filecheck_to_blob(GPRS))
-
- def readRegister(self, regnum):
- return ""
-
- def readRegisters(self):
- return self.reg_data
-
- def haltReason(self):
- return "T02thread:1ff0d;threads:1ff0d;thread-pcs:000000010001bc00;07:0102030405060708;10:1112131415161718;"
-
- self.server.responder = MyResponder()
+ self.server.responder = MyResponder(
+ GPRS,
+ "T02thread:1ff0d;threads:1ff0d;thread-pcs:000000010001bc00;07:0102030405060708;10:1112131415161718;",
+ )
target = self.createTarget("basic_eh_frame.yaml")
process = self.connect(target)
@@ -216,19 +231,10 @@ CHECK-AARCH64-DAG: w30 = 0x22232425
CHECK-AARCH64-DAG: w31 = 0x23242526
"""
- class MyResponder(MockGDBServerResponder):
- reg_data = "".join(self.filecheck_to_blob(GPRS))
-
- def readRegister(self, regnum):
- return ""
-
- def readRegisters(self):
- return self.reg_data
-
- def haltReason(self):
- return "T02thread:1ff0d;threads:1ff0d;thread-pcs:000000010001bc00;07:0102030405060708;10:1112131415161718;"
-
- self.server.responder = MyResponder()
+ self.server.responder = MyResponder(
+ GPRS,
+ "T02thread:1ff0d;threads:1ff0d;thread-pcs:000000010001bc00;07:0102030405060708;10:1112131415161718;",
+ )
target = self.createTarget("basic_eh_frame-aarch64.yaml")
process = self.connect(target)
@@ -300,19 +306,10 @@ CHECK-I386-DAG: sil = 0x61
CHECK-I386-DAG: dil = 0x71
"""
- class MyResponder(MockGDBServerResponder):
- reg_data = "".join(self.filecheck_to_blob(GPRS))
-
- def readRegister(self, regnum):
- return ""
-
- def readRegisters(self):
- return self.reg_data
-
- def haltReason(self):
- return "T02thread:1ff0d;threads:1ff0d;thread-pcs:000000010001bc00;07:0102030405060708;10:1112131415161718;"
-
- self.server.responder = MyResponder()
+ self.server.responder = MyResponder(
+ GPRS,
+ "T02thread:1ff0d;threads:1ff0d;thread-pcs:000000010001bc00;07:0102030405060708;10:1112131415161718;",
+ )
target = self.createTarget("basic_eh_frame-i386.yaml")
process = self.connect(target)
diff --git a/lldb/test/API/functionalities/gdb_remote_client/TestNoWatchpointSupportInfo.py b/lldb/test/API/functionalities/gdb_remote_client/TestNoWatchpointSupportInfo.py
index a51b228e917c..7d6b1afd94a1 100644
--- a/lldb/test/API/functionalities/gdb_remote_client/TestNoWatchpointSupportInfo.py
+++ b/lldb/test/API/functionalities/gdb_remote_client/TestNoWatchpointSupportInfo.py
@@ -61,7 +61,7 @@ class TestNoWatchpointSupportInfo(GDBRemoteTestBase):
wp_opts = lldb.SBWatchpointOptions()
wp_opts.SetWatchpointTypeWrite(lldb.eWatchpointWriteTypeOnModify)
wp = target.WatchpointCreateByAddress(0x100, 8, wp_opts, err)
- if self.TraceOn() and (err.Fail() or wp.IsValid == False):
+ if self.TraceOn() and (err.Fail() or not wp.IsValid):
strm = lldb.SBStream()
err.GetDescription(strm)
print("watchpoint failed: %s" % strm.GetData())
diff --git a/lldb/test/API/functionalities/gdb_remote_client/TestXMLRegisterFlags.py b/lldb/test/API/functionalities/gdb_remote_client/TestXMLRegisterFlags.py
index e2c75970c2d2..2dbb2b5f5e3a 100644
--- a/lldb/test/API/functionalities/gdb_remote_client/TestXMLRegisterFlags.py
+++ b/lldb/test/API/functionalities/gdb_remote_client/TestXMLRegisterFlags.py
@@ -654,3 +654,405 @@ class TestXMLRegisterFlags(GDBRemoteTestBase):
"register info cpsr",
substrs=["| A< | B> | C' | D\" | E& |"],
)
+
+ @skipIfXmlSupportMissing
+ @skipIfRemote
+ def test_no_enum(self):
+ """Check that lldb does not try to print an enum when there isn't one."""
+
+ self.setup_flags_test('<field name="E" start="0" end="0">' "</field>")
+
+ self.expect("register info cpsr", patterns=["E:.*$"], matching=False)
+
+ @skipIfXmlSupportMissing
+ @skipIfRemote
+ def test_enum_type_not_found(self):
+ """Check that lldb uses the default format if we don't find the enum type."""
+ self.setup_register_test(
+ """\
+ <flags id="cpsr_flags" size="4">
+ <field name="E" start="0" end="0" type="some_enum"/>
+ </flags>
+ <reg name="pc" bitsize="64"/>
+ <reg name="x0" regnum="0" bitsize="64"/>
+ <reg name="cpsr" regnum="33" bitsize="32" type="cpsr_flags"/>"""
+ )
+
+ self.expect("register read cpsr", patterns=["\(E = 1\)$"])
+
+ @skipIfXmlSupportMissing
+ @skipIfRemote
+ def test_enum_duplicated_evalue(self):
+ """Check that lldb only uses the last instance of a evalue for each
+ value."""
+ self.setup_register_test(
+ """\
+ <enum id="some_enum" size="4">
+ <evalue name="abc" value="1"/>
+ <evalue name="def" value="1"/>
+ <evalue name="geh" value="2"/>
+ </enum>
+ <flags id="cpsr_flags" size="4">
+ <field name="E" start="0" end="1" type="some_enum"/>
+ </flags>
+ <reg name="pc" bitsize="64"/>
+ <reg name="x0" regnum="0" bitsize="64"/>
+ <reg name="cpsr" regnum="33" bitsize="32" type="cpsr_flags"/>"""
+ )
+
+ self.expect("register info cpsr", patterns=["E: 1 = def, 2 = geh$"])
+ self.expect("register read cpsr", patterns=["\(E = def \| geh\)$"])
+
+ @skipIfXmlSupportMissing
+ @skipIfRemote
+ def test_enum_duplicated(self):
+ """Check that lldb only uses the last instance of enums with the same
+ id."""
+ self.setup_register_test(
+ """\
+ <enum id="some_enum" size="4">
+ <evalue name="abc" value="1"/>
+ </enum>
+ <enum id="some_enum" size="4">
+ <evalue name="def" value="1"/>
+ </enum>
+ <flags id="cpsr_flags" size="4">
+ <field name="E" start="0" end="0" type="some_enum"/>
+ </flags>
+ <reg name="pc" bitsize="64"/>
+ <reg name="x0" regnum="0" bitsize="64"/>
+ <reg name="cpsr" regnum="33" bitsize="32" type="cpsr_flags"/>"""
+ )
+
+ self.expect("register info cpsr", patterns=["E: 1 = def$"])
+ self.expect("register read cpsr", patterns=["\(E = def\)$"])
+
+ @skipIfXmlSupportMissing
+ @skipIfRemote
+ def test_enum_use_first_valid(self):
+ """Check that lldb uses the first enum that parses correctly and ignores
+ the rest."""
+ self.setup_register_test(
+ """\
+ <enum id="some_enum" size="4"/>
+ <enum size="4">
+ <evalue name="invalid" value="1"/>
+ </enum>
+ <enum id="some_enum" size="4">
+ <evalue name="valid" value="1"/>
+ </enum>
+ <enum id="another_enum" size="4">
+ <evalue name="invalid" value="1"/>
+ </enum>
+ <flags id="cpsr_flags" size="4">
+ <field name="E" start="0" end="0" type="some_enum"/>
+ </flags>
+ <reg name="pc" bitsize="64"/>
+ <reg name="x0" regnum="0" bitsize="64"/>
+ <reg name="cpsr" regnum="33" bitsize="32" type="cpsr_flags"/>"""
+ )
+
+ self.expect("register info cpsr", patterns=["E: 1 = valid$"])
+
+ @skipIfXmlSupportMissing
+ @skipIfRemote
+ def test_evalue_empty_name(self):
+ """Check that lldb ignores evalues with an empty name."""
+
+ # The only potential use case for empty names is to shadow an evalue
+ # declared later so that it's name is hidden should the debugger only
+ # pick one of them. This behaviour would be debugger specific so the protocol
+ # would probably not care or leave it up to us, and I think it's not a
+ # useful thing to allow.
+
+ self.setup_register_test(
+ """\
+ <enum id="some_enum" size="4">
+ <evalue name="" value="1"/>
+ <evalue name="valid" value="2"/>
+ </enum>
+ <flags id="cpsr_flags" size="4">
+ <field name="E" start="0" end="1" type="some_enum"/>
+ </flags>
+ <reg name="pc" bitsize="64"/>
+ <reg name="x0" regnum="0" bitsize="64"/>
+ <reg name="cpsr" regnum="33" bitsize="32" type="cpsr_flags"/>"""
+ )
+
+ self.expect("register info cpsr", patterns=["E: 2 = valid$"])
+
+ @skipIfXmlSupportMissing
+ @skipIfRemote
+ def test_evalue_invalid_value(self):
+ """Check that lldb ignores evalues with an invalid value."""
+ self.setup_register_test(
+ """\
+ <enum id="some_enum" size="4">
+ <evalue name="negative_dec" value="-1"/>
+ <evalue name="negative_hex" value="-0x1"/>
+ <evalue name="negative_bin" value="-0b1"/>
+ <evalue name="negative_float" value="-0.5"/>
+ <evalue name="nan" value="aardvark"/>
+ <evalue name="dec" value="1"/>
+ <evalue name="hex" value="0x2"/>
+ <evalue name="octal" value="03"/>
+ <evalue name="float" value="0.5"/>
+ <evalue name="bin" value="0b100"/>
+ </enum>
+ <flags id="cpsr_flags" size="4">
+ <field name="E" start="0" end="2" type="some_enum"/>
+ </flags>
+ <reg name="pc" bitsize="64"/>
+ <reg name="x0" regnum="0" bitsize="64"/>
+ <reg name="cpsr" regnum="33" bitsize="32" type="cpsr_flags"/>"""
+ )
+
+ self.expect(
+ "register info cpsr", patterns=["E: 1 = dec, 2 = hex, 3 = octal, 4 = bin$"]
+ )
+
+ @skipIfXmlSupportMissing
+ @skipIfRemote
+ def test_evalue_out_of_range(self):
+ """Check that lldb will not use an enum type if one of its evalues
+ exceeds the size of the field it is applied to."""
+ self.setup_register_test(
+ """\
+ <enum id="some_enum" size="4">
+ <evalue name="A" value="0"/>
+ <evalue name="B" value="2"/>
+ </enum>
+ <flags id="cpsr_flags" size="4">
+ <field name="E" start="0" end="0" type="some_enum"/>
+ </flags>
+ <reg name="pc" bitsize="64"/>
+ <reg name="x0" regnum="0" bitsize="64"/>
+ <reg name="cpsr" regnum="33" bitsize="32" type="cpsr_flags"/>"""
+ )
+
+ # The whole eunm is rejected even if just 1 value is out of range.
+ self.expect("register info cpsr", patterns=["E: 0 = "], matching=False)
+
+ @skipIfXmlSupportMissing
+ @skipIfRemote
+ def test_enum_ignore_unknown_attributes(self):
+ """Check that lldb ignores unknown attributes on an enum or evalue."""
+ self.setup_register_test(
+ """\
+ <enum id="some_enum" size="4" foo=\"bar\">
+ <evalue name="valid" value="1" colour=\"red"/>
+ </enum>
+ <flags id="cpsr_flags" size="4">
+ <field name="E" start="0" end="0" type="some_enum"/>
+ </flags>
+ <reg name="pc" bitsize="64"/>
+ <reg name="x0" regnum="0" bitsize="64"/>
+ <reg name="cpsr" regnum="33" bitsize="32" type="cpsr_flags"/>"""
+ )
+
+ self.expect("register info cpsr", patterns=["E: 1 = valid$"])
+
+ @skipIfXmlSupportMissing
+ @skipIfRemote
+ def test_evalue_required_attributes(self):
+ """Check that lldb rejects any evalue missing a name and/or value."""
+ self.setup_register_test(
+ """\
+ <enum id="some_enum" size="4">
+ <evalue name="foo"/>
+ <evalue value="1"/>
+ <evalue />
+ <evalue name="valid" value="1"/>
+ </enum>
+ <flags id="cpsr_flags" size="4">
+ <field name="E" start="0" end="0" type="some_enum"/>
+ </flags>
+ <reg name="pc" bitsize="64"/>
+ <reg name="x0" regnum="0" bitsize="64"/>
+ <reg name="cpsr" regnum="33" bitsize="32" type="cpsr_flags"/>"""
+ )
+
+ self.expect("register info cpsr", patterns=["E: 1 = valid$"])
+
+ @skipIfXmlSupportMissing
+ @skipIfRemote
+ def test_evalue_name_xml_reserved_characters(self):
+ """Check that lldb converts reserved character replacements like &amp;
+ when found in evalue names."""
+ self.setup_register_test(
+ """\
+ <enum id="some_enum" size="4">
+ <evalue name="A&amp;" value="0"/>
+ <evalue name="B&quot;" value="1"/>
+ <evalue name="C&apos;" value="2"/>
+ <evalue name="D&gt;" value="3"/>
+ <evalue name="E&lt;" value="4"/>
+ </enum>
+ <flags id="cpsr_flags" size="4">
+ <field name="E" start="0" end="2" type="some_enum"/>
+ </flags>
+ <reg name="pc" bitsize="64"/>
+ <reg name="x0" regnum="0" bitsize="64"/>
+ <reg name="cpsr" regnum="33" bitsize="32" type="cpsr_flags"/>"""
+ )
+
+ self.expect(
+ "register info cpsr",
+ patterns=["E: 0 = A&, 1 = B\", 2 = C', 3 = D>, 4 = E<$"],
+ )
+
+ @skipIfXmlSupportMissing
+ @skipIfRemote
+ def test_enum_value_range(self):
+ """Check that lldb ignores enums whose values would not fit into
+ their field."""
+
+ self.setup_register_test(
+ """\
+ <enum id="some_enum" size="4">
+ <evalue name="A" value="0"/>
+ <evalue name="B" value="1"/>
+ <evalue name="C" value="2"/>
+ <evalue name="D" value="3"/>
+ <evalue name="E" value="4"/>
+ </enum>
+ <flags id="cpsr_flags" size="4">
+ <field name="foo" start="0" end="1" type="some_enum"/>
+ <field name="bar" start="2" end="10" type="some_enum"/>
+ </flags>
+ <reg name="pc" bitsize="64"/>
+ <reg name="x0" regnum="0" bitsize="64"/>
+ <reg name="cpsr" regnum="33" bitsize="32" type="cpsr_flags"/>"""
+ )
+
+ # some_enum can apply to foo
+ self.expect(
+ "register info cpsr", patterns=["bar: 0 = A, 1 = B, 2 = C, 3 = D, 4 = E$"]
+ )
+ # but not to bar
+ self.expect("register info cpsr", patterns=["foo: "], matching=False)
+
+ @skipIfXmlSupportMissing
+ @skipIfRemote
+ def test_evalue_value_limits(self):
+ """Check that lldb can handle an evalue for a field up to 64 bits
+ in size and anything greater is ignored."""
+
+ self.setup_register_test(
+ """\
+ <enum id="some_enum" size="8">
+ <evalue name="min" value="0"/>
+ <evalue name="max" value="0xffffffffffffffff"/>
+ <evalue name="invalid" value="0xfffffffffffffffff"/>
+ </enum>
+ <flags id="x0_flags" size="8">
+ <field name="foo" start="0" end="63" type="some_enum"/>
+ </flags>
+ <reg name="pc" bitsize="64"/>
+ <reg name="x0" regnum="0" bitsize="64" type="x0_flags"/>
+ <reg name="cpsr" regnum="33" bitsize="32"/>"""
+ )
+
+ self.expect(
+ "register info x0", patterns=["foo: 0 = min, 18446744073709551615 = max$"]
+ )
+
+ @skipIfXmlSupportMissing
+ @skipIfRemote
+ def test_field_size_limit(self):
+ """Check that lldb ignores any field > 64 bits. We can't handle those
+ correctly."""
+
+ self.setup_register_test(
+ """\
+ <flags id="x0_flags" size="8">
+ <field name="invalid" start="0" end="64"/>
+ <field name="valid" start="0" end="63"/>
+ </flags>
+ <reg name="pc" bitsize="64"/>
+ <reg name="x0" regnum="0" bitsize="64" type="x0_flags"/>
+ <reg name="cpsr" regnum="33" bitsize="32"/>"""
+ )
+
+ self.expect(
+ "register info x0", substrs=["| 63-0 |\n" "|-------|\n" "| valid |"]
+ )
+
+ @skipIfXmlSupportMissing
+ @skipIfRemote
+ def test_many_fields_same_enum(self):
+ """Check that an enum can be reused by many fields, and fields of many
+ registers."""
+
+ self.setup_register_test(
+ """\
+ <enum id="some_enum" size="8">
+ <evalue name="valid" value="1"/>
+ </enum>
+ <flags id="x0_flags" size="8">
+ <field name="f1" start="0" end="0" type="some_enum"/>
+ <field name="f2" start="1" end="1" type="some_enum"/>
+ </flags>
+ <flags id="cpsr_flags" size="4">
+ <field name="f1" start="0" end="0" type="some_enum"/>
+ <field name="f2" start="1" end="1" type="some_enum"/>
+ </flags>
+ <reg name="pc" bitsize="64"/>
+ <reg name="x0" regnum="0" bitsize="64" type="x0_flags"/>
+ <reg name="cpsr" regnum="33" bitsize="32" type="cpsr_flags"/>"""
+ )
+
+ expected_info = [
+ dedent(
+ """\
+ f2: 1 = valid
+
+ f1: 1 = valid$"""
+ )
+ ]
+ self.expect("register info x0", patterns=expected_info)
+
+ self.expect("register info cpsr", patterns=expected_info)
+
+ expected_read = ["\(f2 = valid, f1 = valid\)$"]
+ self.expect("register read x0", patterns=expected_read)
+ self.expect("register read cpsr", patterns=expected_read)
+
+ @skipIfXmlSupportMissing
+ @skipIfRemote
+ def test_fields_same_name_different_enum(self):
+ """Check that lldb does something sensible when there are two fields with
+ the same name, but their enum types differ."""
+
+ # It's unlikely anyone would do this intentionally but it is allowed by
+ # the protocol spec so we have to cope with it.
+ self.setup_register_test(
+ """\
+ <enum id="foo_enum" size="8">
+ <evalue name="foo_0" value="1"/>
+ </enum>
+ <enum id="foo_alt_enum" size="8">
+ <evalue name="foo_1" value="1"/>
+ </enum>
+ <flags id="x0_flags" size="8">
+ <field name="foo" start="0" end="0" type="foo_enum"/>
+ <field name="foo" start="1" end="1" type="foo_alt_enum"/>
+ </flags>
+ <reg name="pc" bitsize="64"/>
+ <reg name="x0" regnum="0" bitsize="64" type="x0_flags"/>
+ <reg name="cpsr" regnum="33" bitsize="32"/>"""
+ )
+
+ self.expect(
+ "register info x0",
+ patterns=[
+ dedent(
+ """\
+ foo: 1 = foo_1
+
+ foo: 1 = foo_0$"""
+ )
+ ],
+ )
+
+ self.expect("register read x0", patterns=["\(foo = foo_1, foo = foo_0\)$"])
diff --git a/lldb/test/API/functionalities/step_scripted/Steps.py b/lldb/test/API/functionalities/step_scripted/Steps.py
index 7527607be847..3325dba75365 100644
--- a/lldb/test/API/functionalities/step_scripted/Steps.py
+++ b/lldb/test/API/functionalities/step_scripted/Steps.py
@@ -47,7 +47,7 @@ class StepScripted(StepWithChild):
# This plan does a step-over until a variable changes value.
class StepUntil(StepWithChild):
- def __init__(self, thread_plan, args_data, dict):
+ def __init__(self, thread_plan, args_data):
self.thread_plan = thread_plan
self.frame = thread_plan.GetThread().frames[0]
self.target = thread_plan.GetThread().GetProcess().GetTarget()
@@ -99,7 +99,7 @@ class StepUntil(StepWithChild):
class StepReportsStopOthers:
stop_mode_dict = {}
- def __init__(self, thread_plan, args_data, dict):
+ def __init__(self, thread_plan, args_data):
self.thread_plan = thread_plan
self.key = str(args_data.GetValueForKey("token").GetUnsignedIntegerValue(1000))
diff --git a/lldb/test/API/functionalities/step_scripted/TestStepScripted.py b/lldb/test/API/functionalities/step_scripted/TestStepScripted.py
index 9891a9c23b50..7a4992abd8fc 100644
--- a/lldb/test/API/functionalities/step_scripted/TestStepScripted.py
+++ b/lldb/test/API/functionalities/step_scripted/TestStepScripted.py
@@ -7,7 +7,6 @@ import lldbsuite.test.lldbutil as lldbutil
from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
-
class StepScriptedTestCase(TestBase):
NO_DEBUG_INFO_TESTCASE = True
@@ -16,12 +15,14 @@ class StepScriptedTestCase(TestBase):
self.main_source_file = lldb.SBFileSpec("main.c")
self.runCmd("command script import Steps.py")
+ @expectedFailureAll()
def test_standard_step_out(self):
"""Tests stepping with the scripted thread plan laying over a standard
thread plan for stepping out."""
self.build()
self.step_out_with_scripted_plan("Steps.StepOut")
+ @expectedFailureAll()
def test_scripted_step_out(self):
"""Tests stepping with the scripted thread plan laying over an another
scripted thread plan for stepping out."""
@@ -44,6 +45,7 @@ class StepScriptedTestCase(TestBase):
stop_desc = thread.GetStopDescription(1000)
self.assertIn("Stepping out from", stop_desc, "Got right description")
+ @expectedFailureAll()
def test_misspelled_plan_name(self):
"""Test that we get a useful error if we misspell the plan class name"""
self.build()
@@ -62,10 +64,12 @@ class StepScriptedTestCase(TestBase):
# Make sure we didn't let the process run:
self.assertEqual(stop_id, process.GetStopID(), "Process didn't run")
+ @expectedFailureAll()
def test_checking_variable(self):
"""Test that we can call SBValue API's from a scripted thread plan - using SBAPI's to step"""
self.do_test_checking_variable(False)
+ @expectedFailureAll()
def test_checking_variable_cli(self):
"""Test that we can call SBValue API's from a scripted thread plan - using cli to step"""
self.do_test_checking_variable(True)
@@ -126,7 +130,7 @@ class StepScriptedTestCase(TestBase):
cmd = "thread step-scripted -C Steps.StepReportsStopOthers -k token -v %s" % (
token
)
- if run_mode != None:
+ if run_mode is not None:
cmd = cmd + " --run-mode %s" % (run_mode)
if self.TraceOn():
print(cmd)
diff --git a/lldb/test/API/functionalities/stop-on-sharedlibrary-load/TestStopOnSharedlibraryEvents.py b/lldb/test/API/functionalities/stop-on-sharedlibrary-load/TestStopOnSharedlibraryEvents.py
index 58205553154b..f68eb4196c12 100644
--- a/lldb/test/API/functionalities/stop-on-sharedlibrary-load/TestStopOnSharedlibraryEvents.py
+++ b/lldb/test/API/functionalities/stop-on-sharedlibrary-load/TestStopOnSharedlibraryEvents.py
@@ -99,7 +99,7 @@ class TestStopOnSharedlibraryEvents(TestBase):
backstop_bkpt_2.GetNumLocations(), 0, "Set our third breakpoint"
)
- if bkpt_modifier == None:
+ if bkpt_modifier is None:
process.Continue()
self.assertState(
process.GetState(), lldb.eStateStopped, "We didn't stop for the load"
diff --git a/lldb/test/API/functionalities/target-new-solib-notifications/Makefile b/lldb/test/API/functionalities/target-new-solib-notifications/Makefile
index 99998b20bcb0..6c61d210eeb2 100644
--- a/lldb/test/API/functionalities/target-new-solib-notifications/Makefile
+++ b/lldb/test/API/functionalities/target-new-solib-notifications/Makefile
@@ -1,3 +1,23 @@
-CXX_SOURCES := main.cpp
-
-include Makefile.rules
+CXX_SOURCES := main.cpp
+LD_EXTRAS := -L. -l_d -l_c -l_a -l_b
+
+a.out: lib_b lib_a lib_c lib_d
+
+include Makefile.rules
+
+lib_a: lib_b
+ $(MAKE) -f $(MAKEFILE_RULES) \
+ DYLIB_ONLY=YES DYLIB_CXX_SOURCES=a.cpp DYLIB_NAME=_a \
+ LD_EXTRAS="-L. -l_b"
+
+lib_b:
+ $(MAKE) -f $(MAKEFILE_RULES) \
+ DYLIB_ONLY=YES DYLIB_CXX_SOURCES=b.cpp DYLIB_NAME=_b
+
+lib_c:
+ $(MAKE) -f $(MAKEFILE_RULES) \
+ DYLIB_ONLY=YES DYLIB_CXX_SOURCES=c.cpp DYLIB_NAME=_c
+
+lib_d:
+ $(MAKE) -f $(MAKEFILE_RULES) \
+ DYLIB_ONLY=YES DYLIB_CXX_SOURCES=d.cpp DYLIB_NAME=_d
diff --git a/lldb/test/API/functionalities/target-new-solib-notifications/TestModuleLoadedNotifys.py b/lldb/test/API/functionalities/target-new-solib-notifications/TestModuleLoadedNotifys.py
index abf761fb3420..47af6909b728 100644
--- a/lldb/test/API/functionalities/target-new-solib-notifications/TestModuleLoadedNotifys.py
+++ b/lldb/test/API/functionalities/target-new-solib-notifications/TestModuleLoadedNotifys.py
@@ -9,22 +9,47 @@ from lldbsuite.test.lldbtest import *
from lldbsuite.test import lldbutil
+@skipUnlessPlatform(["linux"] + lldbplatformutil.getDarwinOSTriples())
class ModuleLoadedNotifysTestCase(TestBase):
NO_DEBUG_INFO_TESTCASE = True
# At least DynamicLoaderDarwin and DynamicLoaderPOSIXDYLD should batch up
# notifications about newly added/removed libraries. Other DynamicLoaders may
# not be written this way.
- @skipUnlessPlatform(["linux"] + lldbplatformutil.getDarwinOSTriples())
def setUp(self):
# Call super's setUp().
TestBase.setUp(self)
# Find the line number to break inside main().
self.line = line_number("main.cpp", "// breakpoint")
+ def setup_test(self, solibs):
+ if lldb.remote_platform:
+ path = lldb.remote_platform.GetWorkingDirectory()
+ for f in solibs:
+ lldbutil.install_to_target(self, self.getBuildArtifact(f))
+ else:
+ path = self.getBuildDir()
+ if self.dylibPath in os.environ:
+ sep = self.platformContext.shlib_path_separator
+ path = os.environ[self.dylibPath] + sep + path
+ self.runCmd(
+ "settings append target.env-vars '{}={}'".format(self.dylibPath, path)
+ )
+ self.default_path = path
+
def test_launch_notifications(self):
"""Test that lldb broadcasts newly loaded libraries in batches."""
+
+ expected_solibs = [
+ "lib_a." + self.platformContext.shlib_extension,
+ "lib_b." + self.platformContext.shlib_extension,
+ "lib_c." + self.platformContext.shlib_extension,
+ "lib_d." + self.platformContext.shlib_extension,
+ ]
+
self.build()
+ self.setup_test(expected_solibs)
+
exe = self.getBuildArtifact("a.out")
self.dbg.SetAsync(False)
@@ -70,6 +95,8 @@ class ModuleLoadedNotifysTestCase(TestBase):
total_modules_added_events = 0
total_modules_removed_events = 0
already_loaded_modules = []
+ max_solibs_per_event = 0
+ max_solib_chunk_per_event = []
while listener.GetNextEvent(event):
if lldb.SBTarget.EventIsTargetEvent(event):
if event.GetType() == lldb.SBTarget.eBroadcastBitModulesLoaded:
@@ -91,12 +118,17 @@ class ModuleLoadedNotifysTestCase(TestBase):
"{} is already loaded".format(module),
)
already_loaded_modules.append(module)
- if self.TraceOn():
- added_files.append(module.GetFileSpec().GetFilename())
+ added_files.append(module.GetFileSpec().GetFilename())
if self.TraceOn():
# print all of the binaries that have been added
print("Loaded files: %s" % (", ".join(added_files)))
+ # We will check the latest biggest chunk of loaded solibs.
+ # We expect all of our solibs in the last chunk of loaded modules.
+ if solib_count >= max_solibs_per_event:
+ max_solib_chunk_per_event = added_files.copy()
+ max_solibs_per_event = solib_count
+
if event.GetType() == lldb.SBTarget.eBroadcastBitModulesUnloaded:
solib_count = lldb.SBTarget.GetNumModulesFromEvent(event)
total_modules_removed_events += 1
@@ -115,9 +147,7 @@ class ModuleLoadedNotifysTestCase(TestBase):
# binaries in batches. Check that we got back more than 1 solib per event.
# In practice on Darwin today, we get back two events for a do-nothing c
# program: a.out and dyld, and then all the rest of the system libraries.
- # On Linux we get events for ld.so, [vdso], the binary and then all libraries.
-
- avg_solibs_added_per_event = round(
- float(total_solibs_added) / float(total_modules_added_events)
- )
- self.assertGreater(avg_solibs_added_per_event, 1)
+ # On Linux we get events for ld.so, [vdso], the binary and then all libraries,
+ # but the different configurations could load a different number of .so modules
+ # per event.
+ self.assertLessEqual(set(expected_solibs), set(max_solib_chunk_per_event))
diff --git a/lldb/test/API/functionalities/target-new-solib-notifications/a.cpp b/lldb/test/API/functionalities/target-new-solib-notifications/a.cpp
new file mode 100644
index 000000000000..778b46ed5cef
--- /dev/null
+++ b/lldb/test/API/functionalities/target-new-solib-notifications/a.cpp
@@ -0,0 +1,3 @@
+extern "C" int b_function();
+
+extern "C" int a_function() { return b_function(); }
diff --git a/lldb/test/API/functionalities/target-new-solib-notifications/b.cpp b/lldb/test/API/functionalities/target-new-solib-notifications/b.cpp
new file mode 100644
index 000000000000..4f1a4032ee0e
--- /dev/null
+++ b/lldb/test/API/functionalities/target-new-solib-notifications/b.cpp
@@ -0,0 +1 @@
+extern "C" int b_function() { return 500; }
diff --git a/lldb/test/API/functionalities/target-new-solib-notifications/c.cpp b/lldb/test/API/functionalities/target-new-solib-notifications/c.cpp
new file mode 100644
index 000000000000..8abd1b155a75
--- /dev/null
+++ b/lldb/test/API/functionalities/target-new-solib-notifications/c.cpp
@@ -0,0 +1 @@
+extern "C" int c_function() { return 600; }
diff --git a/lldb/test/API/functionalities/target-new-solib-notifications/d.cpp b/lldb/test/API/functionalities/target-new-solib-notifications/d.cpp
new file mode 100644
index 000000000000..58888a29ba32
--- /dev/null
+++ b/lldb/test/API/functionalities/target-new-solib-notifications/d.cpp
@@ -0,0 +1 @@
+extern "C" int d_function() { return 700; }
diff --git a/lldb/test/API/functionalities/target-new-solib-notifications/main.cpp b/lldb/test/API/functionalities/target-new-solib-notifications/main.cpp
index 00130c93b886..77b38c5ccdc6 100644
--- a/lldb/test/API/functionalities/target-new-solib-notifications/main.cpp
+++ b/lldb/test/API/functionalities/target-new-solib-notifications/main.cpp
@@ -1,6 +1,16 @@
-#include <stdio.h>
-int main ()
-{
- puts("running"); // breakpoint here
- return 0;
-}
+#include <stdio.h>
+
+extern "C" int a_function();
+extern "C" int c_function();
+extern "C" int b_function();
+extern "C" int d_function();
+
+int main() {
+ a_function();
+ b_function();
+ c_function();
+ d_function();
+
+ puts("running"); // breakpoint here
+ return 0;
+}
diff --git a/lldb/test/API/functionalities/thread_plan/wrap_step_over.py b/lldb/test/API/functionalities/thread_plan/wrap_step_over.py
index 802aaf2d3ffd..ebb795abfa0e 100644
--- a/lldb/test/API/functionalities/thread_plan/wrap_step_over.py
+++ b/lldb/test/API/functionalities/thread_plan/wrap_step_over.py
@@ -2,7 +2,7 @@ import lldb
class WrapStepOver:
- def __init__(self, thread_plan, args_data, dict):
+ def __init__(self, thread_plan, args_data):
self.plan = thread_plan
thread = thread_plan.GetThread()
target = thread.GetProcess().GetTarget()
diff --git a/lldb/test/API/functionalities/type_types/Makefile b/lldb/test/API/functionalities/type_types/Makefile
new file mode 100644
index 000000000000..3d0b98f13f3d
--- /dev/null
+++ b/lldb/test/API/functionalities/type_types/Makefile
@@ -0,0 +1,2 @@
+CXX_SOURCES := main.cpp
+include Makefile.rules
diff --git a/lldb/test/API/functionalities/type_types/TestFindTypes.py b/lldb/test/API/functionalities/type_types/TestFindTypes.py
new file mode 100644
index 000000000000..42b5c4cfaaf7
--- /dev/null
+++ b/lldb/test/API/functionalities/type_types/TestFindTypes.py
@@ -0,0 +1,66 @@
+"""
+Test the SBModule and SBTarget type lookup APIs to find multiple types.
+"""
+
+import lldb
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
+
+
+class TypeFindFirstTestCase(TestBase):
+ def test_find_first_type(self):
+ """
+ Test SBTarget::FindTypes() and SBModule::FindTypes() APIs.
+
+ We had issues where our declaration context when finding types was
+ incorrectly calculated where a type in a namepace, and a type in a
+ function that was also in the same namespace would match a lookup. For
+ example:
+
+ namespace a {
+ struct Foo {
+ int foo;
+ };
+
+ unsigned foo() {
+ typedef unsigned Foo;
+ Foo foo = 12;
+ return foo;
+ }
+ } // namespace a
+
+
+ Previously LLDB would calculate the declaration context of "a::Foo"
+ correctly, but incorrectly calculate the declaration context of "Foo"
+ from within the foo() function as "a::Foo". Adding tests to ensure this
+ works correctly.
+ """
+ self.build()
+ target = self.createTestTarget()
+ exe_module = target.GetModuleAtIndex(0)
+ self.assertTrue(exe_module.IsValid())
+ # Test the SBTarget and SBModule APIs for FindFirstType
+ for api in [target, exe_module]:
+ # We should find the "a::Foo" but not the "Foo" type in the function
+ types = api.FindTypes("a::Foo")
+ self.assertEqual(types.GetSize(), 1)
+ type_str0 = str(types.GetTypeAtIndex(0))
+ self.assertIn('struct Foo {', type_str0)
+
+ # When we search by type basename, we should find any type whose
+ # basename matches "Foo", so "a::Foo" and the "Foo" type in the
+ # function.
+ types = api.FindTypes("Foo")
+ self.assertEqual(types.GetSize(), 2)
+ type_str0 = str(types.GetTypeAtIndex(0))
+ type_str1 = str(types.GetTypeAtIndex(1))
+ # We don't know which order the types will come back as, so
+ self.assertEqual(set([str(t).split('\n')[0] for t in types]), set(["typedef Foo", "struct Foo {"]))
+
+ # When we search by type basename with "::" prepended, we should
+ # only types in the root namespace which means only "Foo" type in
+ # the function.
+ types = api.FindTypes("::Foo")
+ self.assertEqual(types.GetSize(), 1)
+ type_str0 = str(types.GetTypeAtIndex(0))
+ self.assertIn('typedef Foo', type_str0)
diff --git a/lldb/test/API/functionalities/type_types/main.cpp b/lldb/test/API/functionalities/type_types/main.cpp
new file mode 100644
index 000000000000..095328932cdc
--- /dev/null
+++ b/lldb/test/API/functionalities/type_types/main.cpp
@@ -0,0 +1,15 @@
+namespace a {
+struct Foo {};
+
+unsigned foo() {
+ typedef unsigned Foo;
+ Foo foo = 12;
+ return foo;
+}
+} // namespace a
+
+int main() {
+ a::Foo f = {};
+ a::foo();
+ return 0;
+}