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