199451b44SJordan Rupprecht"""Test Python APIs for target (launch and attach), breakpoint, and process."""
299451b44SJordan Rupprecht
399451b44SJordan Rupprecht
499451b44SJordan Rupprecht
599451b44SJordan Rupprechtimport os
699451b44SJordan Rupprecht
799451b44SJordan Rupprechtimport lldb
899451b44SJordan Rupprechtfrom lldbsuite.test.decorators import *
999451b44SJordan Rupprechtfrom lldbsuite.test.lldbtest import *
1099451b44SJordan Rupprechtimport lldbsuite.test.lldbutil as lldbutil
1199451b44SJordan Rupprecht
1299451b44SJordan Rupprechtclass HelloWorldTestCase(TestBase):
1399451b44SJordan Rupprecht    NO_DEBUG_INFO_TESTCASE = True
1499451b44SJordan Rupprecht
1599451b44SJordan Rupprecht    def setUp(self):
1699451b44SJordan Rupprecht        # Call super's setUp().
1799451b44SJordan Rupprecht        TestBase.setUp(self)
1899451b44SJordan Rupprecht        # Find a couple of the line numbers within main.c.
1999451b44SJordan Rupprecht        self.line1 = line_number('main.c', '// Set break point at this line.')
2099451b44SJordan Rupprecht        self.line2 = line_number('main.c', '// Waiting to be attached...')
2199451b44SJordan Rupprecht
2299451b44SJordan Rupprecht    def tearDown(self):
2399451b44SJordan Rupprecht        # Destroy process before TestBase.tearDown()
2499451b44SJordan Rupprecht        self.dbg.GetSelectedTarget().GetProcess().Destroy()
2599451b44SJordan Rupprecht        # Call super's tearDown().
2699451b44SJordan Rupprecht        TestBase.tearDown(self)
2799451b44SJordan Rupprecht
2899451b44SJordan Rupprecht    @skipIfiOSSimulator
2999451b44SJordan Rupprecht    def test_with_process_launch_api(self):
3099451b44SJordan Rupprecht        """Create target, breakpoint, launch a process, and then kill it."""
3199451b44SJordan Rupprecht        # Get the full path to our executable to be attached/debugged.
3299451b44SJordan Rupprecht        exe = '%s_%d'%(self.getBuildArtifact(self.testMethodName), os.getpid())
3399451b44SJordan Rupprecht        d = {'EXE': exe}
3499451b44SJordan Rupprecht        self.build(dictionary=d)
3599451b44SJordan Rupprecht        self.setTearDownCleanup(dictionary=d)
3699451b44SJordan Rupprecht        target = self.dbg.CreateTarget(exe)
3799451b44SJordan Rupprecht
3899451b44SJordan Rupprecht        breakpoint = target.BreakpointCreateByLocation("main.c", self.line1)
3999451b44SJordan Rupprecht
4099451b44SJordan Rupprecht        # The default state after breakpoint creation should be enabled.
4199451b44SJordan Rupprecht        self.assertTrue(breakpoint.IsEnabled(),
4299451b44SJordan Rupprecht                        "Breakpoint should be enabled after creation")
4399451b44SJordan Rupprecht
4499451b44SJordan Rupprecht        breakpoint.SetEnabled(False)
4599451b44SJordan Rupprecht        self.assertTrue(not breakpoint.IsEnabled(),
4699451b44SJordan Rupprecht                        "Breakpoint.SetEnabled(False) works")
4799451b44SJordan Rupprecht
4899451b44SJordan Rupprecht        breakpoint.SetEnabled(True)
4999451b44SJordan Rupprecht        self.assertTrue(breakpoint.IsEnabled(),
5099451b44SJordan Rupprecht                        "Breakpoint.SetEnabled(True) works")
5199451b44SJordan Rupprecht
5299451b44SJordan Rupprecht        # rdar://problem/8364687
5399451b44SJordan Rupprecht        # SBTarget.Launch() issue (or is there some race condition)?
5499451b44SJordan Rupprecht
5599451b44SJordan Rupprecht        process = target.LaunchSimple(
5699451b44SJordan Rupprecht            None, None, self.get_process_working_directory())
5799451b44SJordan Rupprecht        # The following isn't needed anymore, rdar://8364687 is fixed.
5899451b44SJordan Rupprecht        #
5999451b44SJordan Rupprecht        # Apply some dances after LaunchProcess() in order to break at "main".
6099451b44SJordan Rupprecht        # It only works sometimes.
6199451b44SJordan Rupprecht        #self.breakAfterLaunch(process, "main")
6299451b44SJordan Rupprecht
6399451b44SJordan Rupprecht        process = target.GetProcess()
6499451b44SJordan Rupprecht        self.assertTrue(process, PROCESS_IS_VALID)
6599451b44SJordan Rupprecht
6699451b44SJordan Rupprecht        thread = lldbutil.get_stopped_thread(
6799451b44SJordan Rupprecht            process, lldb.eStopReasonBreakpoint)
6899451b44SJordan Rupprecht        self.assertIsNotNone(thread)
6999451b44SJordan Rupprecht
7099451b44SJordan Rupprecht        # The breakpoint should have a hit count of 1.
7199451b44SJordan Rupprecht        self.assertEqual(breakpoint.GetHitCount(), 1, BREAKPOINT_HIT_ONCE)
7299451b44SJordan Rupprecht
7399451b44SJordan Rupprecht    @skipIfiOSSimulator
7499451b44SJordan Rupprecht    def test_with_attach_to_process_with_id_api(self):
7599451b44SJordan Rupprecht        """Create target, spawn a process, and attach to it with process id."""
7699451b44SJordan Rupprecht        exe = '%s_%d'%(self.testMethodName, os.getpid())
7799451b44SJordan Rupprecht        d = {'EXE': exe}
7899451b44SJordan Rupprecht        self.build(dictionary=d)
7999451b44SJordan Rupprecht        self.setTearDownCleanup(dictionary=d)
8099451b44SJordan Rupprecht        target = self.dbg.CreateTarget(self.getBuildArtifact(exe))
8199451b44SJordan Rupprecht
8299451b44SJordan Rupprecht        # Spawn a new process
8399451b44SJordan Rupprecht        token = exe+'.token'
8499451b44SJordan Rupprecht        if not lldb.remote_platform:
8599451b44SJordan Rupprecht            token = self.getBuildArtifact(token)
8699451b44SJordan Rupprecht            if os.path.exists(token):
8799451b44SJordan Rupprecht                os.remove(token)
8899451b44SJordan Rupprecht        popen = self.spawnSubprocess(self.getBuildArtifact(exe), [token])
8999451b44SJordan Rupprecht        lldbutil.wait_for_file_on_target(self, token)
9099451b44SJordan Rupprecht
9199451b44SJordan Rupprecht        listener = lldb.SBListener("my.attach.listener")
9299451b44SJordan Rupprecht        error = lldb.SBError()
9399451b44SJordan Rupprecht        process = target.AttachToProcessWithID(listener, popen.pid, error)
9499451b44SJordan Rupprecht
9599451b44SJordan Rupprecht        self.assertTrue(error.Success() and process, PROCESS_IS_VALID)
9699451b44SJordan Rupprecht
9799451b44SJordan Rupprecht        # Let's check the stack traces of the attached process.
9899451b44SJordan Rupprecht        stacktraces = lldbutil.print_stacktraces(process, string_buffer=True)
9999451b44SJordan Rupprecht        self.expect(stacktraces, exe=False,
10099451b44SJordan Rupprecht                    substrs=['main.c:%d' % self.line2,
10199451b44SJordan Rupprecht                             '(int)argc=2'])
10299451b44SJordan Rupprecht
10399451b44SJordan Rupprecht    @skipIfiOSSimulator
10499451b44SJordan Rupprecht    @skipIfAsan # FIXME: Hangs indefinitely.
10599451b44SJordan Rupprecht    def test_with_attach_to_process_with_name_api(self):
10699451b44SJordan Rupprecht        """Create target, spawn a process, and attach to it with process name."""
10799451b44SJordan Rupprecht        exe = '%s_%d'%(self.testMethodName, os.getpid())
10899451b44SJordan Rupprecht        d = {'EXE': exe}
10999451b44SJordan Rupprecht        self.build(dictionary=d)
11099451b44SJordan Rupprecht        self.setTearDownCleanup(dictionary=d)
11199451b44SJordan Rupprecht        target = self.dbg.CreateTarget(self.getBuildArtifact(exe))
11299451b44SJordan Rupprecht
11399451b44SJordan Rupprecht        # Spawn a new process.
11499451b44SJordan Rupprecht        token = exe+'.token'
11599451b44SJordan Rupprecht        if not lldb.remote_platform:
11699451b44SJordan Rupprecht            token = self.getBuildArtifact(token)
11799451b44SJordan Rupprecht            if os.path.exists(token):
11899451b44SJordan Rupprecht                os.remove(token)
11999451b44SJordan Rupprecht        popen = self.spawnSubprocess(self.getBuildArtifact(exe), [token])
12099451b44SJordan Rupprecht        lldbutil.wait_for_file_on_target(self, token)
12199451b44SJordan Rupprecht
12299451b44SJordan Rupprecht        listener = lldb.SBListener("my.attach.listener")
12399451b44SJordan Rupprecht        error = lldb.SBError()
12499451b44SJordan Rupprecht        # Pass 'False' since we don't want to wait for new instance of
12599451b44SJordan Rupprecht        # "hello_world" to be launched.
12699451b44SJordan Rupprecht        name = os.path.basename(exe)
12799451b44SJordan Rupprecht
12899451b44SJordan Rupprecht        # While we're at it, make sure that passing a None as the process name
12999451b44SJordan Rupprecht        # does not hang LLDB.
13099451b44SJordan Rupprecht        target.AttachToProcessWithName(listener, None, False, error)
13199451b44SJordan Rupprecht        # Also boundary condition test ConnectRemote(), too.
13299451b44SJordan Rupprecht        target.ConnectRemote(listener, None, None, error)
13399451b44SJordan Rupprecht
13499451b44SJordan Rupprecht        process = target.AttachToProcessWithName(listener, name, False, error)
135*35674976SPavel Labath        self.assertSuccess(error)
136*35674976SPavel Labath        self.assertTrue(process, PROCESS_IS_VALID)
13799451b44SJordan Rupprecht
13899451b44SJordan Rupprecht        # Verify that after attach, our selected target indeed matches name.
13999451b44SJordan Rupprecht        self.expect(
14099451b44SJordan Rupprecht            self.dbg.GetSelectedTarget().GetExecutable().GetFilename(),
14199451b44SJordan Rupprecht            exe=False,
14299451b44SJordan Rupprecht            startstr=name)
14399451b44SJordan Rupprecht
14499451b44SJordan Rupprecht        # Let's check the stack traces of the attached process.
14599451b44SJordan Rupprecht        stacktraces = lldbutil.print_stacktraces(process, string_buffer=True)
14699451b44SJordan Rupprecht        self.expect(stacktraces, exe=False,
14799451b44SJordan Rupprecht                    substrs=['main.c:%d' % self.line2,
14899451b44SJordan Rupprecht                             '(int)argc=2'])
149