xref: /llvm-project/lldb/test/API/python_api/hello_world/TestHelloWorld.py (revision 35674976f09ec99e74d0d28b4a64b6bce360c128)
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    @expectedFailureNetBSD
78    @skipIfReproducer # File synchronization is not supported during replay.
79    def test_with_attach_to_process_with_id_api(self):
80        """Create target, spawn a process, and attach to it with process id."""
81        exe = '%s_%d'%(self.testMethodName, os.getpid())
82        d = {'EXE': exe}
83        self.build(dictionary=d)
84        self.setTearDownCleanup(dictionary=d)
85        target = self.dbg.CreateTarget(self.getBuildArtifact(exe))
86
87        # Spawn a new process
88        token = exe+'.token'
89        if not lldb.remote_platform:
90            token = self.getBuildArtifact(token)
91            if os.path.exists(token):
92                os.remove(token)
93        popen = self.spawnSubprocess(self.getBuildArtifact(exe), [token])
94        self.addTearDownHook(self.cleanupSubprocesses)
95        lldbutil.wait_for_file_on_target(self, token)
96
97        listener = lldb.SBListener("my.attach.listener")
98        error = lldb.SBError()
99        process = target.AttachToProcessWithID(listener, popen.pid, error)
100
101        self.assertTrue(error.Success() and process, PROCESS_IS_VALID)
102
103        # Let's check the stack traces of the attached process.
104        stacktraces = lldbutil.print_stacktraces(process, string_buffer=True)
105        self.expect(stacktraces, exe=False,
106                    substrs=['main.c:%d' % self.line2,
107                             '(int)argc=2'])
108
109    @add_test_categories(['pyapi'])
110    @skipIfiOSSimulator
111    @skipIfAsan # FIXME: Hangs indefinitely.
112    @expectedFailureNetBSD
113    @skipIfReproducer # FIXME: Unexpected packet during (active) replay
114    def test_with_attach_to_process_with_name_api(self):
115        """Create target, spawn a process, and attach to it with process name."""
116        exe = '%s_%d'%(self.testMethodName, os.getpid())
117        d = {'EXE': exe}
118        self.build(dictionary=d)
119        self.setTearDownCleanup(dictionary=d)
120        target = self.dbg.CreateTarget(self.getBuildArtifact(exe))
121
122        # Spawn a new process.
123        token = exe+'.token'
124        if not lldb.remote_platform:
125            token = self.getBuildArtifact(token)
126            if os.path.exists(token):
127                os.remove(token)
128        popen = self.spawnSubprocess(self.getBuildArtifact(exe), [token])
129        self.addTearDownHook(self.cleanupSubprocesses)
130        lldbutil.wait_for_file_on_target(self, token)
131
132        listener = lldb.SBListener("my.attach.listener")
133        error = lldb.SBError()
134        # Pass 'False' since we don't want to wait for new instance of
135        # "hello_world" to be launched.
136        name = os.path.basename(exe)
137
138        # While we're at it, make sure that passing a None as the process name
139        # does not hang LLDB.
140        target.AttachToProcessWithName(listener, None, False, error)
141        # Also boundary condition test ConnectRemote(), too.
142        target.ConnectRemote(listener, None, None, error)
143
144        process = target.AttachToProcessWithName(listener, name, False, error)
145        self.assertSuccess(error)
146        self.assertTrue(process, PROCESS_IS_VALID)
147
148        # Verify that after attach, our selected target indeed matches name.
149        self.expect(
150            self.dbg.GetSelectedTarget().GetExecutable().GetFilename(),
151            exe=False,
152            startstr=name)
153
154        # Let's check the stack traces of the attached process.
155        stacktraces = lldbutil.print_stacktraces(process, string_buffer=True)
156        self.expect(stacktraces, exe=False,
157                    substrs=['main.c:%d' % self.line2,
158                             '(int)argc=2'])
159