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