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_setpgid(self): self.build() exe = os.path.join(os.getcwd(), 'a.out') # Use a file as a synchronization point between test and inferior. pid_file_path = lldbutil.append_to_process_working_directory( "pid_file_%d" % (int(time.time()))) self.addTearDownHook(lambda: self.run_platform_command("rm %s" % (pid_file_path))) popen = self.spawnSubprocess(exe, [pid_file_path]) self.addTearDownHook(self.cleanupSubprocesses) pid = lldbutil.wait_for_file_on_target(self, pid_file_path) # make sure we cleanup the forked child also def cleanupChild(): if lldb.remote_platform: lldb.remote_platform.Kill(int(pid)) else: if os.path.exists("/proc/" + pid): os.kill(int(pid), signal.SIGKILL) self.addTearDownHook(cleanupChild) # Create a target by the debugger. target = self.dbg.CreateTarget(exe) self.assertTrue(target, VALID_TARGET) listener = lldb.SBListener("my.attach.listener") error = lldb.SBError() process = target.AttachToProcessWithID(listener, int(pid), error) self.assertTrue(error.Success() and process, PROCESS_IS_VALID) # set a breakpoint just before the setpgid() call lldbutil.run_break_set_by_file_and_line(self, 'main.c', self.line, num_expected_locations=-1) thread = process.GetSelectedThread() # release the child from its loop value = thread.GetSelectedFrame().EvaluateExpression("release_child_flag = 1") self.assertTrue(value.IsValid() and value.GetValueAsUnsigned(0) == 1); process.Continue() # make sure the child's process group id is different from its pid value = thread.GetSelectedFrame().EvaluateExpression("(int)getpgid(0)") self.assertTrue(value.IsValid()) self.assertNotEqual(value.GetValueAsUnsigned(0), int(pid)); # step over the setpgid() call thread.StepOver() self.assertEqual(thread.GetStopReason(), lldb.eStopReasonPlanComplete) # verify that the process group has been set correctly # this also checks that we are still in full control of the child value = thread.GetSelectedFrame().EvaluateExpression("(int)getpgid(0)") self.assertTrue(value.IsValid()) self.assertEqual(value.GetValueAsUnsigned(0), int(pid)); # run to completion process.Continue() self.assertEqual(process.GetState(), lldb.eStateExited)
def ghstart(debugger, command, result, internal_dict): global client target = debugger.GetSelectedTarget() process = target.GetProcess() broadcaster = target.GetBroadcaster() # Add our thread as a listener to the broadcaster. listener = lldb.SBListener("breakpoint listener") rc = broadcaster.AddListener(listener, lldb.SBProcess.eBroadcastBitStateChanged) if not rc: result.SetStatus(lldb.eReturnStatusFailed) result.AppendMessage('Failed to add listener') return # Create the thread for maximum power! client = GhiDBClientThread(listener, process, process.GetSelectedThread().GetSelectedFrame()) client.start() # Join the thread on exit. atexit.register(_cleanup) # Let the user know everythin's honkey-dorey. result.SetStatus(lldb.eReturnStatusSuccessContinuingResult) result.AppendMessage('Connected to Ghidra server')
def on_done(self, string): if LLDBPlugin.ensure_lldb_is_running(self.window): sublime.status_message('Debugging session started.') else: sublime.error_message('Couldn\'t get a debugging session.') return False LLDBLayoutManager.lldb_toggle_output_view(self.window, show=True) driver = driver_instance() if driver: invalidListener = lldb.SBListener() error = lldb.SBError() target = driver.debugger.CreateTargetWithFileAndArch( None, None) sublime.status_message('Connecting to debugserver at: %s' % string) process = target.ConnectRemote(invalidListener, str(string), None, error) debug(debugPlugin, process) if error.Fail(): sublime.error_message("Connect failed: %s" % error.GetCString()) else: driver.debugger.SetSelectedTarget(target) sublime.status_message('Connected to debugserver.')
def test_attach_fail(self): error_msg = "mock-error-msg" class MyResponder(MockGDBServerResponder): # Pretend we don't have any process during the initial queries. def qC(self): return "E42" def qfThreadInfo(self): return "OK" # No threads. # Then, when we are asked to attach, error out. def vAttach(self, pid): return "E42;" + binascii.hexlify(error_msg.encode()).decode() self.server.responder = MyResponder() target = self.dbg.CreateTarget("") process = self.connect(target) lldbutil.expect_state_changes(self, self.dbg.GetListener(), process, [lldb.eStateConnected]) error = lldb.SBError() target.AttachToProcessWithID(lldb.SBListener(), 47, error) self.assertEquals(error_msg, error.GetCString())
def test_with_attach_to_process_with_id_api(self): """Create target, spawn a process, and attach to it with process id.""" exe = '%s_%d' % (self.testMethodName, os.getpid()) d = {'EXE': exe} self.build(dictionary=d) self.setTearDownCleanup(dictionary=d) target = self.dbg.CreateTarget(self.getBuildArtifact(exe)) # Spawn a new process token = exe + '.token' if not lldb.remote_platform: token = self.getBuildArtifact(token) if os.path.exists(token): os.remove(token) popen = self.spawnSubprocess(self.getBuildArtifact(exe), [token]) lldbutil.wait_for_file_on_target(self, token) listener = lldb.SBListener("my.attach.listener") error = lldb.SBError() process = target.AttachToProcessWithID(listener, popen.pid, error) self.assertTrue(error.Success() and process, PROCESS_IS_VALID) # Let's check the stack traces of the attached process. stacktraces = lldbutil.print_stacktraces(process, string_buffer=True) self.expect(stacktraces, exe=False, substrs=['main.c:%d' % self.line2, '(int)argc=2'])
def doLaunch(self, stop_at_entry, args): """ Handle process launch. """ error = lldb.SBError() fs = self.target.GetExecutable() exe = os.path.join(fs.GetDirectory(), fs.GetFilename()) if self.process is not None and self.process.IsValid(): pid = self.process.GetProcessID() state = state_type_to_str(self.process.GetState()) self.process.Destroy() launchInfo = lldb.SBLaunchInfo(args.split(' ')) self.process = self.target.Launch(launchInfo, error) if not error.Success(): sys.stderr.write("Error during launch: " + str(error)) return # launch succeeded, store pid and add some event listeners self.pid = self.process.GetProcessID() self.processListener = lldb.SBListener("process_event_listener") self.process.GetBroadcaster().AddListener(self.processListener, lldb.SBProcess.eBroadcastBitStateChanged) print "Launched %s %s (pid=%d)" % (exe, args, self.pid) if not stop_at_entry: self.doContinue() else: self.processPendingEvents(self.eventDelayLaunch)
def test_launch_fail(self): class MyResponder(MockGDBServerResponder): # Pretend we don't have any process during the initial queries. def qC(self): return "E42" def qfThreadInfo(self): return "OK" # No threads. # Then, when we are asked to attach, error out. def A(self, packet): return "E47" self.server.responder = MyResponder() target = self.createTarget("a.yaml") process = self.connect(target) lldbutil.expect_state_changes(self, self.dbg.GetListener(), process, [lldb.eStateConnected]) error = lldb.SBError() target.Launch(lldb.SBListener(), None, None, None, None, None, None, 0, True, error) self.assertEquals("'A' packet returned an error: 71", error.GetCString())
def __init__(self, vimx): """ Creates the LLDB SBDebugger object and more! """ import logging self.logger = logging.getLogger(__name__) self.logger.setLevel(logging.INFO) self._sink = open('/dev/null') self._dbg = lldb.SBDebugger.Create() self._dbg.SetOutputFileHandle(self._sink, False) self._ipreter = self._dbg.GetCommandInterpreter() self._rcx = lldb.SBListener("the_ear") # receiver self._trx = lldb.SBBroadcaster("the_mouth") # transmitter for user events self._trx.AddListener(self._rcx, self.CTRL_VOICE) self._target = None self._process = None self._num_bps = 0 self.in_queue = Queue(maxsize=2) self.out_queue = Queue(maxsize=1) self.vimx = vimx self.busy_stack = 0 # when > 0, buffers are not updated self.buffers = VimBuffers(vimx) self.session = Session(self, vimx) super(Controller, self).__init__() # start the thread
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 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 test_stdio_pty(self): target = self._create_target() info = target.GetLaunchInfo() info.SetArguments([ "stdin:stdin", "stdout:STDOUT CONTENT\n", "stderr:STDERR CONTENT\n", "dump:" + self.getBuildArtifact("state.log"), ], False) listener = lldb.SBListener("test_stdio") info.SetListener(listener) self.dbg.SetAsync(True) error = lldb.SBError() process = target.Launch(info, error) self.assertSuccess(error) lldbutil.expect_state_changes(self, listener, process, [lldb.eStateRunning]) process.PutSTDIN("STDIN CONTENT\n") lldbutil.expect_state_changes(self, listener, process, [lldb.eStateExited]) # Echoed stdin, stdout and stderr. With a pty we cannot split standard # output and error. self.assertEqual( process.GetSTDOUT(1000), "STDIN CONTENT\r\nSTDOUT CONTENT\r\nSTDERR CONTENT\r\n") with open(self.getBuildArtifact("state.log")) as s: state = json.load(s) self.assertEqual(state["stdin"], "STDIN CONTENT\n")
def test_with_attach_to_process_with_id_api(self): """Create target, spawn a process, and attach to it with process id.""" self.build(dictionary=self.d) self.setTearDownCleanup(dictionary=self.d) target = self.dbg.CreateTarget(self.exe) # Spawn a new process popen = self.spawnSubprocess(self.exe, ["abc", "xyz"]) self.addTearDownHook(self.cleanupSubprocesses) # Give the subprocess time to start and wait for user input time.sleep(0.25) listener = lldb.SBListener("my.attach.listener") error = lldb.SBError() process = target.AttachToProcessWithID(listener, popen.pid, error) self.assertTrue(error.Success() and process, PROCESS_IS_VALID) # Let's check the stack traces of the attached process. import lldbsuite.test.lldbutil as lldbutil stacktraces = lldbutil.print_stacktraces(process, string_buffer=True) self.expect(stacktraces, exe=False, substrs=['main.c:{0:d}'.format(self.line2), '(int)argc=3'])
def start_breakpoint_listener(target): """Listens for breakpoints being added and adds new ones to the callback registration list""" listener = lldb.SBListener("breakpoint listener") def listen(): event = lldb.SBEvent() try: while True: if listener.WaitForEvent(120, event): if lldb.SBBreakpoint.EventIsBreakpointEvent(event) and \ lldb.SBBreakpoint.GetBreakpointEventTypeFromEvent(event) == \ lldb.eBreakpointEventTypeAdded: global new_breakpoints breakpoint = lldb.SBBreakpoint.GetBreakpointFromEvent(event) print_debug("breakpoint added, id = " + str(breakpoint.id)) new_breakpoints.append(breakpoint.id) except: print_debug("breakpoint listener shutting down") # Start the listener and let it run as a daemon listener_thread = threading.Thread(target=listen) listener_thread.daemon = True listener_thread.start() # Register the listener with the target target.GetBroadcaster().AddListener(listener, lldb.SBTarget.eBroadcastBitBreakpointChanged)
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 test_SBListener(self): obj = lldb.SBListener() if self.TraceOn(): print obj self.assertFalse(obj) # Do fuzz testing on the invalid obj, it should not crash lldb. import sb_listener sb_listener.fuzz_obj(obj)
def fuzz_obj(obj): obj.GetProcess() listener = lldb.SBListener() error = lldb.SBError() obj.Launch(listener, None, None, None, None, None, None, 0, True, error) obj.LaunchSimple(None, None, None) obj.AttachToProcessWithID(listener, 123, error) obj.AttachToProcessWithName(listener, 'lldb', False, error) obj.ConnectRemote(listener, "connect://to/here", None, error) obj.GetExecutable() obj.GetNumModules() obj.GetModuleAtIndex(0xffffffff) obj.GetDebugger() filespec = lldb.SBFileSpec() obj.FindModule(filespec) sc_list = obj.FindFunctions("the_func") sc_list = obj.FindFunctions("the_func", lldb.eFunctionNameTypeAny) obj.FindFirstType("dont_care") obj.FindTypes("dont_care") obj.FindFirstType(None) obj.GetInstructions(lldb.SBAddress(), bytearray()) obj.GetSourceManager() obj.FindGlobalVariables("my_global_var", 1) address = obj.ResolveLoadAddress(0xffff) obj.ResolveSymbolContextForAddress(address, 0) obj.BreakpointCreateByLocation("filename", 20) obj.BreakpointCreateByLocation(filespec, 20) obj.BreakpointCreateByName("func", None) obj.BreakpointCreateByRegex("func.", None) obj.BreakpointCreateByAddress(0xf0f0) obj.GetNumBreakpoints() obj.GetBreakpointAtIndex(0) obj.BreakpointDelete(0) obj.FindBreakpointByID(0) obj.EnableAllBreakpoints() obj.DisableAllBreakpoints() obj.DeleteAllBreakpoints() obj.GetNumWatchpoints() obj.GetWatchpointAtIndex(0) obj.DeleteWatchpoint(0) obj.FindWatchpointByID(0) obj.EnableAllWatchpoints() obj.DisableAllWatchpoints() obj.DeleteAllWatchpoints() obj.GetAddressByteSize() obj.GetByteOrder() obj.GetTriple() error = lldb.SBError() obj.WatchAddress(123, 8, True, True, error) obj.GetBroadcaster() obj.GetDescription(lldb.SBStream(), lldb.eDescriptionLevelBrief) obj.Clear() for module in obj.module_iter(): s = str(module) for bp in obj.breakpoint_iter(): s = str(bp) for wp in obj.watchpoint_iter(): s = str(wp)
def test_launch_A(self): class MyResponder(MockGDBServerResponder): def __init__(self, *args, **kwargs): self.started = False return super().__init__(*args, **kwargs) def qC(self): if self.started: return "QCp10.10" else: return "E42" def qfThreadInfo(self): if self.started: return "mp10.10" else: return "E42" def qsThreadInfo(self): return "l" def A(self, packet): self.started = True return "OK" def qLaunchSuccess(self): if self.started: return "OK" return "E42" self.server.responder = MyResponder() target = self.createTarget("a.yaml") # NB: apparently GDB packets are using "/" on Windows too exe_path = self.getBuildArtifact("a").replace(os.path.sep, '/') exe_hex = binascii.b2a_hex(exe_path.encode()).decode() process = self.connect(target) lldbutil.expect_state_changes(self, self.dbg.GetListener(), process, [lldb.eStateConnected]) target.Launch( lldb.SBListener(), ["arg1", "arg2", "arg3"], # argv [], # envp None, # stdin_path None, # stdout_path None, # stderr_path None, # working_directory 0, # launch_flags True, # stop_at_entry lldb.SBError()) # error self.assertTrue(process, PROCESS_IS_VALID) self.assertEqual(process.GetProcessID(), 16) self.assertPacketLogContains([ "A%d,0,%s,8,1,61726731,8,2,61726732,8,3,61726733" % (len(exe_hex), exe_hex), ])
def test_with_python_api(self): """Test that adding, deleting and modifying watchpoints sends the appropriate events.""" self.build() exe = os.path.join(os.getcwd(), "a.out") target = self.dbg.CreateTarget(exe) self.assertTrue(target, VALID_TARGET) self.main_source_spec = lldb.SBFileSpec(self.main_source) break_in_main = target.BreakpointCreateBySourceRegex( '// Put a breakpoint here.', self.main_source_spec) self.assertTrue(break_in_main, VALID_BREAKPOINT) # Now launch the process, and do not stop at entry point. process = target.LaunchSimple(None, None, self.get_process_working_directory()) self.assertTrue(process, PROCESS_IS_VALID) # The stop reason of the thread should be breakpoint. threads = lldbutil.get_threads_stopped_at_breakpoint( process, break_in_main) if len(threads) != 1: self.fail("Failed to stop at first breakpoint in main.") thread = threads[0] frame = thread.GetFrameAtIndex(0) local_var = frame.FindVariable("local_var") self.assertTrue(local_var.IsValid()) self.listener = lldb.SBListener("com.lldb.testsuite_listener") self.target_bcast = target.GetBroadcaster() self.target_bcast.AddListener( self.listener, lldb.SBTarget.eBroadcastBitWatchpointChanged) self.listener.StartListeningForEvents( self.target_bcast, lldb.SBTarget.eBroadcastBitWatchpointChanged) error = lldb.SBError() local_watch = local_var.Watch(True, True, True, error) if not error.Success(): self.fail("Failed to make watchpoint for local_var: %s" % (error.GetCString())) self.GetWatchpointEvent(lldb.eWatchpointEventTypeAdded) # Now change some of the features of this watchpoint and make sure we get events: local_watch.SetEnabled(False) self.GetWatchpointEvent(lldb.eWatchpointEventTypeDisabled) local_watch.SetIgnoreCount(10) self.GetWatchpointEvent(lldb.eWatchpointEventTypeIgnoreChanged) local_watch.SetCondition("1 == 2") self.GetWatchpointEvent(lldb.eWatchpointEventTypeConditionChanged)
def test_process_attach_with_wrong_arch(self): """Test that when we attach to a binary from the wrong fork of a universal binary, we fix up the ABI correctly.""" if not haswellOrLater(): return # Now keep the architecture at x86_64, but switch the binary # we launch to x86_64h, and make sure on attach we switch to # the correct architecture. # Invoke the default build rule. self.build() # Note that "testit" is a universal binary. exe = self.getBuildArtifact("testit") # Create a target by the debugger. target = self.dbg.CreateTargetWithFileAndTargetTriple( exe, "x86_64-apple-macosx") self.assertTrue(target, VALID_TARGET) self.expect("image list -A -b", substrs=["x86_64 testit"]) bkpt = target.BreakpointCreateBySourceRegex( "sleep", lldb.SBFileSpec("main.c")) self.assertTrue(bkpt.IsValid(), "Valid breakpoint") self.assertTrue( bkpt.GetNumLocations() >= 1, "Our main breakpoint has locations.") popen = self.spawnSubprocess(exe, ["keep_waiting"]) self.addTearDownHook(self.cleanupSubprocesses) error = lldb.SBError() empty_listener = lldb.SBListener() process = target.AttachToProcessWithID( empty_listener, popen.pid, error) self.assertTrue(error.Success(), "Attached to process.") self.expect("image list -A -b", substrs=["x86_64h testit"]) # It may seem odd to check the number of frames, but the bug # that motivated this test was that we eventually fixed the # architecture, but we left the ABI set to the original value. # In that case, if you asked the process for its architecture, # it would look right, but since the ABI was wrong, # backtracing failed. threads = lldbutil.continue_to_breakpoint(process, bkpt) self.assertTrue(len(threads) == 1) thread = threads[0] self.assertTrue( thread.GetNumFrames() > 1, "We were able to backtrace.")
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 test_launch_QEnvironmentHexEncoded_only(self): class MyResponder(MockGDBServerResponder): def qC(self): return "E42" def qfThreadInfo(self): return "E42" def vRun(self, packet): self.started = True return "E28" def QEnvironment(self, packet): return "" self.server.responder = MyResponder() target = self.createTarget("a.yaml") process = self.connect(target) lldbutil.expect_state_changes(self, self.dbg.GetListener(), process, [lldb.eStateConnected]) target.Launch( lldb.SBListener(), [], # argv [ "PLAIN=foo", "NEEDSENC=frob$", "NEEDSENC2=fr*ob", "NEEDSENC3=fro}b", "NEEDSENC4=f#rob", "EQUALS=foo=bar", ], # envp None, # stdin_path None, # stdout_path None, # stderr_path None, # working_directory 0, # launch_flags True, # stop_at_entry lldb.SBError()) # error self.assertPacketLogContains([ "QEnvironmentHexEncoded:504c41494e3d666f6f", "QEnvironmentHexEncoded:4e45454453454e433d66726f6224", "QEnvironmentHexEncoded:4e45454453454e43323d66722a6f62", "QEnvironmentHexEncoded:4e45454453454e43333d66726f7d62", "QEnvironmentHexEncoded:4e45454453454e43343d6623726f62", "QEnvironmentHexEncoded:455155414c533d666f6f3d626172", ])
def doAttach(self, process_name): """ Handle process attach. """ error = lldb.SBError() self.processListener = lldb.SBListener("process_event_listener") self.target = self.dbg.CreateTarget('') self.process = self.target.AttachToProcessWithName(self.processListener, process_name, False, error) if not error.Success(): sys.stderr.write("Error during attach: " + str(error)) return self.ui.activate() self.pid = self.process.GetProcessID() print "Attached to %s (pid=%d)" % (process_name, self.pid)
def test_process_attach_with_wrong_arch(self): """Test that when we attach to a binary from the wrong fork of a universal binary, we fix up the ABI correctly.""" # Now keep the architecture at 32 bit, but switch the binary we launch to # 64 bit, and make sure on attach we switch to the correct # architecture. # Invoke the default build rule. self.build() # Note that "testit" is a universal binary. exe = os.path.join(os.getcwd(), "testit") # Create a target by the debugger. target = self.dbg.CreateTargetWithFileAndTargetTriple( exe, "i386-apple-macosx") self.assertTrue(target, VALID_TARGET) pointer_size = target.GetAddressByteSize() self.assertTrue(pointer_size == 4, "Initially we were 32 bit.") bkpt = target.BreakpointCreateBySourceRegex("sleep", lldb.SBFileSpec("main.c")) self.assertTrue(bkpt.IsValid(), "Valid breakpoint") self.assertTrue(bkpt.GetNumLocations() >= 1, "Our main breakpoint has locations.") popen = self.spawnSubprocess(exe, ["keep_waiting"]) self.addTearDownHook(self.cleanupSubprocesses) error = lldb.SBError() empty_listener = lldb.SBListener() process = target.AttachToProcessWithID(empty_listener, popen.pid, error) self.assertTrue(error.Success(), "Attached to process.") pointer_size = target.GetAddressByteSize() self.assertTrue(pointer_size == 8, "We switched to 64 bit.") # It may seem odd that I am checking the number of frames, but the bug that # motivated this test was that we eventually fixed the architecture, but we # left the ABI set to the original value. In that case, if you asked the # process for its architecture, it would look right, but since the ABI was # wrong, backtracing failed. threads = lldbutil.continue_to_breakpoint(process, bkpt) self.assertTrue(len(threads) == 1) thread = threads[0] self.assertTrue(thread.GetNumFrames() > 1, "We were able to backtrace.")
def __init__(self, server, location_serializer, remote_object_manager, module_source_path_updater, thread_manager, process): Thread.__init__(self) self.daemon = True self.server = server self.location_serializer = location_serializer self.remote_object_manager = remote_object_manager self.module_source_path_updater = module_source_path_updater self.listener = lldb.SBListener('Chrome Dev Tools Listener') self.thread_manager = thread_manager self._add_listener_to_process(process) self._broadcast_process_state(process) self._add_listener_to_target(process.target)
def listen(): listener = DBG.GetListener() process = DBG.GetSelectedTarget().GetProcess() print('Target: %s' % DBG.GetSelectedTarget()) if process is not None: print('process: %s' % DBG.StateAsCString(process.GetState())) broadcaster = process.GetBroadcaster() event = lldb.SBEvent() listener = lldb.SBListener('my listener') rc = broadcaster.AddListener(listener, lldb.SBProcess.eBroadcastBitStateChanged) if rc == 1: print('rc: %s' % rc) GetEvents(listener, broadcaster, 4)
def doAttachById(self, process_id): """ Handle process attach. """ logging.debug("LLDBController.doAttachById") error = lldb.SBError() self.processListener = lldb.SBListener("process_event_listener") self.target = self.dbg.CreateTarget("") self.process = self.target.AttachToProcessWithID( self.processListener, int(process_id), error) if not error.Success(): sys.stderr.write("Error during attach: " + str(error)) return self.ui.activate() self.pid = self.process.GetProcessID() print("Attached to %s (pid=%d)" % (process_id, self.pid))
def attach_and_stop(self, wait_for_process=False): error = lldb.SBError() listener = lldb.SBListener() self.debugger = lldb.SBDebugger.Create() # We don't want to handle process events for now self.debugger.SetAsync(False) self.target = self.debugger.CreateTarget(self.process_name) self.process = self.target.AttachToProcessWithName( listener, self.process_name, wait_for_process, error) if not error.Success(): raise Exception(str(error)) self.thread = self.process.GetSelectedThread() self.frame = self.thread.GetSelectedFrame()
def test_with_attach_to_process_with_name_api(self): """Create target, spawn a process, and attach to it with process name.""" exe = '%s_%d'%(self.testMethodName, os.getpid()) d = {'EXE': exe} self.build(dictionary=d) self.setTearDownCleanup(dictionary=d) target = self.dbg.CreateTarget(self.getBuildArtifact(exe)) # Spawn a new process. token = exe+'.token' if not lldb.remote_platform: token = self.getBuildArtifact(token) if os.path.exists(token): os.remove(token) popen = self.spawnSubprocess(self.getBuildArtifact(exe), [token]) self.addTearDownHook(self.cleanupSubprocesses) lldbutil.wait_for_file_on_target(self, token) listener = lldb.SBListener("my.attach.listener") error = lldb.SBError() # Pass 'False' since we don't want to wait for new instance of # "hello_world" to be launched. name = os.path.basename(exe) # While we're at it, make sure that passing a None as the process name # does not hang LLDB. target.AttachToProcessWithName(listener, None, False, error) # Also boundary condition test ConnectRemote(), too. target.ConnectRemote(listener, None, None, error) process = target.AttachToProcessWithName(listener, name, False, error) self.assertSuccess(error) self.assertTrue(process, PROCESS_IS_VALID) # Verify that after attach, our selected target indeed matches name. self.expect( self.dbg.GetSelectedTarget().GetExecutable().GetFilename(), exe=False, startstr=name) # Let's check the stack traces of the attached process. stacktraces = lldbutil.print_stacktraces(process, string_buffer=True) self.expect(stacktraces, exe=False, substrs=['main.c:%d' % self.line2, '(int)argc=2'])
def DEBUG_initialize(self, args): self.line_offset = 0 if args.get('linesStartAt1', True) else 1 self.col_offset = 0 if args.get('columnsStartAt1', True) else 1 self.debugger = lldb.SBDebugger.Create() log.info('LLDB version: %s', self.debugger.GetVersionString()) self.debugger.SetAsync(True) self.event_listener = lldb.SBListener('DebugSession') listener_handler = debugevents.AsyncListener( self.event_listener, self.event_loop.make_dispatcher(self.handle_debugger_event)) self.listener_handler_token = listener_handler.start() return { 'supportsConfigurationDoneRequest': True, 'supportsEvaluateForHovers': True, 'supportsFunctionBreakpoints': True, 'supportsConditionalBreakpoints': True, 'supportsSetVariable': True }