1# coding=utf8 2""" 3Test lldb data formatter subsystem. 4""" 5 6 7 8import lldb 9from lldbsuite.test.decorators import * 10from lldbsuite.test.lldbtest import * 11from lldbsuite.test import lldbutil 12 13 14class LibcxxStringDataFormatterTestCase(TestBase): 15 16 def setUp(self): 17 # Call super's setUp(). 18 TestBase.setUp(self) 19 # Find the line number to break at. 20 self.main_spec = lldb.SBFileSpec("main.cpp") 21 self.namespace = 'std' 22 23 @add_test_categories(["libc++"]) 24 @expectedFailureAll(bugnumber="llvm.org/pr36109", debug_info="gmodules", triple=".*-android") 25 # Inline namespace is randomly ignored as Clang due to broken lookup inside 26 # the std namespace. 27 @expectedFailureAll(debug_info="gmodules") 28 def test_with_run_command(self): 29 """Test that that file and class static variables display correctly.""" 30 self.build() 31 32 (target, process, thread, bkpt) = lldbutil.run_to_source_breakpoint(self, 33 "Set break point at this line.", 34 self.main_spec) 35 frame = thread.frames[0] 36 37 # This is the function to remove the custom formats in order to have a 38 # clean slate for the next test case. 39 def cleanup(): 40 self.runCmd('type format clear', check=False) 41 self.runCmd('type summary clear', check=False) 42 self.runCmd('type filter clear', check=False) 43 self.runCmd('type synth clear', check=False) 44 self.runCmd( 45 "settings set target.max-children-count 256", 46 check=False) 47 48 is_64_bit = self.process().GetAddressByteSize() == 8 49 50 # Execute the cleanup function during test case tear down. 51 self.addTearDownHook(cleanup) 52 53 ns = self.namespace 54 self.expect( 55 "frame variable", 56 substrs=[ 57 '(%s::wstring) wempty = L""'%ns, 58 '(%s::wstring) s = L"hello world! מזל טוב!"'%ns, 59 '(%s::wstring) S = L"!!!!"'%ns, 60 '(const wchar_t *) mazeltov = 0x', 61 'L"מזל טוב"', 62 '(%s::string) empty = ""'%ns, 63 '(%s::string) q = "hello world"'%ns, 64 '(%s::string) Q = "quite a long std::strin with lots of info inside it"'%ns, 65 '(%s::string) IHaveEmbeddedZeros = "a\\0b\\0c\\0d"'%ns, 66 '(%s::wstring) IHaveEmbeddedZerosToo = L"hello world!\\0てざ ル゜䋨ミ㠧槊 きゅへ狦穤襩 じゃ馩リョ 䤦監"'%ns, 67 '(%s::u16string) u16_string = u"ß水氶"'%ns, 68 # FIXME: This should have a 'u' prefix. 69 '(%s::u16string) u16_empty = ""'%ns, 70 '(%s::u32string) u32_string = U""'%ns, 71 # FIXME: This should have a 'U' prefix. 72 '(%s::u32string) u32_empty = ""'%ns, 73 '(%s::basic_string<unsigned char, %s::char_traits<unsigned char>, ' 74 '%s::allocator<unsigned char> >) uchar = "aaaaa"'%(ns,ns,ns), 75 '(%s::string *) null_str = nullptr'%ns, 76 ]) 77 78 thread.StepOver() 79 80 TheVeryLongOne = frame.FindVariable("TheVeryLongOne") 81 summaryOptions = lldb.SBTypeSummaryOptions() 82 summaryOptions.SetCapping(lldb.eTypeSummaryUncapped) 83 uncappedSummaryStream = lldb.SBStream() 84 TheVeryLongOne.GetSummary(uncappedSummaryStream, summaryOptions) 85 uncappedSummary = uncappedSummaryStream.GetData() 86 self.assertTrue(uncappedSummary.find("someText") > 0, 87 "uncappedSummary does not include the full string") 88 summaryOptions.SetCapping(lldb.eTypeSummaryCapped) 89 cappedSummaryStream = lldb.SBStream() 90 TheVeryLongOne.GetSummary(cappedSummaryStream, summaryOptions) 91 cappedSummary = cappedSummaryStream.GetData() 92 self.assertTrue( 93 cappedSummary.find("someText") <= 0, 94 "cappedSummary includes the full string") 95 96 self.expect_expr("s", result_type=ns+"::wstring", result_summary='L"hello world! מזל טוב!"') 97 98 self.expect( 99 "frame variable", 100 substrs=[ 101 '(%s::wstring) S = L"!!!!!"'%ns, 102 '(const wchar_t *) mazeltov = 0x', 103 'L"מזל טוב"', 104 '(%s::string) q = "hello world"'%ns, 105 '(%s::string) Q = "quite a long std::strin with lots of info inside it"'%ns, 106 '(%s::string) IHaveEmbeddedZeros = "a\\0b\\0c\\0d"'%ns, 107 '(%s::wstring) IHaveEmbeddedZerosToo = L"hello world!\\0てざ ル゜䋨ミ㠧槊 きゅへ狦穤襩 じゃ馩リョ 䤦監"'%ns, 108 '(%s::u16string) u16_string = u"ß水氶"'%ns, 109 '(%s::u32string) u32_string = U""'%ns, 110 '(%s::u32string) u32_empty = ""'%ns, 111 '(%s::basic_string<unsigned char, %s::char_traits<unsigned char>, ' 112 '%s::allocator<unsigned char> >) uchar = "aaaaa"'%(ns,ns,ns), 113 '(%s::string *) null_str = nullptr'%ns, 114 ]) 115 116 # The test assumes that std::string is in its cap-size-data layout. 117 is_alternate_layout = ('arm' in self.getArchitecture()) and self.platformIsDarwin() 118 if is_64_bit and not is_alternate_layout: 119 self.expect("frame variable garbage1", substrs=['garbage1 = Summary Unavailable']) 120 self.expect("frame variable garbage2", substrs=[r'garbage2 = "\xfa\xfa\xfa\xfa"']) 121 self.expect("frame variable garbage3", substrs=[r'garbage3 = "\xf0\xf0"']) 122 self.expect("frame variable garbage4", substrs=['garbage4 = Summary Unavailable']) 123 self.expect("frame variable garbage5", substrs=['garbage5 = Summary Unavailable']) 124 125 # Finally, make sure that if the string is not readable, we give an error: 126 bkpt_2 = target.BreakpointCreateBySourceRegex("Break here to look at bad string", self.main_spec) 127 self.assertEqual(bkpt_2.GetNumLocations(), 1, "Got one location") 128 threads = lldbutil.continue_to_breakpoint(process, bkpt_2) 129 self.assertEqual(len(threads), 1, "Stopped at second breakpoint") 130 frame = threads[0].frames[0] 131 var = frame.FindVariable("in_str") 132 self.assertTrue(var.GetError().Success(), "Made variable") 133 summary = var.GetSummary() 134 self.assertEqual(summary, "Summary Unavailable", "No summary for bad value") 135 136