xref: /llvm-project/lldb/test/API/python_api/value/change_values/TestChangeValueAPI.py (revision ce825e46743be3e402820484bef639d12deefc2a)
1"""
2Test some SBValue APIs.
3"""
4
5
6
7import lldb
8from lldbsuite.test.decorators import *
9from lldbsuite.test.lldbtest import *
10from lldbsuite.test import lldbutil
11
12
13class ChangeValueAPITestCase(TestBase):
14
15    mydir = TestBase.compute_mydir(__file__)
16
17    def setUp(self):
18        # Call super's setUp().
19        TestBase.setUp(self)
20        # We'll use the test method name as the exe_name.
21        self.exe_name = self.testMethodName
22        # Find the line number to of function 'c'.
23        self.line = line_number('main.c', '// Stop here and set values')
24        self.check_line = line_number(
25            'main.c', '// Stop here and check values')
26        self.end_line = line_number(
27            'main.c', '// Set a breakpoint here at the end')
28
29    @expectedFlakeyLinux("llvm.org/pr25652")
30    @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24772")
31    def test_change_value(self):
32        """Exercise the SBValue::SetValueFromCString API."""
33        d = {'EXE': self.exe_name}
34        self.build(dictionary=d)
35        self.setTearDownCleanup(dictionary=d)
36        exe = self.getBuildArtifact(self.exe_name)
37
38        # Create a target by the debugger.
39        target = self.dbg.CreateTarget(exe)
40        self.assertTrue(target, VALID_TARGET)
41
42        # Create the breakpoint inside function 'main'.
43        breakpoint = target.BreakpointCreateByLocation('main.c', self.line)
44        self.assertTrue(breakpoint, VALID_BREAKPOINT)
45
46        # Create the breakpoint inside the function 'main'
47        check_breakpoint = target.BreakpointCreateByLocation(
48            'main.c', self.check_line)
49        self.assertTrue(check_breakpoint, VALID_BREAKPOINT)
50
51        # Create the breakpoint inside function 'main'.
52        end_breakpoint = target.BreakpointCreateByLocation(
53            'main.c', self.end_line)
54        self.assertTrue(end_breakpoint, VALID_BREAKPOINT)
55
56        # Now launch the process, and do not stop at entry point.
57        process = target.LaunchSimple(
58            None, None, self.get_process_working_directory())
59        self.assertTrue(process, PROCESS_IS_VALID)
60
61        # Get Frame #0.
62        self.assertState(process.GetState(), lldb.eStateStopped)
63        thread = lldbutil.get_stopped_thread(
64            process, lldb.eStopReasonBreakpoint)
65        self.assertTrue(
66            thread.IsValid(),
67            "There should be a thread stopped due to breakpoint condition")
68        frame0 = thread.GetFrameAtIndex(0)
69        self.assertTrue(frame0.IsValid(), "Got a valid frame.")
70
71        # Get the val variable and change it:
72        error = lldb.SBError()
73
74        val_value = frame0.FindVariable("val")
75        self.assertTrue(val_value.IsValid(), "Got the SBValue for val")
76        actual_value = val_value.GetValueAsSigned(error, 0)
77        self.assertSuccess(error, "Got a value from val")
78        self.assertEquals(actual_value, 100, "Got the right value from val")
79
80        result = val_value.SetValueFromCString("12345")
81        self.assertTrue(result, "Setting val returned True.")
82        actual_value = val_value.GetValueAsSigned(error, 0)
83        self.assertSuccess(error, "Got a changed value from val")
84        self.assertEqual(
85            actual_value, 12345,
86            "Got the right changed value from val")
87
88        # Now check that we can set a structure element:
89
90        mine_value = frame0.FindVariable("mine")
91        self.assertTrue(mine_value.IsValid(), "Got the SBValue for mine")
92
93        mine_second_value = mine_value.GetChildMemberWithName("second_val")
94        self.assertTrue(
95            mine_second_value.IsValid(),
96            "Got second_val from mine")
97        actual_value = mine_second_value.GetValueAsUnsigned(error, 0)
98        self.assertTrue(
99            error.Success(),
100            "Got an unsigned value for second_val")
101        self.assertEquals(actual_value, 5555)
102
103        result = mine_second_value.SetValueFromCString("98765")
104        self.assertTrue(result, "Success setting mine.second_value.")
105        actual_value = mine_second_value.GetValueAsSigned(error, 0)
106        self.assertTrue(
107            error.Success(),
108            "Got a changed value from mine.second_val")
109        self.assertEquals(actual_value, 98765,
110                        "Got the right changed value from mine.second_val")
111
112        # Next do the same thing with the pointer version.
113        ptr_value = frame0.FindVariable("ptr")
114        self.assertTrue(ptr_value.IsValid(), "Got the SBValue for ptr")
115
116        ptr_second_value = ptr_value.GetChildMemberWithName("second_val")
117        self.assertTrue(ptr_second_value.IsValid(), "Got second_val from ptr")
118        actual_value = ptr_second_value.GetValueAsUnsigned(error, 0)
119        self.assertTrue(
120            error.Success(),
121            "Got an unsigned value for ptr->second_val")
122        self.assertEquals(actual_value, 6666)
123
124        result = ptr_second_value.SetValueFromCString("98765")
125        self.assertTrue(result, "Success setting ptr->second_value.")
126        actual_value = ptr_second_value.GetValueAsSigned(error, 0)
127        self.assertTrue(
128            error.Success(),
129            "Got a changed value from ptr->second_val")
130        self.assertEquals(actual_value, 98765,
131                        "Got the right changed value from ptr->second_val")
132
133        # gcc may set multiple locations for breakpoint
134        breakpoint.SetEnabled(False)
135
136        # Now continue.
137        process.Continue()
138
139        self.assertState(process.GetState(), lldb.eStateStopped)
140        thread = lldbutil.get_stopped_thread(
141            process, lldb.eStopReasonBreakpoint)
142        self.assertTrue(
143            thread.IsValid(),
144            "There should be a thread stopped due to breakpoint condition")
145
146        expected_value = "Val - 12345 Mine - 55, 98765, 55555555. Ptr - 66, 98765, 66666666"
147        stdout = process.GetSTDOUT(1000)
148        self.assertTrue(
149            expected_value in stdout,
150            "STDOUT showed changed values.")
151
152        # Finally, change the stack pointer to 0, and we should not make it to
153        # our end breakpoint.
154        frame0 = thread.GetFrameAtIndex(0)
155        self.assertTrue(frame0.IsValid(), "Second time: got a valid frame.")
156        sp_value = frame0.FindValue("sp", lldb.eValueTypeRegister)
157        self.assertTrue(sp_value.IsValid(), "Got a stack pointer value")
158        result = sp_value.SetValueFromCString("1")
159        self.assertTrue(result, "Setting sp returned true.")
160        actual_value = sp_value.GetValueAsUnsigned(error, 0)
161        self.assertSuccess(error, "Got a changed value for sp")
162        self.assertEqual(
163            actual_value, 1,
164            "Got the right changed value for sp.")
165
166        # Boundary condition test the SBValue.CreateValueFromExpression() API.
167        # LLDB should not crash!
168        nosuchval = mine_value.CreateValueFromExpression(None, None)
169
170        process.Continue()
171
172        self.assertState(process.GetState(), lldb.eStateStopped)
173        thread = lldbutil.get_stopped_thread(
174            process, lldb.eStopReasonBreakpoint)
175        self.assertTrue(
176            thread is None,
177            "We should not have managed to hit our second breakpoint with sp == 1")
178
179        process.Kill()
180