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