1""" 2Test how many times newly loaded binaries are notified; 3they should be delivered in batches instead of one-by-one. 4""" 5 6from __future__ import print_function 7 8 9import lldb 10from lldbsuite.test.decorators import * 11from lldbsuite.test.lldbtest import * 12from lldbsuite.test import lldbutil 13 14class ModuleLoadedNotifysTestCase(TestBase): 15 16 mydir = TestBase.compute_mydir(__file__) 17 NO_DEBUG_INFO_TESTCASE = True 18 19 # DynamicLoaderDarwin should batch up notifications about 20 # newly added/removed libraries. Other DynamicLoaders may 21 # not be written this way. 22 @skipUnlessDarwin 23 24 def setUp(self): 25 # Call super's setUp(). 26 TestBase.setUp(self) 27 # Find the line number to break inside main(). 28 self.line = line_number('main.cpp', '// breakpoint') 29 30 def test_launch_notifications(self): 31 """Test that lldb broadcasts newly loaded libraries in batches.""" 32 self.build() 33 exe = self.getBuildArtifact("a.out") 34 self.dbg.SetAsync(False) 35 36 listener = self.dbg.GetListener() 37 listener.StartListeningForEventClass( 38 self.dbg, 39 lldb.SBTarget.GetBroadcasterClassName(), 40 lldb.SBTarget.eBroadcastBitModulesLoaded | lldb.SBTarget.eBroadcastBitModulesUnloaded) 41 42 # Create a target by the debugger. 43 target = self.dbg.CreateTarget(exe) 44 self.assertTrue(target, VALID_TARGET) 45 46 # break on main 47 breakpoint = target.BreakpointCreateByName('main', 'a.out') 48 49 event = lldb.SBEvent() 50 # CreateTarget() generated modules-loaded events; consume them & toss 51 while listener.GetNextEvent(event): 52 True 53 54 error = lldb.SBError() 55 flags = target.GetLaunchInfo().GetLaunchFlags() 56 process = target.Launch(listener, 57 None, # argv 58 None, # envp 59 None, # stdin_path 60 None, # stdout_path 61 None, # stderr_path 62 None, # working directory 63 flags, # launch flags 64 False, # Stop at entry 65 error) # error 66 67 self.assertTrue( 68 process.GetState() == lldb.eStateStopped, 69 PROCESS_STOPPED) 70 71 total_solibs_added = 0 72 total_solibs_removed = 0 73 total_modules_added_events = 0 74 total_modules_removed_events = 0 75 while listener.GetNextEvent(event): 76 if lldb.SBTarget.EventIsTargetEvent(event): 77 if event.GetType() == lldb.SBTarget.eBroadcastBitModulesLoaded: 78 solib_count = lldb.SBTarget.GetNumModulesFromEvent(event) 79 total_modules_added_events += 1 80 total_solibs_added += solib_count 81 if self.TraceOn(): 82 # print all of the binaries that have been added 83 added_files = [] 84 i = 0 85 while i < solib_count: 86 module = lldb.SBTarget.GetModuleAtIndexFromEvent(i, event) 87 added_files.append(module.GetFileSpec().GetFilename()) 88 i = i + 1 89 print("Loaded files: %s" % (', '.join(added_files))) 90 91 if event.GetType() == lldb.SBTarget.eBroadcastBitModulesUnloaded: 92 solib_count = lldb.SBTarget.GetNumModulesFromEvent(event) 93 total_modules_removed_events += 1 94 total_solibs_removed += solib_count 95 if self.TraceOn(): 96 # print all of the binaries that have been removed 97 removed_files = [] 98 i = 0 99 while i < solib_count: 100 module = lldb.SBTarget.GetModuleAtIndexFromEvent(i, event) 101 removed_files.append(module.GetFileSpec().GetFilename()) 102 i = i + 1 103 print("Unloaded files: %s" % (', '.join(removed_files))) 104 105 106 # This is testing that we get back a small number of events with the loaded 107 # binaries in batches. Check that we got back more than 1 solib per event. 108 # In practice on Darwin today, we get back two events for a do-nothing c 109 # program: a.out and dyld, and then all the rest of the system libraries. 110 111 avg_solibs_added_per_event = int(float(total_solibs_added) / float(total_modules_added_events)) 112 self.assertGreater(avg_solibs_added_per_event, 1) 113