def fuzz_obj(obj): obj.AddEvent(lldb.SBEvent()) obj.StartListeningForEvents(lldb.SBBroadcaster(), 0xffffffff) obj.StopListeningForEvents(lldb.SBBroadcaster(), 0xffffffff) event = lldb.SBEvent() broadcaster = lldb.SBBroadcaster() obj.WaitForEvent(5, event) obj.WaitForEventForBroadcaster(5, broadcaster, event) obj.WaitForEventForBroadcasterWithType(5, broadcaster, 0xffffffff, event) obj.PeekAtNextEvent(event) obj.PeekAtNextEventForBroadcaster(broadcaster, event) obj.PeekAtNextEventForBroadcasterWithType(broadcaster, 0xffffffff, event) obj.GetNextEvent(event) obj.GetNextEventForBroadcaster(broadcaster, event) obj.GetNextEventForBroadcasterWithType(broadcaster, 0xffffffff, event) obj.HandleBroadcastEvent(event)
def safe_call(self, method, args=[], sync=False, timeout=None): # threadsafe """ (Thread-safe) Call `method` with `args`. If `sync` is True, wait for `method` to complete and return its value. If timeout is set and non- negative, and the `method` did not complete within `timeout` seconds, an EventLoopError is raised! """ if self._dbg is None: self.logger.critical("Debugger not found!") raise EventLoopError("Dead debugger!") if self.out_queue.full(): # garbage self.out_queue.get() # clean try: self.in_queue.put((method, args, sync), block=False) interrupt = lldb.SBEvent(self.CTRL_VOICE, "the_sound") self._trx.BroadcastEvent(interrupt) if sync: return self.out_queue.get(block=True, timeout=timeout) except Empty: raise EventLoopError("Timed out!") except Full: self.logger.critical("Event loop thread is probably dead!") raise EventLoopError("Dead event loop!")
def run(self): event = lldb.SBEvent() try: timeout_count = 0 # Wait up to 4 times for the event to arrive. while not self.done(timeout_count): if self.trace_on: print("Calling wait for event...") if self.listener.WaitForEvent(self.wait_seconds, event): while event.IsValid(): # Check if it's a process event. if SBProcess.EventIsStructuredDataEvent(event): self.handle_structured_data_event(event) else: if self.trace_on: print("ignoring unexpected event:", lldbutil.get_description(event)) # Grab the next event, if there is one. event.Clear() if not self.listener.GetNextEvent(event): if self.trace_on: print("listener has no more events " "available at this time") else: if self.trace_on: print("timeout occurred waiting for event...") timeout_count += 1 self.listener.Clear() except Exception as e: self.exception = e
def wait_for_stop(self, process, listener): retry_count = 5 if process.GetState() == lldb.eStateStopped or process.GetState( ) == lldb.eStateCrashed or process.GetState( ) == lldb.eStateDetached or process.GetState() == lldb.eStateExited: return True while retry_count > 0: event = lldb.SBEvent() listener.WaitForEvent(2, event) if event.GetType() == lldb.SBProcess.eBroadcastBitStateChanged: if process.GetState( ) == lldb.eStateStopped or process.GetState( ) == lldb.eStateCrashed or process.GetState( ) == lldb.eStateDetached or process.GetState( ) == lldb.eStateExited: return True if process.GetState( ) == lldb.eStateCrashed or process.GetState( ) == lldb.eStateDetached or process.GetState( ) == lldb.eStateExited: return False retry_count = retry_count - 1 return False
def run(self): _ = self._dbg process = _.process broadcaster = process.GetBroadcaster() event = lldb.SBEvent() listener = lldb.SBListener('ExitListener') rc = broadcaster.AddListener( listener, lldb.SBProcess.eBroadcastBitStateChanged) while True: if listener.WaitForEventForBroadcasterWithType( lldb.eStateExited, broadcaster, lldb.SBProcess.eBroadcastBitStateChanged, event): # print _.sbdbg.StateAsCString(process.GetState()) if process.GetState() == lldb.eStateExited: _.state = 'EXITED' _.rtcode = process.GetExitStatus() _.stop_time = time() _.global_vars = _.get_globals() _.clear() break elif process.GetState() == lldb.eStateStopped: _.filter_frames() frame = _.get_crash_frame() _.crash_line = int( frame.line_entry.GetLine().__str__()) _.rtcode = process.GetExitStatus() _.stop_time = time() _.global_vars = _.get_globals() # print(frame.line_entry.GetLine()) _.state = 'STOPPED' # _.filter_frames() break
def test_clearing_listener(self): """Make sure we also clear listerers from the hook up for event type manager""" self.build() my_first_listener = lldb.SBListener("bonus_listener") my_listener = lldb.SBListener("test_listener") my_third_listener = lldb.SBListener("extra_bonus_listener") my_listener.StartListeningForEventClass( self.dbg, lldb.SBTarget.GetBroadcasterClassName(), lldb.SBTarget.eBroadcastBitBreakpointChanged) my_first_listener.StartListeningForEventClass( self.dbg, lldb.SBTarget.GetBroadcasterClassName(), lldb.SBTarget.eBroadcastBitWatchpointChanged) my_third_listener.StartListeningForEventClass( self.dbg, lldb.SBTarget.GetBroadcasterClassName(), lldb.SBTarget.eBroadcastBitModulesUnloaded) exe = self.getBuildArtifact("a.out") my_listener.Clear() target = self.dbg.CreateTarget(exe) bkpt = target.BreakpointCreateByName("main") event = lldb.SBEvent() my_listener.WaitForEvent(1, event) self.assertTrue(not event.IsValid(), "We don't get events we aren't listening to.")
def test_breakpoint_set_restart(self): self.build() exe = self.getBuildArtifact("a.out") target = self.dbg.CreateTarget(exe) self.assertTrue(target, VALID_TARGET) self.dbg.SetAsync(True) process = target.LaunchSimple( None, None, self.get_process_working_directory()) self.assertTrue(process, PROCESS_IS_VALID) event = lldb.SBEvent() # Wait for inferior to transition to running state while self.dbg.GetListener().WaitForEvent(2, event): if lldb.SBProcess.GetStateFromEvent(event) == lldb.eStateRunning: break bp = target.BreakpointCreateBySourceRegex( self.BREAKPOINT_TEXT, lldb.SBFileSpec('main.cpp')) self.assertTrue( bp.IsValid() and bp.GetNumLocations() == 1, VALID_BREAKPOINT) while self.dbg.GetListener().WaitForEvent(2, event): if lldb.SBProcess.GetStateFromEvent( event) == lldb.eStateStopped and lldb.SBProcess.GetRestartedFromEvent(event): continue if lldb.SBProcess.GetStateFromEvent(event) == lldb.eStateRunning: continue self.fail( "Setting a breakpoint generated an unexpected event: %s" % lldb.SBDebugger.StateAsCString( lldb.SBProcess.GetStateFromEvent(event)))
def run(self): while not self.should_quit: event = lldb.SBEvent() if self._listener.WaitForEvent(1, event): if lldb.SBTarget.EventIsTargetEvent(event): self._handle_target_event(event) elif lldb.SBProcess.EventIsProcessEvent(event): self._handle_process_event(event) # Even though Breakpoints are registered on SBTarget # lldb.SBTarget.EventIsTargetEvent() # will return false for breakpoint events so handle them here. elif lldb.SBBreakpoint.EventIsBreakpointEvent(event): self._handle_breakpoint_event(event) elif lldb.SBWatchpoint.EventIsWatchpointEvent(event): self._handle_watchpoint_event(event) else: self._handle_unknown_event(event) # Event loop terminates, shutdown chrome server app. self._app.shutdown() # Detach/Kill inferior. if self._debugger_store.is_attach: self._debugger_store.debugger.GetSelectedTarget().process.Detach() else: self._debugger_store.debugger.GetSelectedTarget().process.Kill()
def connect_command(debugger, command, result, internal_dict): # These two are passed in by the script which loads us connect_url = internal_dict['fruitstrap_connect_url'] error = lldb.SBError() process = lldb.target.ConnectRemote( lldb.target.GetDebugger().GetListener(), connect_url, None, error) # Wait for connection to succeed listener = lldb.target.GetDebugger().GetListener() listener.StartListeningForEvents(process.GetBroadcaster(), lldb.SBProcess.eBroadcastBitStateChanged) events = [] state = (process.GetState() or lldb.eStateInvalid) while state != lldb.eStateConnected: event = lldb.SBEvent() if listener.WaitForEvent(1, event): state = process.GetStateFromEvent(event) events.append(event) else: state = lldb.eStateInvalid # Add events back to queue, otherwise lldb freezes for event in events: listener.AddEvent(event)
def autoexit_command(debugger, command, result, internal_dict): process = lldb.target.process listener = debugger.GetListener() listener.StartListeningForEvents( process.GetBroadcaster(), lldb.SBProcess.eBroadcastBitStateChanged | lldb.SBProcess.eBroadcastBitSTDOUT | lldb.SBProcess.eBroadcastBitSTDERR) event = lldb.SBEvent() while True: if listener.WaitForEvent( 1, event) and lldb.SBProcess.EventIsProcessEvent(event): state = lldb.SBProcess.GetStateFromEvent(event) else: state = process.GetState() if state == lldb.eStateExited: sys.exit(process.GetExitStatus()) elif state == lldb.eStateStopped: debugger.HandleCommand('bt') sys.exit({exitcode_app_crash}) stdout = process.GetSTDOUT(1024) while stdout: sys.stdout.write(stdout) stdout = process.GetSTDOUT(1024) stderr = process.GetSTDERR(1024) while stderr: sys.stdout.write(stderr) stderr = process.GetSTDERR(1024)
def get_next_event(): event = lldb.SBEvent() if not listener.WaitForEvent(timeout, event): test.fail( "Timed out while waiting for a transition to state %s" % lldb.SBDebugger.StateAsCString(expected_state)) return event
def connect_command(debugger, command, result, internal_dict): # These two are passed in by the script which loads us connect_url = internal_dict['fruitstrap_connect_url'] error = lldb.SBError() # We create a new listener here and will use it for both target and the process. # It allows us to prevent data races when both our code and internal lldb code # try to process STDOUT/STDERR messages global listener listener = lldb.SBListener('iosdeploy_listener') listener.StartListeningForEventClass( debugger, lldb.SBTarget.GetBroadcasterClassName(), lldb.SBProcess.eBroadcastBitStateChanged | lldb.SBProcess.eBroadcastBitSTDOUT | lldb.SBProcess.eBroadcastBitSTDERR) process = lldb.target.ConnectRemote(listener, connect_url, None, error) # Wait for connection to succeed events = [] state = (process.GetState() or lldb.eStateInvalid) while state != lldb.eStateConnected: event = lldb.SBEvent() if listener.WaitForEvent(1, event): state = process.GetStateFromEvent(event) events.append(event) else: state = lldb.eStateInvalid # Add events back to queue, otherwise lldb freezes for event in events: listener.AddEvent(event)
def run(self): while True: self.wait_event.wait() self.wait_event.clear() if self.exiting: log_v('Listener thread was asked to exit, complying') self.notify_event.set() return while True: event = lldb.SBEvent() log_v('Listener waiting for events') wait_result = self.listener.WaitForEvent(10, event) log_v('Listener wait exited: {}, {}'.format( str(wait_result), str(event))) if not wait_result: log_v('Listener thread timed out waiting for notification') self.wait_timeout = True self.notify_event.set() break processState = self.process.GetState() if processState == lldb.eStateStopped: log_v( 'Listener detected process state change, but it is not stopped: {}' .format(str(processState))) break log_v('Process not stopped, listening for the next event') log_v('Listener thread got event, notifying') self.notify_event.set()
def wait_for_and_check_event(self, wait_time, value): event = lldb.SBEvent() got_event = self.dbg.GetListener().WaitForEvent(wait_time, event) self.assertTrue(got_event, "Failed to get event after wait") self.assertTrue(lldb.SBProcess.EventIsProcessEvent(event), "Event was not a process event") event_type = lldb.SBProcess.GetStateFromEvent(event) self.assertEqual(event_type, value)
def _handle_listener(self, listener, callbacks): while self.running: event = lldb.SBEvent() result = listener.WaitForEvent(lldb.UINT32_MAX, event) if result and event.IsValid(): callback = callbacks.get(event.GetType()) if callback is not None: callback(event)
def __init__(self, sync): self.sync = sync self.process = sync.process self.listener = lldb.SBListener('ret_sync listener') self.broadcaster = self.process.GetBroadcaster() self.broadcaster.AddListener(self.listener, lldb.SBProcess.eBroadcastBitStateChanged) self.event = lldb.SBEvent() super(EventHandlerThread, self).__init__()
def do_profile_and_detach(self): (target, process, thread, bkpt) = lldbutil.run_to_source_breakpoint(self, "Set a breakpoint here", self.main_source_file) interp = self.dbg.GetCommandInterpreter() result = lldb.SBCommandReturnObject() # First make sure we are getting async data. Set a short interval, continue a bit and check: interp.HandleCommand( "process plugin packet send 'QSetEnableAsyncProfiling;enable:1;interval_usec:500000;scan_type=0x5;'", result) self.assertTrue(result.Succeeded(), "process packet send failed: %s" % (result.GetError())) # Run a bit to give us a change to collect profile data: bkpt.SetIgnoreCount(1) threads = lldbutil.continue_to_breakpoint(process, bkpt) self.assertEqual(len(threads), 1, "Hit our breakpoint again.") str = process.GetAsyncProfileData(1000) self.assertTrue(len(str) > 0, "Got some profile data") # Now make the profiling interval very long and try to detach. interp.HandleCommand( "process plugin packet send 'QSetEnableAsyncProfiling;enable:1;interval_usec:10000000;scan_type=0x5;'", result) self.assertTrue(result.Succeeded(), "process packet send failed: %s" % (result.GetError())) self.dbg.SetAsync(True) listener = self.dbg.GetListener() # We don't want to hit our breakpoint anymore. bkpt.SetEnabled(False) # Record our process pid so we can kill it since we are going to detach... self.pid = process.GetProcessID() def cleanup(): self.dbg.SetAsync(False) os.kill(self.pid, signal.SIGKILL) self.addTearDownHook(cleanup) process.Continue() event = lldb.SBEvent() success = listener.WaitForEventForBroadcaster(0, process.GetBroadcaster(), event) self.assertTrue(success, "Got an event which should be running.") event_state = process.GetStateFromEvent(event) self.assertEqual(event_state, lldb.eStateRunning, "Got the running event") # Now detach: error = process.Detach() self.assertTrue(error.Success(), "Detached successfully")
def autoexit_command(debugger, command, result, internal_dict): global listener process = lldb.target.process # This line prevents internal lldb listener from processing STDOUT/STDERR messages. Without it, an order of log writes is incorrect sometimes debugger.GetListener().StopListeningForEvents( process.GetBroadcaster(), lldb.SBProcess.eBroadcastBitSTDOUT | lldb.SBProcess.eBroadcastBitSTDERR) event = lldb.SBEvent() def ProcessSTDOUT(): stdout = process.GetSTDOUT(1024) while stdout: sys.stdout.write(stdout) stdout = process.GetSTDOUT(1024) def ProcessSTDERR(): stderr = process.GetSTDERR(1024) while stderr: sys.stdout.write(stderr) stderr = process.GetSTDERR(1024) while True: if listener.WaitForEvent( 1, event) and lldb.SBProcess.EventIsProcessEvent(event): state = lldb.SBProcess.GetStateFromEvent(event) type = event.GetType() if type & lldb.SBProcess.eBroadcastBitSTDOUT: ProcessSTDOUT() if type & lldb.SBProcess.eBroadcastBitSTDERR: ProcessSTDERR() else: state = process.GetState() if state != lldb.eStateRunning: # Let's make sure that we drained our streams before exit ProcessSTDOUT() ProcessSTDERR() if state == lldb.eStateExited: sys.stdout.write('\\nPROCESS_EXITED\\n') os._exit(process.GetExitStatus()) elif state == lldb.eStateStopped: sys.stdout.write('\\nPROCESS_STOPPED\\n') debugger.HandleCommand('bt') os._exit({exitcode_app_crash}) elif state == lldb.eStateCrashed: sys.stdout.write('\\nPROCESS_CRASHED\\n') debugger.HandleCommand('bt') os._exit({exitcode_app_crash}) elif state == lldb.eStateDetached: sys.stdout.write('\\nPROCESS_DETACHED\\n') os._exit({exitcode_app_crash})
def run(self): """ main loop to listen for LLDB events """ event = lldb.SBEvent() Event listener = lldb.debugger.GetListener() num_tries = 2 #GetEvents(listener, num_tries) return
def fuzz_obj(obj): obj.SetAsync(True) obj.SetAsync(False) obj.GetAsync() obj.SkipLLDBInitFiles(True) obj.SetInputFileHandle(None, True) obj.SetOutputFileHandle(None, True) obj.SetErrorFileHandle(None, True) obj.SetInputString("") obj.GetInputFileHandle() obj.GetOutputFileHandle() obj.GetErrorFileHandle() obj.GetCommandInterpreter() obj.HandleCommand("nothing here") listener = obj.GetListener() try: obj.HandleProcessEvent(lldb.SBProcess(), lldb.SBEvent(), None, None) except Exception: pass obj.CreateTargetWithFileAndTargetTriple("a.out", "A-B-C") obj.CreateTargetWithFileAndArch("b.out", "arm") obj.CreateTarget("c.out") obj.DeleteTarget(lldb.SBTarget()) obj.GetTargetAtIndex(0xffffffff) obj.FindTargetWithProcessID(0) obj.FindTargetWithFileAndArch("a.out", "arm") obj.GetNumTargets() obj.GetSelectedTarget() obj.GetNumPlatforms() obj.GetPlatformAtIndex(0xffffffff) obj.GetNumAvailablePlatforms() obj.GetAvailablePlatformInfoAtIndex(0xffffffff) obj.GetSourceManager() obj.SetSelectedTarget(lldb.SBTarget()) obj.SetCurrentPlatformSDKRoot("tmp/sdk-root") try: obj.DispatchInput(None) except Exception: pass obj.DispatchInputInterrupt() obj.DispatchInputEndOfFile() obj.GetInstanceName() obj.GetDescription(lldb.SBStream()) obj.GetTerminalWidth() obj.SetTerminalWidth(0xffffffff) obj.GetID() obj.GetPrompt() obj.SetPrompt("Hi, Mom!") obj.GetScriptLanguage() obj.SetScriptLanguage(lldb.eScriptLanguageNone) obj.SetScriptLanguage(lldb.eScriptLanguagePython) obj.GetCloseInputOnEOF() obj.SetCloseInputOnEOF(True) obj.SetCloseInputOnEOF(False) obj.Clear() for target in obj: s = str(target)
def run(self): while True: event = lldb.SBEvent() if not self._listener.PeekAtNextEvent(event): continue process = self._interpreter.GetProcess() if process and not process.GetUniqueID() in self._handled: self._suppress_signals(process) self._handled.add(process.GetUniqueID())
def get_next_event(): event = lldb.SBEvent() if not listener.WaitForEventForBroadcasterWithType( timeout, process.GetBroadcaster(), lldb.SBProcess.eBroadcastBitStateChanged, event): test.fail( "Timed out while waiting for a transition to state %s" % lldb.SBDebugger.StateAsCString(expected_state)) return event
def eventLoop(self): while not self.isDone(): event = lldb.SBEvent() got_event = self.listener.WaitForEvent(lldb.UINT32_MAX, event) if got_event and not event.IsValid(): self.winAddStr("Warning: Invalid or no event...") continue elif not event.GetBroadcaster().IsValid(): continue self.event_queue.put(event)
def thread_proc(self): while not self.stopping: event = self.event if self.listener.WaitForEvent(1, event): if log.isEnabledFor(logging.DEBUG): descr = lldb.SBStream() event.GetDescription(descr) log.debug('### Debug event: %s %s', event.GetDataFlavor(), descr.GetData()) self.event_sink(event) self.event = lldb.SBEvent()
def test(self): """ Test auto-continue behavior when a process is interrupted to deliver an "asynchronous" packet. This simulates the situation when a process stops on its own just as lldb client is about to interrupt it. The client should not auto-continue in this case, unless the user has explicitly requested that we ignore signals of this type. """ class MyResponder(MockGDBServerResponder): continueCount = 0 def setBreakpoint(self, packet): return "OK" def interrupt(self): # Simulate process stopping due to a raise(SIGINT) just as lldb # is about to interrupt it. return "T02reason:signal" def cont(self): self.continueCount += 1 if self.continueCount == 1: # No response, wait for the client to interrupt us. return None return "W00" # Exit self.server.responder = MyResponder() target = self.createTarget("a.yaml") process = self.connect(target) self.dbg.SetAsync(True) process.Continue() # resume the process and immediately try to set another breakpoint. When using the remote # stub, this will trigger a request to stop the process. Make sure we # do not lose this signal. bkpt = target.BreakpointCreateByAddress(0x1234) self.assertTrue(bkpt.IsValid()) self.assertEqual(bkpt.GetNumLocations(), 1) event = lldb.SBEvent() while self.dbg.GetListener().WaitForEvent(2, event): if self.TraceOn(): print( "Process changing state to:", self.dbg.StateAsCString(process.GetStateFromEvent(event))) if process.GetStateFromEvent(event) == lldb.eStateExited: break # We should get only one continue packet as the client should not # auto-continue after setting the breakpoint. self.assertEqual(self.server.responder.continueCount, 1) # And the process should end up in the stopped state. self.assertEqual(process.GetState(), lldb.eStateStopped)
def match_state(self, process_listener, expected_state): num_seconds = 5 broadcaster = self.process().GetBroadcaster() event_type_mask = lldb.SBProcess.eBroadcastBitStateChanged event = lldb.SBEvent() got_event = process_listener.WaitForEventForBroadcasterWithType( num_seconds, broadcaster, event_type_mask, event) self.assertTrue(got_event, "Got an event") state = lldb.SBProcess.GetStateFromEvent(event) self.assertTrue( state == expected_state, "It was the %s state." % lldb.SBDebugger_StateAsCString(expected_state))
def run(self): while not self.should_quit: event = lldb.SBEvent() if self.listener.WaitForEvent(1, event): if event.GetType() == lldb.SBTarget.eBroadcastBitModulesLoaded: self.module_source_path_updater.modules_updated() elif lldb.SBProcess.EventIsProcessEvent(event): self._broadcast_process_state( lldb.SBProcess.GetProcessFromEvent(event)) elif lldb.SBBreakpoint.EventIsBreakpointEvent(event): self._breakpoint_event(event) elif lldb.SBWatchpoint.EventIsWatchpointEvent(event): self._watchpoint_event(event)
def fuzz_obj(obj): obj.BroadcastEventByType(lldb.eBreakpointEventTypeInvalidType, True) obj.BroadcastEvent(lldb.SBEvent(), False) listener = lldb.SBListener("fuzz_testing") obj.AddInitialEventsToListener(listener, 0xffffffff) obj.AddInitialEventsToListener(listener, 0) obj.AddListener(listener, 0xffffffff) obj.AddListener(listener, 0) obj.GetName() obj.EventTypeHasListeners(0) obj.RemoveListener(listener, 0xffffffff) obj.RemoveListener(listener, 0) obj.Clear()
def fetch_events(self): event = lldb.SBEvent() done = False while not done: if self.listener.WaitForEvent(1, event): event_mask = event.GetType() if event.BroadcasterMatchesRef(self.test_broadcaster): if event_mask & self.eBroadcastBitStopDiagnosticThread: done = True elif event.BroadcasterMatchesRef(self.diagnostic_broadcaster): self.diagnostic_events.append( lldb.SBDebugger.GetDiagnosticFromEvent(event))
def GetWatchpointEvent (self, event_type): # We added a watchpoint so we should get a watchpoint added event. event = lldb.SBEvent() success = self.listener.WaitForEvent (1, event) self.assertTrue(success == True, "Successfully got watchpoint event") self.assertTrue (lldb.SBWatchpoint.EventIsWatchpointEvent(event), "Event is a watchpoint event.") found_type = lldb.SBWatchpoint.GetWatchpointEventTypeFromEvent (event) self.assertTrue (found_type == event_type, "Event is not correct type, expected: %d, found: %d"%(event_type, found_type)) # There shouldn't be another event waiting around: found_event = self.listener.PeekAtNextEventForBroadcasterWithType (self.target_bcast, lldb.SBTarget.eBroadcastBitBreakpointChanged, event) if found_event: print "Found an event I didn't expect: ", event self.assertTrue (not found_event, "Only one event per change.")