179 lines · python
1"""2Test lldb breakpoint ids.3"""4 5import lldb6from lldbsuite.test.decorators import *7from lldbsuite.test.lldbtest import *8from lldbsuite.test import lldbutil9 10 11class TestCPPBreakpointLocations(TestBase):12 @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24764")13 def test(self):14 self.do_test(dict())15 16 @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24764")17 @skipIf(compiler=no_match("clang"))18 @skipIf(compiler_version=["<", "15.0"])19 def test_simple_template_names(self):20 self.do_test(dict(CFLAGS_EXTRAS="-gsimple-template-names"))21 22 def do_test(self, debug_flags):23 self.build(dictionary=debug_flags)24 self.breakpoint_id_tests()25 26 def verify_breakpoint_locations(self, target, bp_dict):27 name = bp_dict["name"]28 names = bp_dict["loc_names"]29 bp = target.BreakpointCreateByName(name)30 self.assertEqual(31 bp.GetNumLocations(),32 len(names),33 "Make sure we find the right number of breakpoint locations for {}".format(34 name35 ),36 )37 38 bp_loc_names = list()39 for bp_loc in bp:40 bp_loc_names.append(bp_loc.GetAddress().GetFunction().GetName())41 42 for name in names:43 found = name in bp_loc_names44 if not found:45 print("Didn't find '%s' in: %s" % (name, bp_loc_names))46 self.assertTrue(found, "Make sure we find all required locations")47 48 def breakpoint_id_tests(self):49 # Create a target by the debugger.50 exe = self.getBuildArtifact("a.out")51 target = self.dbg.CreateTarget(exe)52 self.assertTrue(target, VALID_TARGET)53 bp_dicts = [54 {55 "name": "func1",56 "loc_names": ["a::c::func1()", "aa::cc::func1()", "b::c::func1()"],57 },58 {59 "name": "func2",60 "loc_names": ["a::c::func2()", "aa::cc::func2()", "c::d::func2()"],61 },62 {63 "name": "func3",64 "loc_names": [65 "a::c::func3()",66 "aa::cc::func3()",67 "b::c::func3()",68 "c::d::func3()",69 ],70 },71 {"name": "c::func1", "loc_names": ["a::c::func1()", "b::c::func1()"]},72 {"name": "c::func2", "loc_names": ["a::c::func2()"]},73 {"name": "c::func3", "loc_names": ["a::c::func3()", "b::c::func3()"]},74 {"name": "a::c::func1", "loc_names": ["a::c::func1()"]},75 {"name": "b::c::func1", "loc_names": ["b::c::func1()"]},76 {"name": "c::d::func2", "loc_names": ["c::d::func2()"]},77 {"name": "a::c::func1()", "loc_names": ["a::c::func1()"]},78 {"name": "b::c::func1()", "loc_names": ["b::c::func1()"]},79 {"name": "c::d::func2()", "loc_names": ["c::d::func2()"]},80 # Template cases81 {"name": "func<float>", "loc_names": []},82 {"name": "Foo::func<float>", "loc_names": []},83 {"name": "ns::Foo::func<float>", "loc_names": []},84 {"name": "func<int>", "loc_names": ["auto ns::Foo<double>::func<int>()"]},85 {86 "name": "Foo<double>::func<int>",87 "loc_names": ["auto ns::Foo<double>::func<int>()"],88 },89 {90 "name": "ns::Foo<double>::func<int>",91 "loc_names": ["auto ns::Foo<double>::func<int>()"],92 },93 {94 "name": "func",95 "loc_names": [96 "auto ns::Foo<double>::func<int>()",97 "auto ns::Foo<double>::func<ns::Foo<int>>()",98 ],99 },100 {"name": "operator", "loc_names": []},101 {102 "name": "ns::Foo<double>::operator bool",103 "loc_names": ["ns::Foo<double>::operator bool()"],104 },105 {106 "name": "operator a::c",107 "loc_names": ["ns::Foo<double>::operator a::c<a::c>()"],108 },109 {110 "name": "operator ns::Foo<int>",111 "loc_names": ["ns::Foo<double>::operator ns::Foo<int><ns::Foo<int>>()"],112 },113 {"name": "operator<<<a::c>", "loc_names": []},114 {115 "name": "operator<<<int>",116 "loc_names": ["void ns::Foo<double>::operator<<<int>(int)"],117 },118 {119 "name": "ns::Foo<double>::operator<<",120 "loc_names": [121 "void ns::Foo<double>::operator<<<int>(int)",122 "void ns::Foo<double>::operator<<<ns::Foo<int>>(ns::Foo<int>)",123 ],124 },125 {"name": "g<float>", "loc_names": []},126 {"name": "g<int>", "loc_names": ["void ns::g<int>()"]},127 {"name": "g<char>", "loc_names": ["void ns::g<char>()"]},128 {"name": "g", "loc_names": ["void ns::g<int>()", "void ns::g<char>()"]},129 {"name": "ns::g<float>", "loc_names": []},130 {"name": "ns::g<int>", "loc_names": ["void ns::g<int>()"]},131 {"name": "ns::g<char>", "loc_names": ["void ns::g<char>()"]},132 {"name": "ns::g", "loc_names": ["void ns::g<int>()", "void ns::g<char>()"]},133 ]134 135 for bp_dict in bp_dicts:136 self.verify_breakpoint_locations(target, bp_dict)137 138 @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24764")139 def test_destructors(self):140 self.build()141 exe = self.getBuildArtifact("a.out")142 target = self.dbg.CreateTarget(exe)143 144 # Don't skip prologue, so we can check the breakpoint address more145 # easily146 self.runCmd("settings set target.skip-prologue false")147 try:148 names = ["~c", "c::~c", "c::~c()"]149 loc_names = {"a::c::~c()", "b::c::~c()"}150 # TODO: For windows targets we should put windows mangled names151 # here152 symbols = ["_ZN1a1cD1Ev", "_ZN1a1cD2Ev", "_ZN1b1cD1Ev", "_ZN1b1cD2Ev"]153 154 for name in names:155 bp = target.BreakpointCreateByName(name)156 157 bp_loc_names = {158 bp_loc.GetAddress().GetFunction().GetName() for bp_loc in bp159 }160 self.assertEqual(161 bp_loc_names, loc_names, "Breakpoint set on the correct symbol"162 )163 164 bp_addresses = {bp_loc.GetLoadAddress() for bp_loc in bp}165 symbol_addresses = set()166 for symbol in symbols:167 sc_list = target.FindSymbols(symbol, lldb.eSymbolTypeCode)168 self.assertEqual(sc_list.GetSize(), 1, "Found symbol " + symbol)169 symbol = sc_list.GetContextAtIndex(0).GetSymbol()170 symbol_addresses.add(171 symbol.GetStartAddress().GetLoadAddress(target)172 )173 174 self.assertEqual(175 symbol_addresses, bp_addresses, "Breakpoint set on correct address"176 )177 finally:178 self.runCmd("settings clear target.skip-prologue")179