xref: /llvm-project/lldb/test/API/python_api/debugger/TestDebuggerAPI.py (revision 4cc8f2a017c76af25234afc7c380550e9c93135c)
1"""
2Test Debugger APIs.
3"""
4
5import lldb
6
7from lldbsuite.test.decorators import *
8from lldbsuite.test.lldbtest import *
9from lldbsuite.test import lldbutil
10
11
12class DebuggerAPITestCase(TestBase):
13    NO_DEBUG_INFO_TESTCASE = True
14
15    def test_debugger_api_boundary_condition(self):
16        """Exercise SBDebugger APIs with boundary conditions."""
17        self.dbg.HandleCommand(None)
18        self.dbg.SetDefaultArchitecture(None)
19        self.dbg.GetScriptingLanguage(None)
20        self.dbg.CreateTarget(None)
21        self.dbg.CreateTarget(None, None, None, True, lldb.SBError())
22        self.dbg.CreateTargetWithFileAndTargetTriple(None, None)
23        self.dbg.CreateTargetWithFileAndArch(None, None)
24        self.dbg.FindTargetWithFileAndArch(None, None)
25        self.dbg.SetInternalVariable(None, None, None)
26        self.dbg.GetInternalVariableValue(None, None)
27        # FIXME (filcab): We must first allow for the swig bindings to know if
28        # a Python callback is set. (Check python-typemaps.swig)
29        # self.dbg.SetLoggingCallback(None)
30        self.dbg.SetPrompt(None)
31        self.dbg.SetCurrentPlatform(None)
32        self.dbg.SetCurrentPlatformSDKRoot(None)
33
34        fresh_dbg = lldb.SBDebugger()
35        self.assertEquals(len(fresh_dbg), 0)
36
37    def test_debugger_delete_invalid_target(self):
38        """SBDebugger.DeleteTarget() should not crash LLDB given and invalid target."""
39        target = lldb.SBTarget()
40        self.assertFalse(target.IsValid())
41        self.dbg.DeleteTarget(target)
42
43    def test_debugger_internal_variables(self):
44        """Ensure that SBDebugger reachs the same instance of properties
45           regardless CommandInterpreter's context initialization"""
46        self.build()
47        exe = self.getBuildArtifact("a.out")
48
49        # Create a target by the debugger.
50        target = self.dbg.CreateTarget(exe)
51        self.assertTrue(target, VALID_TARGET)
52
53        property_name = "target.process.memory-cache-line-size"
54
55        def get_cache_line_size():
56            value_list = lldb.SBStringList()
57            value_list = self.dbg.GetInternalVariableValue(property_name,
58                                                           self.dbg.GetInstanceName())
59
60            self.assertEqual(value_list.GetSize(), 1)
61            try:
62                return int(value_list.GetStringAtIndex(0))
63            except ValueError as error:
64                self.fail("Value is not a number: " + error)
65
66        # Get global property value while there are no processes.
67        global_cache_line_size = get_cache_line_size()
68
69        # Run a process via SB interface. CommandInterpreter's execution context
70        # remains empty.
71        error = lldb.SBError()
72        launch_info = lldb.SBLaunchInfo(None)
73        launch_info.SetLaunchFlags(lldb.eLaunchFlagStopAtEntry)
74        process = target.Launch(launch_info, error)
75        self.assertTrue(process, PROCESS_IS_VALID)
76
77        # This should change the value of a process's local property.
78        new_cache_line_size = global_cache_line_size + 512
79        error = self.dbg.SetInternalVariable(property_name,
80                                             str(new_cache_line_size),
81                                             self.dbg.GetInstanceName())
82        self.assertSuccess(error,
83                           property_name + " value was changed successfully")
84
85        # Check that it was set actually.
86        self.assertEqual(get_cache_line_size(), new_cache_line_size)
87
88        # Run any command to initialize CommandInterpreter's execution context.
89        self.runCmd("target list")
90
91        # Test the local property again, is it set to new_cache_line_size?
92        self.assertEqual(get_cache_line_size(), new_cache_line_size)
93
94    def test_CreateTarget_platform(self):
95        exe = self.getBuildArtifact("a.out")
96        self.yaml2obj("elf.yaml", exe)
97        error = lldb.SBError()
98        target1 = self.dbg.CreateTarget(exe, None, "remote-linux",
99                False, error)
100        self.assertSuccess(error)
101        platform1 = target1.GetPlatform()
102        platform1.SetWorkingDirectory("/foo/bar")
103
104        # Reuse a platform if it matches the currently selected one...
105        target2 = self.dbg.CreateTarget(exe, None, "remote-linux",
106                False, error)
107        self.assertSuccess(error)
108        platform2 = target2.GetPlatform()
109        self.assertTrue(platform2.GetWorkingDirectory().endswith("bar"),
110                platform2.GetWorkingDirectory())
111
112        # ... but create a new one if it doesn't.
113        self.dbg.SetSelectedPlatform(lldb.SBPlatform("remote-windows"))
114        target3 = self.dbg.CreateTarget(exe, None, "remote-linux",
115                False, error)
116        self.assertSuccess(error)
117        platform3 = target3.GetPlatform()
118        self.assertIsNone(platform3.GetWorkingDirectory())
119
120    def test_CreateTarget_arch(self):
121        exe = self.getBuildArtifact("a.out")
122        if lldbplatformutil.getHostPlatform() == 'linux':
123            self.yaml2obj("macho.yaml", exe)
124            arch = "x86_64-apple-macosx"
125            expected_platform = "remote-macosx"
126        else:
127            self.yaml2obj("elf.yaml", exe)
128            arch = "x86_64-pc-linux"
129            expected_platform = "remote-linux"
130
131        fbsd = lldb.SBPlatform("remote-freebsd")
132        self.dbg.SetSelectedPlatform(fbsd)
133
134        error = lldb.SBError()
135        target1 = self.dbg.CreateTarget(exe, arch, None, False, error)
136        self.assertSuccess(error)
137        platform1 = target1.GetPlatform()
138        self.assertEqual(platform1.GetName(), expected_platform)
139        platform1.SetWorkingDirectory("/foo/bar")
140
141        # Reuse a platform even if it is not currently selected.
142        self.dbg.SetSelectedPlatform(fbsd)
143        target2 = self.dbg.CreateTarget(exe, arch, None, False, error)
144        self.assertSuccess(error)
145        platform2 = target2.GetPlatform()
146        self.assertEqual(platform2.GetName(), expected_platform)
147        self.assertTrue(platform2.GetWorkingDirectory().endswith("bar"),
148                platform2.GetWorkingDirectory())
149