xref: /llvm-project/lldb/test/API/python_api/hello_world/TestHelloWorld.py (revision 2238dcc39358353cac21df75c3c3286ab20b8f53)
1"""Test Python APIs for target (launch and attach), breakpoint, and process."""
2
3
4import os
5
6import lldb
7from lldbsuite.test.decorators import *
8from lldbsuite.test.lldbtest import *
9import lldbsuite.test.lldbutil as lldbutil
10
11
12class HelloWorldTestCase(TestBase):
13    NO_DEBUG_INFO_TESTCASE = True
14
15    def setUp(self):
16        # Call super's setUp().
17        TestBase.setUp(self)
18        # Find a couple of the line numbers within main.c.
19        self.line1 = line_number("main.c", "// Set break point at this line.")
20        self.line2 = line_number("main.c", "// Waiting to be attached...")
21
22    def tearDown(self):
23        # Destroy process before TestBase.tearDown()
24        self.dbg.GetSelectedTarget().GetProcess().Destroy()
25        # Call super's tearDown().
26        TestBase.tearDown(self)
27
28    @skipIfiOSSimulator
29    def test_with_process_launch_api(self):
30        """Create target, breakpoint, launch a process, and then kill it."""
31        # Get the full path to our executable to be attached/debugged.
32        exe = "%s_%d" % (self.getBuildArtifact(self.testMethodName), os.getpid())
33        d = {"EXE": exe}
34        self.build(dictionary=d)
35        self.setTearDownCleanup(dictionary=d)
36        target = self.dbg.CreateTarget(exe)
37
38        breakpoint = target.BreakpointCreateByLocation("main.c", self.line1)
39
40        # The default state after breakpoint creation should be enabled.
41        self.assertTrue(
42            breakpoint.IsEnabled(), "Breakpoint should be enabled after creation"
43        )
44
45        breakpoint.SetEnabled(False)
46        self.assertTrue(
47            not breakpoint.IsEnabled(), "Breakpoint.SetEnabled(False) works"
48        )
49
50        breakpoint.SetEnabled(True)
51        self.assertTrue(breakpoint.IsEnabled(), "Breakpoint.SetEnabled(True) works")
52
53        # rdar://problem/8364687
54        # SBTarget.Launch() issue (or is there some race condition)?
55
56        process = target.LaunchSimple(None, None, self.get_process_working_directory())
57        # The following isn't needed anymore, rdar://8364687 is fixed.
58        #
59        # Apply some dances after LaunchProcess() in order to break at "main".
60        # It only works sometimes.
61        # self.breakAfterLaunch(process, "main")
62
63        process = target.GetProcess()
64        self.assertTrue(process, PROCESS_IS_VALID)
65
66        thread = lldbutil.get_stopped_thread(process, lldb.eStopReasonBreakpoint)
67        self.assertIsNotNone(thread)
68
69        # The breakpoint should have a hit count of 1.
70        self.assertEqual(breakpoint.GetHitCount(), 1, BREAKPOINT_HIT_ONCE)
71
72    @skipIfiOSSimulator
73    def test_with_attach_to_process_with_id_api(self):
74        """Create target, spawn a process, and attach to it with process id."""
75        exe = "%s_%d" % (self.testMethodName, os.getpid())
76        d = {"EXE": exe}
77        self.build(dictionary=d)
78        self.setTearDownCleanup(dictionary=d)
79        target = self.dbg.CreateTarget(self.getBuildArtifact(exe))
80
81        # Spawn a new process
82        token = exe + ".token"
83        if not lldb.remote_platform:
84            token = self.getBuildArtifact(token)
85            if os.path.exists(token):
86                os.remove(token)
87        popen = self.spawnSubprocess(self.getBuildArtifact(exe), [token])
88        lldbutil.wait_for_file_on_target(self, token)
89
90        listener = lldb.SBListener("my.attach.listener")
91        error = lldb.SBError()
92        process = target.AttachToProcessWithID(listener, popen.pid, error)
93
94        self.assertTrue(error.Success() and process, PROCESS_IS_VALID)
95
96        # Let's check the stack traces of the attached process.
97        stacktraces = lldbutil.print_stacktraces(process, string_buffer=True)
98        self.expect(
99            stacktraces, exe=False, substrs=["main.c:%d" % self.line2, "(int)argc=2"]
100        )
101
102    @skipIfiOSSimulator
103    @skipIfAsan  # FIXME: Hangs indefinitely.
104    def test_with_attach_to_process_with_name_api(self):
105        """Create target, spawn a process, and attach to it with process name."""
106        exe = "%s_%d" % (self.testMethodName, os.getpid())
107        d = {"EXE": exe}
108        self.build(dictionary=d)
109        self.setTearDownCleanup(dictionary=d)
110        target = self.dbg.CreateTarget(self.getBuildArtifact(exe))
111
112        # Spawn a new process.
113        token = exe + ".token"
114        if not lldb.remote_platform:
115            token = self.getBuildArtifact(token)
116            if os.path.exists(token):
117                os.remove(token)
118        popen = self.spawnSubprocess(self.getBuildArtifact(exe), [token])
119        lldbutil.wait_for_file_on_target(self, token)
120
121        listener = lldb.SBListener("my.attach.listener")
122        error = lldb.SBError()
123        # Pass 'False' since we don't want to wait for new instance of
124        # "hello_world" to be launched.
125        name = os.path.basename(exe)
126
127        # While we're at it, make sure that passing a None as the process name
128        # does not hang LLDB.
129        target.AttachToProcessWithName(listener, None, False, error)
130        # Also boundary condition test ConnectRemote(), too.
131        target.ConnectRemote(listener, None, None, error)
132
133        process = target.AttachToProcessWithName(listener, name, False, error)
134        self.assertSuccess(error)
135        self.assertTrue(process, PROCESS_IS_VALID)
136
137        # Verify that after attach, our selected target indeed matches name.
138        self.expect(
139            self.dbg.GetSelectedTarget().GetExecutable().GetFilename(),
140            exe=False,
141            startstr=name,
142        )
143
144        # Let's check the stack traces of the attached process.
145        stacktraces = lldbutil.print_stacktraces(process, string_buffer=True)
146        self.expect(
147            stacktraces, exe=False, substrs=["main.c:%d" % self.line2, "(int)argc=2"]
148        )
149