def test_attach(self): """ This test attaches to a process that creates a file. We attach and disconnect before the file is created, and as the process is not terminated upon disconnection, the file is created anyway. """ self.build_and_create_debug_adaptor() program = self.getBuildArtifact("a.out") # Use a file as a synchronization point between test and inferior. sync_file_path = lldbutil.append_to_process_working_directory( self, "sync_file_%d" % (int(time.time()))) self.addTearDownHook( lambda: self.run_platform_command("rm %s" % (sync_file_path))) self.process = subprocess.Popen([program, sync_file_path]) lldbutil.wait_for_file_on_target(self, sync_file_path) self.attach(pid=self.process.pid, disconnectAutomatically=False) response = self.vscode.request_evaluate("wait_for_attach = false;") self.assertTrue(response['success']) # verify we haven't produced the side effect file yet self.assertFalse(os.path.exists(program + ".side_effect")) self.vscode.request_disconnect() time.sleep(2) # verify we produced the side effect file, as the program continued after disconnecting self.assertTrue(os.path.exists(program + ".side_effect"))
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 test_reproducer_attach(self): """Test thread creation after process attach.""" exe = '%s_%d' % (self.testMethodName, os.getpid()) token = self.getBuildArtifact(exe + '.token') if os.path.exists(token): os.remove(token) reproducer = self.getBuildArtifact(exe + '.reproducer') if os.path.exists(reproducer): try: shutil.rmtree(reproducer) except OSError: pass self.build(dictionary={'EXE': exe}) self.addTearDownHook(self.cleanupSubprocesses) inferior = self.spawnSubprocess(self.getBuildArtifact(exe), [token]) pid = inferior.pid lldbutil.wait_for_file_on_target(self, token) # Use Popen because pexpect is overkill and spawnSubprocess is # asynchronous. capture = subprocess.Popen([ lldbtest_config.lldbExec, '-b', '--no-lldbinit', '--no-use-colors' ] + sum(map(lambda x: ['-O', x], self.setUpCommands()), []) + [ '--capture', '--capture-path', reproducer, '-o', 'proc att -n {}'.format(exe), '-o', 'reproducer generate' ], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE) outs, _ = capture.communicate() outs = outs.decode('utf-8') self.assertIn('Process {} stopped'.format(pid), outs) self.assertIn('Reproducer written', outs) # Check that replay works. replay = subprocess.Popen( [lldbtest_config.lldbExec, '-replay', reproducer], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE) outs, _ = replay.communicate() outs = outs.decode('utf-8') self.assertIn('Process {} stopped'.format(pid), outs) # We can dump the reproducer in the current context. self.expect('reproducer dump -f {} -p process'.format(reproducer), substrs=['pid = {}'.format(pid), 'name = {}'.format(exe)])
def test_load_after_attach(self): self.build() sync_file_path = lldbutil.append_to_process_working_directory( self, "process_ready") ctx = self.platformContext lib_name = ctx.shlib_prefix + 'lib_b.' + ctx.shlib_extension exe = self.getBuildArtifact("a.out") lib = self.getBuildArtifact(lib_name) target = self.dbg.CreateTarget(exe) environment = self.registerSharedLibrariesWithTarget(target, ["lib_b"]) # Spawn a new process. # use realpath to workaround llvm.org/pr48376 # Pass path to solib for dlopen to properly locate the library. popen = self.spawnSubprocess(os.path.realpath(exe), [sync_file_path], extra_env=environment) lldbutil.wait_for_file_on_target(self, sync_file_path) # Attach to the spawned process. error = lldb.SBError() process = target.AttachToProcessWithID(self.dbg.GetListener(), popen.pid, error) self.assertSuccess(error) # Continue until first breakpoint. breakpoint1 = self.target().BreakpointCreateBySourceRegex( "// break here", lldb.SBFileSpec("main.cpp")) self.assertEqual(breakpoint1.GetNumResolvedLocations(), 1) stopped_threads = lldbutil.continue_to_breakpoint( self.process(), breakpoint1) self.assertEqual(len(stopped_threads), 1) # Change a variable to escape the loop self.runCmd("expression main_thread_continue = 1") # Continue so that dlopen is called. breakpoint2 = self.target().BreakpointCreateBySourceRegex( "// break after dlopen", lldb.SBFileSpec("main.cpp")) self.assertEqual(breakpoint2.GetNumResolvedLocations(), 1) stopped_threads = lldbutil.continue_to_breakpoint( self.process(), breakpoint2) self.assertEqual(len(stopped_threads), 1) # Check that image list contains liblib_b after dlopen. self.match("image list", patterns=[lib_name], matching=True, msg=lib_name + " missing in image list")
def test_process_list_with_args(self): """Test process list show process args""" self.build() exe = self.getBuildArtifact("TestProcess") # Spawn a new process sync_file = lldbutil.append_to_process_working_directory(self, "ready.txt") popen = self.spawnSubprocess(exe, args=[sync_file, "arg1", "--arg2", "arg3"]) lldbutil.wait_for_file_on_target(self, sync_file) substrs = [str(popen.pid), "TestProcess", "arg1 --arg2 arg3"] self.expect("platform process list -v", substrs=substrs)
def test_platform_process_connect(self): self.build() hostname = socket.getaddrinfo("localhost", 0, proto=socket.IPPROTO_TCP)[0][4][0] listen_url = "[%s]:0" % hostname port_file = self.getBuildArtifact("port") commandline_args = [ "platform", "--listen", listen_url, "--socket-file", port_file, "--", self.getBuildArtifact("a.out"), "foo" ] self.spawnSubprocess(lldbgdbserverutils.get_lldb_server_exe(), commandline_args) socket_id = lldbutil.wait_for_file_on_target(self, port_file) new_platform = lldb.SBPlatform("remote-" + self.getPlatform()) self.dbg.SetSelectedPlatform(new_platform) connect_url = "connect://[%s]:%s" % (hostname, socket_id) self.runCmd("platform connect %s" % connect_url) lldbutil.run_break_set_by_symbol(self, "main") process = self.process() process.Continue() frame = self.frame() self.assertEqual(frame.GetFunction().GetName(), "main") self.assertEqual(frame.FindVariable("argc").GetValueAsSigned(), 2) process.Continue()
def test_by_name(self): ''' Tests attaching to a process by process name. ''' self.build_and_create_debug_adaptor() orig_program = self.getBuildArtifact("a.out") # Since we are going to attach by process name, we need a unique # process name that has minimal chance to match a process that is # already running. To do this we use tempfile.mktemp() to give us a # full path to a location where we can copy our executable. We then # run this copy to ensure we don't get the error "more that one # process matches 'a.out'". program = tempfile.mktemp() shutil.copyfile(orig_program, program) shutil.copymode(orig_program, program) # Use a file as a synchronization point between test and inferior. pid_file_path = lldbutil.append_to_process_working_directory( self, "pid_file_%d" % (int(time.time()))) def cleanup(): if os.path.exists(program): os.unlink(program) self.run_platform_command("rm %s" % (pid_file_path)) # Execute the cleanup function during test case tear down. self.addTearDownHook(cleanup) popen = self.spawnSubprocess(program, [pid_file_path]) pid = lldbutil.wait_for_file_on_target(self, pid_file_path) self.attach(program=program) self.set_and_hit_breakpoint(continueToExit=True)
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 test_platform_process_connect(self): self.build() self.init_llgs_test(False) working_dir = lldb.remote_platform.GetWorkingDirectory() err = lldb.remote_platform.Put(lldb.SBFileSpec(os.path.join(os.getcwd(), "a.out")), lldb.SBFileSpec(os.path.join(working_dir, "a.out"))) if err.Fail(): raise RuntimeError("Unable copy '%s' to '%s'.\n>>> %s" % (f, wd, err.GetCString())) m = re.search("^(.*)://([^:/]*)", configuration.lldb_platform_url) protocol = m.group(1) hostname = m.group(2) unix_protocol = protocol.startswith("unix-") if unix_protocol: p = re.search("^(.*)-connect", protocol) listen_url = "%s://%s" % (p.group(1), os.path.join(working_dir, "platform-%d.sock" % int(time.time()))) else: listen_url = "*:0" port_file = "%s/port" % working_dir commandline_args = ["platform", "--listen", listen_url, "--socket-file", port_file, "--", "%s/a.out" % working_dir, "foo"] self.spawnSubprocess(self.debug_monitor_exe, commandline_args, install_remote=False) self.addTearDownHook(self.cleanupSubprocesses) socket_id = lldbutil.wait_for_file_on_target(self, port_file) new_debugger = lldb.SBDebugger.Create() new_debugger.SetAsync(False) def del_debugger(new_debugger=new_debugger): del new_debugger self.addTearDownHook(del_debugger) new_platform = lldb.SBPlatform(lldb.remote_platform.GetName()) new_debugger.SetSelectedPlatform(new_platform) new_interpreter = new_debugger.GetCommandInterpreter() if unix_protocol: connect_url = "%s://%s%s" % (protocol, hostname, socket_id) else: connect_url = "%s://%s:%s" % (protocol, hostname, socket_id) command = "platform connect %s" % (connect_url) result = lldb.SBCommandReturnObject() new_interpreter.HandleCommand(command, result) self.assertTrue(result.Succeeded(), "platform process connect failed: %s" % result.GetOutput()) target = new_debugger.GetSelectedTarget() process = target.GetProcess() thread = process.GetThreadAtIndex(0) breakpoint = target.BreakpointCreateByName("main") process.Continue() frame = thread.GetFrameAtIndex(0) self.assertEqual(frame.GetFunction().GetName(), "main") self.assertEqual(frame.FindVariable("argc").GetValueAsSigned(), 2) process.Continue()
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 test_target_auto_install_main_executable(self): if lldbgdbserverutils.get_lldb_server_exe() is None: self.skipTest("lldb-server not found") self.build() hostname = socket.getaddrinfo("localhost", 0, proto=socket.IPPROTO_TCP)[0][4][0] listen_url = "[%s]:0"%hostname port_file = self.getBuildArtifact("port") commandline_args = [ "platform", "--listen", listen_url, "--socket-file", port_file] self.spawnSubprocess( lldbgdbserverutils.get_lldb_server_exe(), commandline_args) socket_id = lldbutil.wait_for_file_on_target(self, port_file) new_platform = lldb.SBPlatform("remote-" + self.getPlatform()) self.dbg.SetSelectedPlatform(new_platform) connect_url = "connect://[%s]:%s" % (hostname, socket_id) connect_opts = lldb.SBPlatformConnectOptions(connect_url) self.assertSuccess(new_platform.ConnectRemote(connect_opts)) wd = self.getBuildArtifact("wd") os.mkdir(wd) new_platform.SetWorkingDirectory(wd) # Manually install the modified binary. src_device = lldb.SBFileSpec(self.getBuildArtifact("a.device.out")) dest = lldb.SBFileSpec(os.path.join(wd, "a.out")) self.assertSuccess(new_platform.Put(src_device, dest)) # Test the default setting. self.expect("settings show target.auto-install-main-executable", substrs=["target.auto-install-main-executable (boolean) = true"], msg="Default settings for target.auto-install-main-executable failed.") # Disable the auto install. self.runCmd("settings set target.auto-install-main-executable false") self.expect("settings show target.auto-install-main-executable", substrs=["target.auto-install-main-executable (boolean) = false"]) # Create the target with the original file. self.runCmd("target create --remote-file %s %s "% (dest.fullpath, self.getBuildArtifact("a.out"))) self.expect("process launch", substrs=["exited with status = 74"])
def do_function_starts(self, in_memory): """Run the binary, stop at our unstripped function, make sure the caller has synthetic symbols""" exe = self.getBuildArtifact(exe_name) # Now strip the binary, but leave externals so we can break on dont_strip_me. try: fail_str = system([["strip", "-u", "-x", "-S", exe]]) except CalledProcessError as cmd_error: self.fail("Strip failed: %d" % (cmd_error.returncode)) # Use a file as a synchronization point between test and inferior. pid_file_path = lldbutil.append_to_process_working_directory( self, "token_pid_%d" % (int(os.getpid()))) self.addTearDownHook( lambda: self.run_platform_command("rm %s" % (pid_file_path))) popen = self.spawnSubprocess(exe, [pid_file_path]) self.addTearDownHook(self.cleanupSubprocesses) # Wait until process has fully started up. pid = lldbutil.wait_for_file_on_target(self, pid_file_path) if in_memory: remove_file(exe) target = self.dbg.CreateTarget(None) self.assertTrue(target.IsValid(), "Got a vaid empty target.") error = lldb.SBError() attach_info = lldb.SBAttachInfo() attach_info.SetProcessID(popen.pid) attach_info.SetIgnoreExisting(False) process = target.Attach(attach_info, error) self.assertTrue( error.Success(), "Didn't attach successfully to %d: %s" % (popen.pid, error.GetCString())) bkpt = target.BreakpointCreateByName("dont_strip_me", exe) self.assertTrue(bkpt.GetNumLocations() > 0, "Didn't set the dont_strip_me bkpt.") threads = lldbutil.continue_to_breakpoint(process, bkpt) self.assertEqual(len(threads), 1, "Didn't hit my breakpoint.") # Our caller frame should have been stripped. Make sure we made a synthetic symbol # for it: thread = threads[0] self.assertTrue(thread.num_frames > 1, "Couldn't backtrace.") name = thread.frame[1].GetFunctionName() self.assertTrue(name.startswith("___lldb_unnamed_symbol")) self.assertTrue(name.endswith("$$StripMe"))
def test_attach_and_check_dsyms(self): """Test attach to binary, see if the framework dSYM is found""" exe = self.getBuildArtifact(exe_name) self.build() # Use a file as a synchronization point between test and inferior. pid_file_path = lldbutil.append_to_process_working_directory( self, "token_pid_%d" % (int(os.getpid()))) self.addTearDownHook( lambda: self.run_platform_command("rm %s" % (pid_file_path))) popen = self.spawnSubprocess(exe, [self.getBuildDir(), pid_file_path]) # Wait for the inferior to start up, dlopen a bundle, remove the bundle it linked in pid = lldbutil.wait_for_file_on_target(self, pid_file_path) # Since the library that was dlopen()'ed is now removed, lldb will need to find the # binary & dSYM via target.exec-search-paths settings_str = "settings set target.exec-search-paths " + self.get_process_working_directory( ) + "/hide.app" self.runCmd(settings_str) self.runCmd("process attach -p " + str(popen.pid)) target = self.dbg.GetSelectedTarget() self.assertTrue( target.IsValid(), 'Should have a valid Target after attaching to process') setup_complete = target.FindFirstGlobalVariable("setup_is_complete") self.assertEquals(setup_complete.GetValueAsUnsigned(), 1, 'Check that inferior process has completed setup') # Find the bundle module, see if we found the dSYM too (they're both in "hide.app") i = 0 found_module = False while i < target.GetNumModules(): mod = target.GetModuleAtIndex(i) if mod.GetFileSpec().GetFilename() == 'MyFramework': found_module = True dsym_name = mod.GetSymbolFileSpec().GetFilename() self.assertTrue( dsym_name == 'MyFramework', "Check that we found the dSYM for the bundle that was loaded" ) i = i + 1 self.assertTrue( found_module, "Check that we found the framework loaded in lldb's image list")
def test_attach_to_process_by_id_denied(self): """Test attach by process id denied""" self.build() exe = self.getBuildArtifact(exe_name) # Use a file as a synchronization point between test and inferior. pid_file_path = lldbutil.append_to_process_working_directory( self, "pid_file_%d" % (int(time.time()))) self.addTearDownHook( lambda: self.run_platform_command("rm %s" % (pid_file_path))) # Spawn a new process popen = self.spawnSubprocess(exe, [pid_file_path]) pid = lldbutil.wait_for_file_on_target(self, pid_file_path) self.expect('process attach -p ' + pid, startstr='error: attach failed:', error=True)
def test_attach_to_process_by_id_denied(self): """Test attach by process id denied""" self.build() exe = os.path.join(os.getcwd(), exe_name) # 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))) # Spawn a new process popen = self.spawnSubprocess(exe, [pid_file_path]) self.addTearDownHook(self.cleanupSubprocesses) pid = lldbutil.wait_for_file_on_target(self, pid_file_path) self.expect('process attach -p ' + pid, startstr = 'error: attach failed:', error = True)
def test_platform_process_connect(self): self.build() hostname = socket.getaddrinfo("localhost", 0, proto=socket.IPPROTO_TCP)[0][4][0] listen_url = "[%s]:0" % hostname port_file = self.getBuildArtifact("port") commandline_args = [ "platform", "--listen", listen_url, "--socket-file", port_file, "--", self.getBuildArtifact("a.out"), "foo" ] self.spawnSubprocess(lldbgdbserverutils.get_lldb_server_exe(), commandline_args) socket_id = lldbutil.wait_for_file_on_target(self, port_file) self.dbg.SetAsync(False) new_platform = lldb.SBPlatform("remote-" + self.getPlatform()) self.dbg.SetSelectedPlatform(new_platform) connect_url = "connect://[%s]:%s" % (hostname, socket_id) command = "platform connect %s" % (connect_url) result = lldb.SBCommandReturnObject() self.dbg.GetCommandInterpreter().HandleCommand(command, result) self.assertTrue( result.Succeeded(), "platform process connect failed: %s" % result.GetError()) target = self.dbg.GetSelectedTarget() process = target.GetProcess() thread = process.GetThreadAtIndex(0) breakpoint = target.BreakpointCreateByName("main") process.Continue() frame = thread.GetFrameAtIndex(0) self.assertEqual(frame.GetFunction().GetName(), "main") self.assertEqual(frame.FindVariable("argc").GetValueAsSigned(), 2) process.Continue()
def test(self): self.build() exe = self.getBuildArtifact("a.out") # Use a file as a synchronization point between test and inferior. pid_file_path = lldbutil.append_to_process_working_directory( self, "token_pid_%d" % (int(os.getpid()))) self.addTearDownHook( lambda: self.run_platform_command("rm %s" % (pid_file_path))) # Spawn a new process popen = self.spawnSubprocess(exe, [pid_file_path]) # Wait until process has fully started up. pid = lldbutil.wait_for_file_on_target(self, pid_file_path) # Now we can safely remove the executable and test if we can attach. os.remove(exe) self.runCmd("process attach -p " + str(popen.pid)) self.runCmd("kill")
def test_macos_sdk(self): self.build() exe = self.getBuildArtifact('a.out') token = self.getBuildArtifact('token') # Remove the old token. try: os.remove(token) except: pass # Create a fake 'SDK' directory. test_home = os.path.join(self.getBuildDir(), 'fake_home.noindex') macos_version = platform.mac_ver()[0] sdk_dir = os.path.join(test_home, 'Library', 'Developer', 'Xcode', 'macOS DeviceSupport', macos_version) symbols_dir = os.path.join(sdk_dir, 'Symbols') lldbutil.mkdir_p(symbols_dir) # Save the current home directory and restore it afterwards. old_home = os.getenv('HOME') def cleanup(): if not old_home: del os.environ['HOME'] else: os.environ['HOME'] = old_home self.addTearDownHook(cleanup) os.environ['HOME'] = test_home # Launch our test binary. inferior = self.spawnSubprocess(exe, [token]) pid = inferior.pid # Wait for the binary to launch. lldbutil.wait_for_file_on_target(self, token) # Move the binary into the 'SDK'. rel_exe_path = os.path.relpath(exe, '/') exe_sdk_path = os.path.join(symbols_dir, rel_exe_path) lldbutil.mkdir_p(os.path.dirname(exe_sdk_path)) shutil.move(exe, exe_sdk_path) # Attach to it with debugserver. debugserver = get_debugserver_exe() debugserver_args = [ 'localhost:{}'.format(self.PORT), '--attach={}'.format(pid) ] self.spawnSubprocess(debugserver, debugserver_args) # Select the platform. self.expect('platform select remote-macosx', substrs=[sdk_dir]) # Connect to debugserver interpreter = self.dbg.GetCommandInterpreter() connected = False for i in range(self.ATTEMPTS): result = lldb.SBCommandReturnObject() interpreter.HandleCommand('gdb-remote {}'.format(self.PORT), result) connected = result.Succeeded() if connected: break time.sleep(self.TIMEOUT) self.assertTrue(connected, "could not connect to debugserver") # Make sure the image was loaded from the 'SDK'. self.expect('image list', substrs=[exe_sdk_path])
def await_token(self, name): for i in range(6): lldbutil.wait_for_file_on_target(self, name + '.token.%d' % (i + 1))
def test_platform_process_connect(self): self.build() self.init_llgs_test(False) working_dir = lldb.remote_platform.GetWorkingDirectory() src = lldb.SBFileSpec(self.getBuildArtifact("a.out")) dest = lldb.SBFileSpec(os.path.join(working_dir, "a.out")) err = lldb.remote_platform.Put(src, dest) if err.Fail(): raise RuntimeError("Unable copy '%s' to '%s'.\n>>> %s" % (f, wd, err.GetCString())) m = re.search("^(.*)://([^:/]*)", configuration.lldb_platform_url) protocol = m.group(1) hostname = m.group(2) unix_protocol = protocol.startswith("unix-") if unix_protocol: p = re.search("^(.*)-connect", protocol) path = lldbutil.join_remote_paths( configuration.lldb_platform_working_dir, self.getBuildDirBasename(), "platform-%d.sock" % int(time.time())) listen_url = "%s://%s" % (p.group(1), path) else: listen_url = "*:0" port_file = "%s/port" % working_dir commandline_args = [ "platform", "--listen", listen_url, "--socket-file", port_file, "--", "%s/a.out" % working_dir, "foo" ] self.spawnSubprocess(self.debug_monitor_exe, commandline_args, install_remote=False) socket_id = lldbutil.wait_for_file_on_target(self, port_file) self.dbg.SetAsync(False) new_platform = lldb.SBPlatform(lldb.remote_platform.GetName()) self.dbg.SetSelectedPlatform(new_platform) if unix_protocol: connect_url = "%s://%s%s" % (protocol, hostname, socket_id) else: connect_url = "%s://%s:%s" % (protocol, hostname, socket_id) command = "platform connect %s" % (connect_url) result = lldb.SBCommandReturnObject() self.dbg.GetCommandInterpreter().HandleCommand(command, result) self.assertTrue( result.Succeeded(), "platform process connect failed: %s" % result.GetOutput()) target = self.dbg.GetSelectedTarget() process = target.GetProcess() thread = process.GetThreadAtIndex(0) breakpoint = target.BreakpointCreateByName("main") process.Continue() frame = thread.GetFrameAtIndex(0) self.assertEqual(frame.GetFunction().GetName(), "main") self.assertEqual(frame.FindVariable("argc").GetValueAsSigned(), 2) process.Continue()
def test_target_auto_install_main_executable(self): self.build() hostname = socket.getaddrinfo("localhost", 0, proto=socket.IPPROTO_TCP)[0][4][0] listen_url = "[%s]:0" % hostname port_file = self.getBuildArtifact("port") commandline_args = [ "platform", "--listen", listen_url, "--socket-file", port_file ] self.spawnSubprocess(lldbgdbserverutils.get_lldb_server_exe(), commandline_args) socket_id = lldbutil.wait_for_file_on_target(self, port_file) new_platform = lldb.SBPlatform("remote-" + self.getPlatform()) self.dbg.SetSelectedPlatform(new_platform) connect_url = "connect://[%s]:%s" % (hostname, socket_id) connect_opts = lldb.SBPlatformConnectOptions(connect_url) self.assertSuccess(new_platform.ConnectRemote(connect_opts)) wd = self.getBuildArtifact("wd") os.mkdir(wd) new_platform.SetWorkingDirectory(wd) # Manually install the modified binary. src_device = lldb.SBFileSpec(self.getBuildArtifact("a.device.out")) dest = lldb.SBFileSpec(os.path.join(wd, "a.out")) self.assertSuccess(new_platform.Put(src_device, dest)) # Test the default setting. self.expect( "settings show target.auto-install-main-executable", substrs=["target.auto-install-main-executable (boolean) = true"], msg= "Default settings for target.auto-install-main-executable failed.") # Disable the auto install. self.runCmd("settings set target.auto-install-main-executable false") self.expect( "settings show target.auto-install-main-executable", substrs=["target.auto-install-main-executable (boolean) = false"]) # Create the target with the original file. self.runCmd("target create --remote-file %s %s " % (dest.fullpath, self.getBuildArtifact("a.out"))) target = self.dbg.GetSelectedTarget() breakpoint = target.BreakpointCreateByName("main") launch_info = target.GetLaunchInfo() error = lldb.SBError() process = target.Launch(launch_info, error) self.assertTrue(process, PROCESS_IS_VALID) thread = lldbutil.get_stopped_thread(process, lldb.eStopReasonBreakpoint) self.assertTrue(thread.IsValid(), "There should be a thread stopped due to breakpoint") frame = thread.GetFrameAtIndex(0) self.assertEqual(frame.GetFunction().GetName(), "main") self.expect("target variable build", substrs=['"device"'], msg="Magic in the binary is wrong") process.Continue()
def _launch_and_wait_for_init(self): sync_file_path = lldbutil.append_to_process_working_directory( self, "process_ready") inferior = self._launch_inferior(self._run_args + [sync_file_path]) lldbutil.wait_for_file_on_target(self, sync_file_path) return inferior