1 """Test Python APIs for working with formatters""" 2 3 import os, sys, time 4 import unittest2 5 import lldb 6 from lldbtest import * 7 import lldbutil 8 9 class SBFormattersAPITestCase(TestBase): 10 11 mydir = os.path.join("python_api", "formatters") 12 13 @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin") 14 @python_api_test 15 @dsym_test 16 def test_with_dsym_formatters_api(self): 17 """Test Python APIs for working with formatters""" 18 self.buildDsym() 19 self.setTearDownCleanup() 20 self.formatters() 21 22 @python_api_test 23 @dwarf_test 24 def test_with_dwarf_formatters_api(self): 25 """Test Python APIs for working with formatters""" 26 self.buildDwarf() 27 self.setTearDownCleanup() 28 self.formatters() 29 30 @python_api_test 31 def test_force_synth_off(self): 32 """Test that one can have the public API return non-synthetic SBValues if desired""" 33 self.buildDwarf(dictionary={'EXE':'no_synth'}) 34 self.setTearDownCleanup() 35 self.force_synth_off() 36 37 def setUp(self): 38 # Call super's setUp(). 39 TestBase.setUp(self) 40 self.line = line_number('main.cpp', '// Set break point at this line.') 41 42 def formatters(self): 43 """Test Python APIs for working with formatters""" 44 self.runCmd("file a.out", CURRENT_EXECUTABLE_SET) 45 46 lldbutil.run_break_set_by_file_and_line (self, "main.cpp", self.line, num_expected_locations=1, loc_exact=True) 47 48 self.runCmd("run", RUN_SUCCEEDED) 49 50 # The stop reason of the thread should be breakpoint. 51 self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, 52 substrs = ['stopped', 53 'stop reason = breakpoint']) 54 55 # This is the function to remove the custom formats in order to have a 56 # clean slate for the next test case. 57 def cleanup(): 58 self.runCmd('type format clear', check=False) 59 self.runCmd('type summary clear', check=False) 60 self.runCmd('type filter clear', check=False) 61 self.runCmd('type synthetic clear', check=False) 62 self.runCmd('type category delete foobar', check=False) 63 self.runCmd('type category delete JASSynth', check=False) 64 self.runCmd('type category delete newbar', check=False) 65 66 # Execute the cleanup function during test case tear down. 67 self.addTearDownHook(cleanup) 68 69 70 format = lldb.SBTypeFormat(lldb.eFormatHex) 71 category = self.dbg.GetDefaultCategory() 72 category.AddTypeFormat(lldb.SBTypeNameSpecifier("int"),format) 73 74 self.expect("frame variable foo.A", 75 substrs = ['0x00000001']) 76 self.expect("frame variable foo.E", matching=False, 77 substrs = ['b8cca70a']) 78 79 category.AddTypeFormat(lldb.SBTypeNameSpecifier("long"),format) 80 self.expect("frame variable foo.A", 81 substrs = ['0x00000001']) 82 self.expect("frame variable foo.E", 83 substrs = ['b8cca70a']) 84 85 format.format = lldb.eFormatOctal 86 category.AddTypeFormat(lldb.SBTypeNameSpecifier("int"),format) 87 self.expect("frame variable foo.A", 88 substrs = ['01']) 89 self.expect("frame variable foo.E", 90 substrs = ['b8cca70a']) 91 92 category.DeleteTypeFormat(lldb.SBTypeNameSpecifier("int")) 93 category.DeleteTypeFormat(lldb.SBTypeNameSpecifier("long")) 94 self.expect("frame variable foo.A", matching=False, 95 substrs = ['01']) 96 self.expect("frame variable foo.E", matching=False, 97 substrs = ['b8cca70a']) 98 99 summary = lldb.SBTypeSummary.CreateWithSummaryString("the hello world you'll never see") 100 summary.SetSummaryString('hello world') 101 new_category = self.dbg.GetCategory("foobar") 102 self.assertFalse(new_category.IsValid(), "getting a non-existing category worked") 103 new_category = self.dbg.CreateCategory("foobar") 104 new_category.enabled = True 105 new_category.AddTypeSummary(lldb.SBTypeNameSpecifier("^.*t$",True),summary) 106 self.expect("frame variable foo.A", 107 substrs = ['hello world']) 108 self.expect("frame variable foo.E", matching=False, 109 substrs = ['hello world']) 110 self.expect("frame variable foo.B", 111 substrs = ['hello world']) 112 self.expect("frame variable foo.F", 113 substrs = ['hello world']) 114 new_category.enabled = False 115 self.expect("frame variable foo.A", matching=False, 116 substrs = ['hello world']) 117 self.expect("frame variable foo.E", matching=False, 118 substrs = ['hello world']) 119 self.expect("frame variable foo.B", matching=False, 120 substrs = ['hello world']) 121 self.expect("frame variable foo.F", matching=False, 122 substrs = ['hello world']) 123 self.dbg.DeleteCategory(new_category.GetName()) 124 self.expect("frame variable foo.A", matching=False, 125 substrs = ['hello world']) 126 self.expect("frame variable foo.E", matching=False, 127 substrs = ['hello world']) 128 self.expect("frame variable foo.B", matching=False, 129 substrs = ['hello world']) 130 self.expect("frame variable foo.F", matching=False, 131 substrs = ['hello world']) 132 133 filter = lldb.SBTypeFilter(0) 134 filter.AppendExpressionPath("A") 135 filter.AppendExpressionPath("D") 136 self.assertTrue(filter.GetNumberOfExpressionPaths() == 2, "filter with two items does not have two items") 137 138 category.AddTypeFilter(lldb.SBTypeNameSpecifier("JustAStruct"),filter) 139 self.expect("frame variable foo", 140 substrs = ['A = 1', 'D = 6.28']) 141 self.expect("frame variable foo", matching=False, 142 substrs = ['B = ', 'C = ', 'E = ', 'F = ']) 143 144 category.DeleteTypeFilter(lldb.SBTypeNameSpecifier("JustAStruct",True)) 145 self.expect("frame variable foo", 146 substrs = ['A = 1', 'D = 6.28']) 147 self.expect("frame variable foo", matching=False, 148 substrs = ['B = ', 'C = ', 'E = ', 'F = ']) 149 150 category.DeleteTypeFilter(lldb.SBTypeNameSpecifier("JustAStruct",False)) 151 self.expect("frame variable foo", 152 substrs = ['A = 1', 'D = 6.28']) 153 self.expect("frame variable foo", matching=True, 154 substrs = ['B = ', 'C = ', 'E = ', 'F = ']) 155 156 self.runCmd("command script import --allow-reload ./jas_synth.py") 157 158 self.expect("frame variable foo", matching=False, 159 substrs = ['X = 1']) 160 161 self.dbg.GetCategory("JASSynth").SetEnabled(True) 162 self.expect("frame variable foo", matching=True, 163 substrs = ['X = 1']) 164 165 foo_var = self.dbg.GetSelectedTarget().GetProcess().GetSelectedThread().GetSelectedFrame().FindVariable('foo') 166 self.assertTrue(foo_var.IsValid(), 'could not find foo') 167 168 self.assertTrue(foo_var.GetNumChildren() == 2, 'synthetic value has wrong number of child items (synth)') 169 self.assertTrue(foo_var.GetChildMemberWithName('X').GetValueAsUnsigned() == 1, 'foo_synth.X has wrong value (synth)') 170 self.assertFalse(foo_var.GetChildMemberWithName('B').IsValid(), 'foo_synth.B is valid but should not (synth)') 171 172 self.dbg.GetCategory("JASSynth").SetEnabled(False) 173 foo_var = self.dbg.GetSelectedTarget().GetProcess().GetSelectedThread().GetSelectedFrame().FindVariable('foo') 174 self.assertTrue(foo_var.IsValid(), 'could not find foo') 175 176 self.assertFalse(foo_var.GetNumChildren() == 2, 'still seeing synthetic value') 177 178 filter = lldb.SBTypeFilter(0) 179 filter.AppendExpressionPath("A") 180 filter.AppendExpressionPath("D") 181 category.AddTypeFilter(lldb.SBTypeNameSpecifier("JustAStruct"),filter) 182 self.expect("frame variable foo", 183 substrs = ['A = 1', 'D = 6.28']) 184 185 foo_var = self.dbg.GetSelectedTarget().GetProcess().GetSelectedThread().GetSelectedFrame().FindVariable('foo') 186 self.assertTrue(foo_var.IsValid(), 'could not find foo') 187 188 self.assertTrue(foo_var.GetNumChildren() == 2, 'synthetic value has wrong number of child items (filter)') 189 self.assertTrue(foo_var.GetChildMemberWithName('X').GetValueAsUnsigned() == 0, 'foo_synth.X has wrong value (filter)') 190 self.assertTrue(foo_var.GetChildMemberWithName('A').GetValueAsUnsigned() == 1, 'foo_synth.A has wrong value (filter)') 191 192 self.assertTrue(filter.ReplaceExpressionPathAtIndex(0,"C"), "failed to replace an expression path in filter") 193 self.expect("frame variable foo", 194 substrs = ['A = 1', 'D = 6.28']) 195 category.AddTypeFilter(lldb.SBTypeNameSpecifier("JustAStruct"),filter) 196 self.expect("frame variable foo", 197 substrs = ["C = 'e'", 'D = 6.28']) 198 category.AddTypeFilter(lldb.SBTypeNameSpecifier("FooType"),filter) 199 filter.ReplaceExpressionPathAtIndex(1,"F") 200 self.expect("frame variable foo", 201 substrs = ["C = 'e'", 'D = 6.28']) 202 category.AddTypeFilter(lldb.SBTypeNameSpecifier("JustAStruct"),filter) 203 self.expect("frame variable foo", 204 substrs = ["C = 'e'", 'F = 0']) 205 self.expect("frame variable bar", 206 substrs = ["C = 'e'", 'D = 6.28']) 207 208 foo_var = self.dbg.GetSelectedTarget().GetProcess().GetSelectedThread().GetSelectedFrame().FindVariable('foo') 209 self.assertTrue(foo_var.IsValid(), 'could not find foo') 210 self.assertTrue(foo_var.GetChildMemberWithName('C').GetValueAsUnsigned() == ord('e'), 'foo_synth.C has wrong value (filter)') 211 212 chosen = self.dbg.GetFilterForType(lldb.SBTypeNameSpecifier("JustAStruct")) 213 self.assertTrue(chosen.count == 2, "wrong filter found for JustAStruct") 214 self.assertTrue(chosen.GetExpressionPathAtIndex(0) == 'C', "wrong item at index 0 for JustAStruct") 215 self.assertTrue(chosen.GetExpressionPathAtIndex(1) == 'F', "wrong item at index 1 for JustAStruct") 216 217 self.assertFalse(category.DeleteTypeFilter(lldb.SBTypeNameSpecifier("NoSuchType")),"deleting a non-existing filter worked") 218 self.assertFalse(category.DeleteTypeSummary(lldb.SBTypeNameSpecifier("NoSuchType")),"deleting a non-existing summary worked") 219 self.assertFalse(category.DeleteTypeFormat(lldb.SBTypeNameSpecifier("NoSuchType")),"deleting a non-existing format worked") 220 self.assertFalse(category.DeleteTypeSynthetic(lldb.SBTypeNameSpecifier("NoSuchType")),"deleting a non-existing synthetic worked") 221 222 self.assertFalse(category.DeleteTypeFilter(lldb.SBTypeNameSpecifier("")),"deleting a filter for '' worked") 223 self.assertFalse(category.DeleteTypeSummary(lldb.SBTypeNameSpecifier("")),"deleting a summary for '' worked") 224 self.assertFalse(category.DeleteTypeFormat(lldb.SBTypeNameSpecifier("")),"deleting a format for '' worked") 225 self.assertFalse(category.DeleteTypeSynthetic(lldb.SBTypeNameSpecifier("")),"deleting a synthetic for '' worked") 226 227 try: 228 self.assertFalse(category.AddTypeSummary(lldb.SBTypeNameSpecifier("NoneSuchType"), None), "adding a summary valued None worked") 229 except: 230 pass 231 else: 232 self.assertFalse(True, "adding a summary valued None worked") 233 234 try: 235 self.assertFalse(category.AddTypeFilter(lldb.SBTypeNameSpecifier("NoneSuchType"), None), "adding a filter valued None worked") 236 except: 237 pass 238 else: 239 self.assertFalse(True, "adding a filter valued None worked") 240 241 try: 242 self.assertFalse(category.AddTypeSynthetic(lldb.SBTypeNameSpecifier("NoneSuchType"), None), "adding a synthetic valued None worked") 243 except: 244 pass 245 else: 246 self.assertFalse(True, "adding a synthetic valued None worked") 247 248 try: 249 self.assertFalse(category.AddTypeFormat(lldb.SBTypeNameSpecifier("NoneSuchType"), None), "adding a format valued None worked") 250 except: 251 pass 252 else: 253 self.assertFalse(True, "adding a format valued None worked") 254 255 256 self.assertFalse(category.AddTypeSummary(lldb.SBTypeNameSpecifier("EmptySuchType"), lldb.SBTypeSummary()), "adding a summary without value worked") 257 self.assertFalse(category.AddTypeFilter(lldb.SBTypeNameSpecifier("EmptySuchType"), lldb.SBTypeFilter()), "adding a filter without value worked") 258 self.assertFalse(category.AddTypeSynthetic(lldb.SBTypeNameSpecifier("EmptySuchType"), lldb.SBTypeSynthetic()), "adding a synthetic without value worked") 259 self.assertFalse(category.AddTypeFormat(lldb.SBTypeNameSpecifier("EmptySuchType"), lldb.SBTypeFormat()), "adding a format without value worked") 260 261 self.assertFalse(category.AddTypeSummary(lldb.SBTypeNameSpecifier(""), lldb.SBTypeSummary.CreateWithSummaryString("")), "adding a summary for an invalid type worked") 262 self.assertFalse(category.AddTypeFilter(lldb.SBTypeNameSpecifier(""), lldb.SBTypeFilter(0)), "adding a filter for an invalid type worked") 263 self.assertFalse(category.AddTypeSynthetic(lldb.SBTypeNameSpecifier(""), lldb.SBTypeSynthetic.CreateWithClassName("")), "adding a synthetic for an invalid type worked") 264 self.assertFalse(category.AddTypeFormat(lldb.SBTypeNameSpecifier(""), lldb.SBTypeFormat(lldb.eFormatHex)), "adding a format for an invalid type worked") 265 266 new_category = self.dbg.CreateCategory("newbar") 267 new_category.AddTypeSummary(lldb.SBTypeNameSpecifier("JustAStruct"), 268 lldb.SBTypeSummary.CreateWithScriptCode("return 'hello scripted world';")) 269 self.expect("frame variable foo", matching=False, 270 substrs = ['hello scripted world']) 271 new_category.enabled = True 272 self.expect("frame variable foo", matching=True, 273 substrs = ['hello scripted world']) 274 275 self.expect("frame variable foo_ptr", matching=True, 276 substrs = ['hello scripted world']) 277 new_category.AddTypeSummary(lldb.SBTypeNameSpecifier("JustAStruct"), 278 lldb.SBTypeSummary.CreateWithScriptCode("return 'hello scripted world';", 279 lldb.eTypeOptionSkipPointers)) 280 self.expect("frame variable foo", matching=True, 281 substrs = ['hello scripted world']) 282 283 frame = self.dbg.GetSelectedTarget().GetProcess().GetSelectedThread().GetSelectedFrame() 284 foo_ptr = frame.FindVariable("foo_ptr") 285 summary = foo_ptr.GetTypeSummary() 286 287 self.assertFalse(summary.IsValid(), "summary found for foo* when none was planned") 288 289 self.expect("frame variable foo_ptr", matching=False, 290 substrs = ['hello scripted world']) 291 292 new_category.AddTypeSummary(lldb.SBTypeNameSpecifier("JustAStruct"), 293 lldb.SBTypeSummary.CreateWithSummaryString("hello static world", 294 lldb.eTypeOptionNone)) 295 296 summary = foo_ptr.GetTypeSummary() 297 298 self.assertTrue(summary.IsValid(), "no summary found for foo* when one was in place") 299 self.assertTrue(summary.GetData() == "hello static world", "wrong summary found for foo*") 300 301 def force_synth_off(self): 302 """Test that one can have the public API return non-synthetic SBValues if desired""" 303 self.runCmd("file no_synth", CURRENT_EXECUTABLE_SET) 304 305 lldbutil.run_break_set_by_file_and_line (self, "main.cpp", self.line, num_expected_locations=1, loc_exact=True) 306 307 self.runCmd("run", RUN_SUCCEEDED) 308 309 # The stop reason of the thread should be breakpoint. 310 self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, 311 substrs = ['stopped', 312 'stop reason = breakpoint']) 313 314 # This is the function to remove the custom formats in order to have a 315 # clean slate for the next test case. 316 def cleanup(): 317 self.runCmd('type format clear', check=False) 318 self.runCmd('type summary clear', check=False) 319 self.runCmd('type filter clear', check=False) 320 self.runCmd('type synthetic clear', check=False) 321 self.runCmd('type category delete foobar', check=False) 322 self.runCmd('type category delete JASSynth', check=False) 323 self.runCmd('type category delete newbar', check=False) 324 self.runCmd('settings set target.enable-synthetic-value true') 325 326 # Execute the cleanup function during test case tear down. 327 self.addTearDownHook(cleanup) 328 329 frame = self.dbg.GetSelectedTarget().GetProcess().GetSelectedThread().GetSelectedFrame() 330 int_vector = frame.FindVariable("int_vector") 331 if self.TraceOn(): 332 print int_vector 333 self.assertTrue(int_vector.GetNumChildren() == 0, 'synthetic vector is empty') 334 335 self.runCmd('settings set target.enable-synthetic-value false') 336 frame = self.dbg.GetSelectedTarget().GetProcess().GetSelectedThread().GetSelectedFrame() 337 int_vector = frame.FindVariable("int_vector") 338 if self.TraceOn(): 339 print int_vector 340 self.assertFalse(int_vector.GetNumChildren() == 0, '"physical" vector is not empty') 341 342 self.runCmd('settings set target.enable-synthetic-value true') 343 frame = self.dbg.GetSelectedTarget().GetProcess().GetSelectedThread().GetSelectedFrame() 344 int_vector = frame.FindVariable("int_vector") 345 if self.TraceOn(): 346 print int_vector 347 self.assertTrue(int_vector.GetNumChildren() == 0, 'synthetic vector is still empty') 348 349 350 if __name__ == '__main__': 351 import atexit 352 lldb.SBDebugger.Initialize() 353 atexit.register(lambda: lldb.SBDebugger.Terminate()) 354 unittest2.main() 355