1"""
2Test target commands: target.auto-install-main-executable.
3"""
4
5import time
6import gdbremote_testcase
7
8from lldbsuite.test.decorators import *
9from lldbsuite.test.lldbtest import *
10from lldbsuite.test import lldbutil
11
12
13class TestAutoInstallMainExecutable(gdbremote_testcase.GdbRemoteTestCaseBase):
14    mydir = TestBase.compute_mydir(__file__)
15
16    def setUp(self):
17        super(TestAutoInstallMainExecutable, self).setUp()
18        self._initial_platform = lldb.DBG.GetSelectedPlatform()
19
20    def tearDown(self):
21        lldb.DBG.SetSelectedPlatform(self._initial_platform)
22        super(TestAutoInstallMainExecutable, self).tearDown()
23
24    @llgs_test
25    @no_debug_info_test
26    @skipIf(remote=False)
27    @expectedFailureAll(hostoslist=["windows"], triple='.*-android')
28    def test_target_auto_install_main_executable(self):
29        self.build()
30        self.init_llgs_test(False)
31
32        # Manually install the modified binary.
33        working_dir = lldb.remote_platform.GetWorkingDirectory()
34        src_device = lldb.SBFileSpec(self.getBuildArtifact("a.device.out"))
35        dest = lldb.SBFileSpec(os.path.join(working_dir, "a.out"))
36        err = lldb.remote_platform.Put(src_device, dest)
37        if err.Fail():
38            raise RuntimeError(
39                "Unable copy '%s' to '%s'.\n>>> %s" %
40                (src_device.GetFilename(), working_dir, err.GetCString()))
41
42        m = re.search("^(.*)://([^/]*):(.*)$", configuration.lldb_platform_url)
43        protocol = m.group(1)
44        hostname = m.group(2)
45        hostport = int(m.group(3))
46        listen_url = "*:"+str(hostport+1)
47
48        commandline_args = [
49            "platform",
50            "--listen",
51            listen_url,
52            "--server"
53            ]
54
55        self.spawnSubprocess(
56            self.debug_monitor_exe,
57            commandline_args,
58            install_remote=False)
59        self.addTearDownHook(self.cleanupSubprocesses)
60
61        # Wait for the new process gets ready.
62        time.sleep(0.1)
63
64        new_debugger = lldb.SBDebugger.Create()
65        new_debugger.SetAsync(False)
66
67        def del_debugger(new_debugger=new_debugger):
68            del new_debugger
69        self.addTearDownHook(del_debugger)
70
71        new_platform = lldb.SBPlatform(lldb.remote_platform.GetName())
72        new_debugger.SetSelectedPlatform(new_platform)
73        new_interpreter = new_debugger.GetCommandInterpreter()
74
75        connect_url = "%s://%s:%s" % (protocol, hostname, str(hostport+1))
76
77        command = "platform connect %s" % (connect_url)
78
79        result = lldb.SBCommandReturnObject()
80
81        # Test the default setting.
82        new_interpreter.HandleCommand("settings show target.auto-install-main-executable", result)
83        self.assertTrue(
84            result.Succeeded() and
85            "target.auto-install-main-executable (boolean) = true" in result.GetOutput(),
86            "Default settings for target.auto-install-main-executable failed.: %s - %s" %
87            (result.GetOutput(), result.GetError()))
88
89        # Disable the auto install.
90        new_interpreter.HandleCommand("settings set target.auto-install-main-executable false", result)
91        new_interpreter.HandleCommand("settings show target.auto-install-main-executable", result)
92        self.assertTrue(
93            result.Succeeded() and
94            "target.auto-install-main-executable (boolean) = false" in result.GetOutput(),
95            "Default settings for target.auto-install-main-executable failed.: %s - %s" %
96            (result.GetOutput(), result.GetError()))
97
98        new_interpreter.HandleCommand("platform select %s"%configuration.lldb_platform_name, result)
99        new_interpreter.HandleCommand(command, result)
100
101        self.assertTrue(
102            result.Succeeded(),
103            "platform process connect failed: %s - %s" %
104            (result.GetOutput(),result.GetError()))
105
106        # Create the target with the original file.
107        new_interpreter.HandleCommand("target create --remote-file %s %s "%
108                                        (os.path.join(working_dir,dest.GetFilename()), self.getBuildArtifact("a.out")),
109                                      result)
110        self.assertTrue(
111            result.Succeeded(),
112            "platform create failed: %s - %s" %
113            (result.GetOutput(),result.GetError()))
114
115        target = new_debugger.GetSelectedTarget()
116        breakpoint = target.BreakpointCreateByName("main")
117
118        launch_info = lldb.SBLaunchInfo(None)
119        error = lldb.SBError()
120        process = target.Launch(launch_info, error)
121        self.assertTrue(process, PROCESS_IS_VALID)
122
123        thread = lldbutil.get_stopped_thread(process, lldb.eStopReasonBreakpoint)
124        self.assertTrue(
125            thread.IsValid(),
126            "There should be a thread stopped due to breakpoint")
127
128        frame = thread.GetFrameAtIndex(0)
129        self.assertEqual(frame.GetFunction().GetName(), "main")
130
131        new_interpreter.HandleCommand("target variable build", result)
132        self.assertTrue(
133            result.Succeeded() and
134            '"device"' in result.GetOutput(),
135            "Magic in the binary is wrong: %s " % result.GetOutput())
136
137        process.Continue()
138