xref: /llvm-project/lldb/test/API/python_api/hello_world/TestHelloWorld.py (revision 2238dcc39358353cac21df75c3c3286ab20b8f53)
199451b44SJordan Rupprecht"""Test Python APIs for target (launch and attach), breakpoint, and process."""
299451b44SJordan Rupprecht
399451b44SJordan Rupprecht
499451b44SJordan Rupprechtimport os
599451b44SJordan Rupprecht
699451b44SJordan Rupprechtimport lldb
799451b44SJordan Rupprechtfrom lldbsuite.test.decorators import *
899451b44SJordan Rupprechtfrom lldbsuite.test.lldbtest import *
999451b44SJordan Rupprechtimport lldbsuite.test.lldbutil as lldbutil
1099451b44SJordan Rupprecht
11*2238dcc3SJonas Devlieghere
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.
19*2238dcc3SJonas Devlieghere        self.line1 = line_number("main.c", "// Set break point at this line.")
20*2238dcc3SJonas Devlieghere        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.
32*2238dcc3SJonas Devlieghere        exe = "%s_%d" % (self.getBuildArtifact(self.testMethodName), os.getpid())
33*2238dcc3SJonas Devlieghere        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.
41*2238dcc3SJonas Devlieghere        self.assertTrue(
42*2238dcc3SJonas Devlieghere            breakpoint.IsEnabled(), "Breakpoint should be enabled after creation"
43*2238dcc3SJonas Devlieghere        )
4499451b44SJordan Rupprecht
4599451b44SJordan Rupprecht        breakpoint.SetEnabled(False)
46*2238dcc3SJonas Devlieghere        self.assertTrue(
47*2238dcc3SJonas Devlieghere            not breakpoint.IsEnabled(), "Breakpoint.SetEnabled(False) works"
48*2238dcc3SJonas Devlieghere        )
4999451b44SJordan Rupprecht
5099451b44SJordan Rupprecht        breakpoint.SetEnabled(True)
51*2238dcc3SJonas Devlieghere        self.assertTrue(breakpoint.IsEnabled(), "Breakpoint.SetEnabled(True) works")
5299451b44SJordan Rupprecht
5399451b44SJordan Rupprecht        # rdar://problem/8364687
5499451b44SJordan Rupprecht        # SBTarget.Launch() issue (or is there some race condition)?
5599451b44SJordan Rupprecht
56*2238dcc3SJonas Devlieghere        process = target.LaunchSimple(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
66*2238dcc3SJonas Devlieghere        thread = lldbutil.get_stopped_thread(process, lldb.eStopReasonBreakpoint)
6799451b44SJordan Rupprecht        self.assertIsNotNone(thread)
6899451b44SJordan Rupprecht
6999451b44SJordan Rupprecht        # The breakpoint should have a hit count of 1.
7099451b44SJordan Rupprecht        self.assertEqual(breakpoint.GetHitCount(), 1, BREAKPOINT_HIT_ONCE)
7199451b44SJordan Rupprecht
7299451b44SJordan Rupprecht    @skipIfiOSSimulator
7399451b44SJordan Rupprecht    def test_with_attach_to_process_with_id_api(self):
7499451b44SJordan Rupprecht        """Create target, spawn a process, and attach to it with process id."""
75*2238dcc3SJonas Devlieghere        exe = "%s_%d" % (self.testMethodName, os.getpid())
76*2238dcc3SJonas Devlieghere        d = {"EXE": exe}
7799451b44SJordan Rupprecht        self.build(dictionary=d)
7899451b44SJordan Rupprecht        self.setTearDownCleanup(dictionary=d)
7999451b44SJordan Rupprecht        target = self.dbg.CreateTarget(self.getBuildArtifact(exe))
8099451b44SJordan Rupprecht
8199451b44SJordan Rupprecht        # Spawn a new process
82*2238dcc3SJonas Devlieghere        token = exe + ".token"
8399451b44SJordan Rupprecht        if not lldb.remote_platform:
8499451b44SJordan Rupprecht            token = self.getBuildArtifact(token)
8599451b44SJordan Rupprecht            if os.path.exists(token):
8699451b44SJordan Rupprecht                os.remove(token)
8799451b44SJordan Rupprecht        popen = self.spawnSubprocess(self.getBuildArtifact(exe), [token])
8899451b44SJordan Rupprecht        lldbutil.wait_for_file_on_target(self, token)
8999451b44SJordan Rupprecht
9099451b44SJordan Rupprecht        listener = lldb.SBListener("my.attach.listener")
9199451b44SJordan Rupprecht        error = lldb.SBError()
9299451b44SJordan Rupprecht        process = target.AttachToProcessWithID(listener, popen.pid, error)
9399451b44SJordan Rupprecht
9499451b44SJordan Rupprecht        self.assertTrue(error.Success() and process, PROCESS_IS_VALID)
9599451b44SJordan Rupprecht
9699451b44SJordan Rupprecht        # Let's check the stack traces of the attached process.
9799451b44SJordan Rupprecht        stacktraces = lldbutil.print_stacktraces(process, string_buffer=True)
98*2238dcc3SJonas Devlieghere        self.expect(
99*2238dcc3SJonas Devlieghere            stacktraces, exe=False, substrs=["main.c:%d" % self.line2, "(int)argc=2"]
100*2238dcc3SJonas Devlieghere        )
10199451b44SJordan Rupprecht
10299451b44SJordan Rupprecht    @skipIfiOSSimulator
10399451b44SJordan Rupprecht    @skipIfAsan  # FIXME: Hangs indefinitely.
10499451b44SJordan Rupprecht    def test_with_attach_to_process_with_name_api(self):
10599451b44SJordan Rupprecht        """Create target, spawn a process, and attach to it with process name."""
106*2238dcc3SJonas Devlieghere        exe = "%s_%d" % (self.testMethodName, os.getpid())
107*2238dcc3SJonas Devlieghere        d = {"EXE": exe}
10899451b44SJordan Rupprecht        self.build(dictionary=d)
10999451b44SJordan Rupprecht        self.setTearDownCleanup(dictionary=d)
11099451b44SJordan Rupprecht        target = self.dbg.CreateTarget(self.getBuildArtifact(exe))
11199451b44SJordan Rupprecht
11299451b44SJordan Rupprecht        # Spawn a new process.
113*2238dcc3SJonas Devlieghere        token = exe + ".token"
11499451b44SJordan Rupprecht        if not lldb.remote_platform:
11599451b44SJordan Rupprecht            token = self.getBuildArtifact(token)
11699451b44SJordan Rupprecht            if os.path.exists(token):
11799451b44SJordan Rupprecht                os.remove(token)
11899451b44SJordan Rupprecht        popen = self.spawnSubprocess(self.getBuildArtifact(exe), [token])
11999451b44SJordan Rupprecht        lldbutil.wait_for_file_on_target(self, token)
12099451b44SJordan Rupprecht
12199451b44SJordan Rupprecht        listener = lldb.SBListener("my.attach.listener")
12299451b44SJordan Rupprecht        error = lldb.SBError()
12399451b44SJordan Rupprecht        # Pass 'False' since we don't want to wait for new instance of
12499451b44SJordan Rupprecht        # "hello_world" to be launched.
12599451b44SJordan Rupprecht        name = os.path.basename(exe)
12699451b44SJordan Rupprecht
12799451b44SJordan Rupprecht        # While we're at it, make sure that passing a None as the process name
12899451b44SJordan Rupprecht        # does not hang LLDB.
12999451b44SJordan Rupprecht        target.AttachToProcessWithName(listener, None, False, error)
13099451b44SJordan Rupprecht        # Also boundary condition test ConnectRemote(), too.
13199451b44SJordan Rupprecht        target.ConnectRemote(listener, None, None, error)
13299451b44SJordan Rupprecht
13399451b44SJordan Rupprecht        process = target.AttachToProcessWithName(listener, name, False, error)
13435674976SPavel Labath        self.assertSuccess(error)
13535674976SPavel Labath        self.assertTrue(process, PROCESS_IS_VALID)
13699451b44SJordan Rupprecht
13799451b44SJordan Rupprecht        # Verify that after attach, our selected target indeed matches name.
13899451b44SJordan Rupprecht        self.expect(
13999451b44SJordan Rupprecht            self.dbg.GetSelectedTarget().GetExecutable().GetFilename(),
14099451b44SJordan Rupprecht            exe=False,
141*2238dcc3SJonas Devlieghere            startstr=name,
142*2238dcc3SJonas Devlieghere        )
14399451b44SJordan Rupprecht
14499451b44SJordan Rupprecht        # Let's check the stack traces of the attached process.
14599451b44SJordan Rupprecht        stacktraces = lldbutil.print_stacktraces(process, string_buffer=True)
146*2238dcc3SJonas Devlieghere        self.expect(
147*2238dcc3SJonas Devlieghere            stacktraces, exe=False, substrs=["main.c:%d" % self.line2, "(int)argc=2"]
148*2238dcc3SJonas Devlieghere        )
149