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