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"))
Esempio n. 2
0
    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'])
Esempio n. 3
0
    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)])
Esempio n. 4
0
    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")
Esempio n. 5
0
    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)
Esempio n. 6
0
    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()
Esempio n. 7
0
    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)
Esempio n. 9
0
    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()
Esempio n. 10
0
    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"])
Esempio n. 12
0
    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"))
Esempio n. 13
0
    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")
Esempio n. 14
0
    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)
Esempio n. 15
0
    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")
Esempio n. 18
0
    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])
Esempio n. 19
0
 def await_token(self, name):
     for i in range(6):
         lldbutil.wait_for_file_on_target(self,
                                          name + '.token.%d' % (i + 1))
Esempio n. 20
0
    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()
Esempio n. 22
0
 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