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