xref: /llvm-project/lldb/test/API/python_api/value/change_values/TestChangeValueAPI.py (revision 05d7d6949c7cd3f1566d4c8394fa59160a7ffd05)
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.assertEquals(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.assertTrue(error.Success(), "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.assertTrue(error.Success(), "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.assertEquals(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        # Grab the stdout and make sure we changed the real values as well.
147        # This doesn't work for reproducers as the inferior doesn't run.
148        if not configuration.is_reproducer():
149            expected_value = "Val - 12345 Mine - 55, 98765, 55555555. Ptr - 66, 98765, 66666666"
150            stdout = process.GetSTDOUT(1000)
151            self.assertTrue(
152                expected_value in stdout,
153                "STDOUT showed changed values.")
154
155        # Finally, change the stack pointer to 0, and we should not make it to
156        # our end breakpoint.
157        frame0 = thread.GetFrameAtIndex(0)
158        self.assertTrue(frame0.IsValid(), "Second time: got a valid frame.")
159        sp_value = frame0.FindValue("sp", lldb.eValueTypeRegister)
160        self.assertTrue(sp_value.IsValid(), "Got a stack pointer value")
161        result = sp_value.SetValueFromCString("1")
162        self.assertTrue(result, "Setting sp returned true.")
163        actual_value = sp_value.GetValueAsUnsigned(error, 0)
164        self.assertTrue(error.Success(), "Got a changed value for sp")
165        self.assertEqual(
166            actual_value, 1,
167            "Got the right changed value for sp.")
168
169        # Boundary condition test the SBValue.CreateValueFromExpression() API.
170        # LLDB should not crash!
171        nosuchval = mine_value.CreateValueFromExpression(None, None)
172
173        process.Continue()
174
175        self.assertEquals(process.GetState(), lldb.eStateStopped)
176        thread = lldbutil.get_stopped_thread(
177            process, lldb.eStopReasonBreakpoint)
178        self.assertTrue(
179            thread is None,
180            "We should not have managed to hit our second breakpoint with sp == 1")
181
182        process.Kill()
183