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