199451b44SJordan Rupprecht""" 299451b44SJordan RupprechtTest some SBValue APIs. 399451b44SJordan Rupprecht""" 499451b44SJordan Rupprecht 599451b44SJordan Rupprechtimport lldb 6710276a2SWalter Erquinigofrom lldbsuite.test import lldbutil 799451b44SJordan Rupprechtfrom lldbsuite.test.decorators import * 899451b44SJordan Rupprechtfrom lldbsuite.test.lldbtest import * 999451b44SJordan Rupprecht 1099451b44SJordan Rupprecht 1199451b44SJordan Rupprechtclass ValueAPITestCase(TestBase): 1299451b44SJordan Rupprecht def setUp(self): 1399451b44SJordan Rupprecht # Call super's setUp(). 1499451b44SJordan Rupprecht TestBase.setUp(self) 1599451b44SJordan Rupprecht # We'll use the test method name as the exe_name. 1699451b44SJordan Rupprecht self.exe_name = self.testMethodName 1799451b44SJordan Rupprecht # Find the line number to of function 'c'. 182238dcc3SJonas Devlieghere self.line = line_number("main.c", "// Break at this line") 1999451b44SJordan Rupprecht 20ab05d913Stcwg @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24772") 2199451b44SJordan Rupprecht def test(self): 2299451b44SJordan Rupprecht """Exercise some SBValue APIs.""" 232238dcc3SJonas Devlieghere d = {"EXE": self.exe_name} 2499451b44SJordan Rupprecht self.build(dictionary=d) 2599451b44SJordan Rupprecht self.setTearDownCleanup(dictionary=d) 2699451b44SJordan Rupprecht exe = self.getBuildArtifact(self.exe_name) 2799451b44SJordan Rupprecht 2899451b44SJordan Rupprecht # Create a target by the debugger. 2999451b44SJordan Rupprecht target = self.dbg.CreateTarget(exe) 3099451b44SJordan Rupprecht self.assertTrue(target, VALID_TARGET) 3199451b44SJordan Rupprecht 3299451b44SJordan Rupprecht # Create the breakpoint inside function 'main'. 332238dcc3SJonas Devlieghere breakpoint = target.BreakpointCreateByLocation("main.c", self.line) 3499451b44SJordan Rupprecht self.assertTrue(breakpoint, VALID_BREAKPOINT) 3599451b44SJordan Rupprecht 3699451b44SJordan Rupprecht # Now launch the process, and do not stop at entry point. 372238dcc3SJonas Devlieghere process = target.LaunchSimple(None, None, self.get_process_working_directory()) 3899451b44SJordan Rupprecht self.assertTrue(process, PROCESS_IS_VALID) 3999451b44SJordan Rupprecht 4099451b44SJordan Rupprecht # Get Frame #0. 4147c4c6a7SDave Lee self.assertState(process.GetState(), lldb.eStateStopped) 422238dcc3SJonas Devlieghere thread = lldbutil.get_stopped_thread(process, lldb.eStopReasonBreakpoint) 4399451b44SJordan Rupprecht self.assertTrue( 4499451b44SJordan Rupprecht thread.IsValid(), 452238dcc3SJonas Devlieghere "There should be a thread stopped due to breakpoint condition", 462238dcc3SJonas Devlieghere ) 4799451b44SJordan Rupprecht frame0 = thread.GetFrameAtIndex(0) 4899451b44SJordan Rupprecht 4999451b44SJordan Rupprecht # Get global variable 'days_of_week'. 502238dcc3SJonas Devlieghere list = target.FindGlobalVariables("days_of_week", 1) 5199451b44SJordan Rupprecht days_of_week = list.GetValueAtIndex(0) 5299451b44SJordan Rupprecht self.assertTrue(days_of_week, VALID_VARIABLE) 5399451b44SJordan Rupprecht self.assertEqual(days_of_week.GetNumChildren(), 7, VALID_VARIABLE) 5499451b44SJordan Rupprecht self.DebugSBValue(days_of_week) 5599451b44SJordan Rupprecht 5699451b44SJordan Rupprecht # Use this to test the "child" and "children" accessors: 5799451b44SJordan Rupprecht children = days_of_week.children 5899451b44SJordan Rupprecht self.assertEqual(len(children), 7, VALID_VARIABLE) 5999451b44SJordan Rupprecht for i in range(0, len(children)): 6099451b44SJordan Rupprecht day = days_of_week.child[i] 6199451b44SJordan Rupprecht list_day = children[i] 6299451b44SJordan Rupprecht self.assertNotEqual(day, None) 6399451b44SJordan Rupprecht self.assertNotEqual(list_day, None) 6499451b44SJordan Rupprecht self.assertEqual(day.GetSummary(), list_day.GetSummary(), VALID_VARIABLE) 6599451b44SJordan Rupprecht 6699451b44SJordan Rupprecht # Spot check the actual value: 6799451b44SJordan Rupprecht first_day = days_of_week.child[1] 6899451b44SJordan Rupprecht self.assertEqual(first_day.GetSummary(), '"Monday"', VALID_VARIABLE) 6999451b44SJordan Rupprecht 7099451b44SJordan Rupprecht # Get global variable 'weekdays'. 712238dcc3SJonas Devlieghere list = target.FindGlobalVariables("weekdays", 1) 7299451b44SJordan Rupprecht weekdays = list.GetValueAtIndex(0) 7399451b44SJordan Rupprecht self.assertTrue(weekdays, VALID_VARIABLE) 74619e2e09SDave Lee self.assertEqual(weekdays.GetNumChildren(), 5, VALID_VARIABLE) 7599451b44SJordan Rupprecht self.DebugSBValue(weekdays) 7699451b44SJordan Rupprecht 7799451b44SJordan Rupprecht # Get global variable 'g_table'. 782238dcc3SJonas Devlieghere list = target.FindGlobalVariables("g_table", 1) 7999451b44SJordan Rupprecht g_table = list.GetValueAtIndex(0) 8099451b44SJordan Rupprecht self.assertTrue(g_table, VALID_VARIABLE) 81619e2e09SDave Lee self.assertEqual(g_table.GetNumChildren(), 2, VALID_VARIABLE) 8299451b44SJordan Rupprecht self.DebugSBValue(g_table) 8399451b44SJordan Rupprecht 8499451b44SJordan Rupprecht fmt = lldbutil.BasicFormatter() 8599451b44SJordan Rupprecht cvf = lldbutil.ChildVisitingFormatter(indent_child=2) 8699451b44SJordan Rupprecht rdf = lldbutil.RecursiveDecentFormatter(indent_child=2) 8799451b44SJordan Rupprecht if self.TraceOn(): 8899451b44SJordan Rupprecht print(fmt.format(days_of_week)) 8999451b44SJordan Rupprecht print(cvf.format(days_of_week)) 9099451b44SJordan Rupprecht print(cvf.format(weekdays)) 9199451b44SJordan Rupprecht print(rdf.format(g_table)) 9299451b44SJordan Rupprecht 9399451b44SJordan Rupprecht # Get variable 'my_int_ptr'. 942238dcc3SJonas Devlieghere value = frame0.FindVariable("my_int_ptr") 9599451b44SJordan Rupprecht self.assertTrue(value, VALID_VARIABLE) 9699451b44SJordan Rupprecht self.DebugSBValue(value) 9799451b44SJordan Rupprecht 9899451b44SJordan Rupprecht # Get what 'my_int_ptr' points to. 9999451b44SJordan Rupprecht pointed = value.GetChildAtIndex(0) 10099451b44SJordan Rupprecht self.assertTrue(pointed, VALID_VARIABLE) 10199451b44SJordan Rupprecht self.DebugSBValue(pointed) 10299451b44SJordan Rupprecht 10399451b44SJordan Rupprecht # While we are at it, verify that 'my_int_ptr' points to 'g_my_int'. 1042238dcc3SJonas Devlieghere symbol = target.ResolveLoadAddress(int(pointed.GetLocation(), 0)).GetSymbol() 10599451b44SJordan Rupprecht self.assertTrue(symbol) 1062238dcc3SJonas Devlieghere self.expect(symbol.GetName(), exe=False, startstr="g_my_int") 10799451b44SJordan Rupprecht 10899451b44SJordan Rupprecht # Get variable 'str_ptr'. 1092238dcc3SJonas Devlieghere value = frame0.FindVariable("str_ptr") 11099451b44SJordan Rupprecht self.assertTrue(value, VALID_VARIABLE) 11199451b44SJordan Rupprecht self.DebugSBValue(value) 11299451b44SJordan Rupprecht 11399451b44SJordan Rupprecht # SBValue::TypeIsPointerType() should return true. 11499451b44SJordan Rupprecht self.assertTrue(value.TypeIsPointerType()) 11599451b44SJordan Rupprecht 11699451b44SJordan Rupprecht # Verify the SBValue::GetByteSize() API is working correctly. 11799451b44SJordan Rupprecht arch = self.getArchitecture() 1182238dcc3SJonas Devlieghere if arch == "i386": 119619e2e09SDave Lee self.assertEqual(value.GetByteSize(), 4) 1202238dcc3SJonas Devlieghere elif arch == "x86_64": 121619e2e09SDave Lee self.assertEqual(value.GetByteSize(), 8) 12299451b44SJordan Rupprecht 12399451b44SJordan Rupprecht # Get child at index 5 => 'Friday'. 12499451b44SJordan Rupprecht child = value.GetChildAtIndex(5, lldb.eNoDynamicValues, True) 12599451b44SJordan Rupprecht self.assertTrue(child, VALID_VARIABLE) 12699451b44SJordan Rupprecht self.DebugSBValue(child) 12799451b44SJordan Rupprecht 1282238dcc3SJonas Devlieghere self.expect(child.GetSummary(), exe=False, substrs=["Friday"]) 12999451b44SJordan Rupprecht 13099451b44SJordan Rupprecht # Now try to get at the same variable using GetValueForExpressionPath(). 13199451b44SJordan Rupprecht # These two SBValue objects should have the same value. 1322238dcc3SJonas Devlieghere val2 = value.GetValueForExpressionPath("[5]") 13399451b44SJordan Rupprecht self.assertTrue(val2, VALID_VARIABLE) 13499451b44SJordan Rupprecht self.DebugSBValue(val2) 1352238dcc3SJonas Devlieghere self.assertTrue( 1362238dcc3SJonas Devlieghere child.GetValue() == val2.GetValue() 1372238dcc3SJonas Devlieghere and child.GetSummary() == val2.GetSummary() 1382238dcc3SJonas Devlieghere ) 13999451b44SJordan Rupprecht 1402238dcc3SJonas Devlieghere val_i = target.EvaluateExpression("i") 1412238dcc3SJonas Devlieghere val_s = target.EvaluateExpression("s") 1422238dcc3SJonas Devlieghere val_a = target.EvaluateExpression("a") 143*53fd724bSDave Lee self.assertTrue(val_s.member["a"].GetAddress().IsValid(), VALID_VARIABLE) 144*53fd724bSDave Lee self.assertTrue(val_s.member["a"].AddressOf(), VALID_VARIABLE) 1452238dcc3SJonas Devlieghere self.assertTrue(val_a.Cast(val_i.GetType()).AddressOf(), VALID_VARIABLE) 14699451b44SJordan Rupprecht 147f05e2fb0SJim Ingham # Test some other cases of the Cast API. We allow casts from one struct type 148f05e2fb0SJim Ingham # to another, which is a little weird, but we don't support casting from a 1493707c540Sjimingham # smaller type to a larger when the underlying data is not in the inferior, 1503707c540Sjimingham # since then we have no way to fetch the out-of-bounds values. 1513707c540Sjimingham # For an expression that references a variable, or a FindVariable result, 1523707c540Sjimingham # or an SBValue made from an address and a type, we can get back to the target, 1533707c540Sjimingham # so those will work. Make sure they do and get the right extra values as well. 1543707c540Sjimingham 1553707c540Sjimingham # We're casting everything to the type of "f", so get that first: 1563707c540Sjimingham f_var = frame0.FindVariable("f") 1573707c540Sjimingham self.assertSuccess(f_var.error, "Got f") 1583707c540Sjimingham bigger_type = f_var.GetType() 1593707c540Sjimingham 1603707c540Sjimingham # First try a value that we got from FindVariable 1613707c540Sjimingham container = frame0.FindVariable("my_container") 1623707c540Sjimingham self.assertSuccess(container.error, "Found my_container") 1633707c540Sjimingham fv_small = container.GetValueForExpressionPath(".data.small") 1643707c540Sjimingham self.assertSuccess(fv_small.error, "Found small in my_container") 1653707c540Sjimingham fv_cast = fv_small.Cast(bigger_type) 1663707c540Sjimingham self.assertSuccess(fv_cast.error, "Can cast up from FindVariable") 1673707c540Sjimingham child_checks = [ 1683707c540Sjimingham ValueCheck(name="a", value="33", type="int"), 1693707c540Sjimingham ValueCheck(name="b", value="44", type="int"), 1703707c540Sjimingham ValueCheck(name="c", value="55", type="int"), 1713707c540Sjimingham ] 1723707c540Sjimingham cast_check = ValueCheck(type=bigger_type.name, children=child_checks) 1733707c540Sjimingham 1743707c540Sjimingham # Now try one we made with expr. This one should fail, because expr 1753707c540Sjimingham # stores the "canonical value" in host memory, and doesn't know how 1763707c540Sjimingham # to augment that from the live address. 1773707c540Sjimingham expr_cont = frame0.EvaluateExpression("my_container") 1783707c540Sjimingham self.assertSuccess(expr_cont.error, "Got my_container by expr") 1793707c540Sjimingham expr_small = expr_cont.GetValueForExpressionPath(".data.small") 1803707c540Sjimingham self.assertSuccess(expr_small.error, "Got small by expr") 1813707c540Sjimingham expr_cast = expr_small.Cast(bigger_type) 1823707c540Sjimingham self.assertFailure(expr_cast.error, msg="Cannot cast expr result") 1833707c540Sjimingham 1843707c540Sjimingham # Now try one we made with CreateValueFromAddress. That will succeed 1853707c540Sjimingham # because this directly tracks the inferior memory. 1863707c540Sjimingham small_addr = fv_small.addr 1873707c540Sjimingham self.assertTrue(small_addr.IsValid()) 1883707c540Sjimingham small_type = fv_small.GetType() 1893707c540Sjimingham vfa_small = target.CreateValueFromAddress( 1903707c540Sjimingham "small_from_addr", small_addr, small_type 191ecbe78c1SJonas Devlieghere ) 1923707c540Sjimingham self.assertSuccess(vfa_small.error, "Made small from address") 1933707c540Sjimingham vfa_cast = vfa_small.Cast(bigger_type) 1943707c540Sjimingham self.assertSuccess(vfa_cast.error, "Made a cast from vfa_small") 1953707c540Sjimingham cast_check.check_value(self, vfa_cast, "Cast of ValueFromAddress succeeds") 1963707c540Sjimingham 1973707c540Sjimingham # Next try ValueObject created from data. They should fail as there's no 1983707c540Sjimingham # way to grow the data: 1993707c540Sjimingham data_small = target.CreateValueFromData( 2003707c540Sjimingham "small_from_data", fv_small.data, fv_small.type 2013707c540Sjimingham ) 2023707c540Sjimingham self.assertSuccess(data_small.error, "Made a valid object from data") 2033707c540Sjimingham data_cast = data_small.Cast(bigger_type) 2043707c540Sjimingham self.assertFailure(data_cast.error, msg="Cannot cast data backed SBValue") 2053707c540Sjimingham 2063707c540Sjimingham # Now check casting from a larger type to a smaller, we can always do this, 2073707c540Sjimingham # so just test one case: 2083707c540Sjimingham weird_cast = f_var.Cast(val_s.GetType()) 209ecbe78c1SJonas Devlieghere self.assertSuccess(weird_cast.GetError(), "Can cast from a larger to a smaller") 210ecbe78c1SJonas Devlieghere self.assertEqual( 211*53fd724bSDave Lee weird_cast.member["a"].GetValueAsSigned(0), 212ecbe78c1SJonas Devlieghere 33, 213ecbe78c1SJonas Devlieghere "Got the right value", 214ecbe78c1SJonas Devlieghere ) 215f05e2fb0SJim Ingham 21699451b44SJordan Rupprecht # Check that lldb.value implements truth testing. 2172238dcc3SJonas Devlieghere self.assertFalse(lldb.value(frame0.FindVariable("bogus"))) 2182238dcc3SJonas Devlieghere self.assertTrue(lldb.value(frame0.FindVariable("uinthex"))) 21999451b44SJordan Rupprecht 2202238dcc3SJonas Devlieghere self.assertEqual( 2212238dcc3SJonas Devlieghere int(lldb.value(frame0.FindVariable("uinthex"))), 2222238dcc3SJonas Devlieghere 3768803088, 2232238dcc3SJonas Devlieghere "uinthex == 3768803088", 2242238dcc3SJonas Devlieghere ) 2252238dcc3SJonas Devlieghere self.assertEqual( 2262238dcc3SJonas Devlieghere int(lldb.value(frame0.FindVariable("sinthex"))), 2272238dcc3SJonas Devlieghere -526164208, 2282238dcc3SJonas Devlieghere "sinthex == -526164208", 2292238dcc3SJonas Devlieghere ) 23099451b44SJordan Rupprecht 23199451b44SJordan Rupprecht # Check value_iter works correctly. 23299451b44SJordan Rupprecht for v in [ 2332238dcc3SJonas Devlieghere lldb.value(frame0.FindVariable("uinthex")), 2342238dcc3SJonas Devlieghere lldb.value(frame0.FindVariable("sinthex")), 23599451b44SJordan Rupprecht ]: 23699451b44SJordan Rupprecht self.assertTrue(v) 23799451b44SJordan Rupprecht 2380ed758b2SDave Lee self.assertEqual( 2392238dcc3SJonas Devlieghere frame0.FindVariable("uinthex").GetValueAsUnsigned(), 2402238dcc3SJonas Devlieghere 3768803088, 2412238dcc3SJonas Devlieghere "unsigned uinthex == 3768803088", 2422238dcc3SJonas Devlieghere ) 2430ed758b2SDave Lee self.assertEqual( 2442238dcc3SJonas Devlieghere frame0.FindVariable("sinthex").GetValueAsUnsigned(), 2452238dcc3SJonas Devlieghere 3768803088, 2462238dcc3SJonas Devlieghere "unsigned sinthex == 3768803088", 2472238dcc3SJonas Devlieghere ) 24899451b44SJordan Rupprecht 2491fb5c7a2SDave Lee self.assertEqual( 2502238dcc3SJonas Devlieghere frame0.FindVariable("uinthex").GetValueAsSigned(), 2512238dcc3SJonas Devlieghere -526164208, 2522238dcc3SJonas Devlieghere "signed uinthex == -526164208", 2532238dcc3SJonas Devlieghere ) 2541fb5c7a2SDave Lee self.assertEqual( 2552238dcc3SJonas Devlieghere frame0.FindVariable("sinthex").GetValueAsSigned(), 2562238dcc3SJonas Devlieghere -526164208, 2572238dcc3SJonas Devlieghere "signed sinthex == -526164208", 2582238dcc3SJonas Devlieghere ) 259710276a2SWalter Erquinigo 260710276a2SWalter Erquinigo # Check that hex value printing works as expected. 261710276a2SWalter Erquinigo self.assertEqual( 262710276a2SWalter Erquinigo frame0.FindVariable("fixed_int_ptr").GetValue(), 26395686016SDavid Spickett "0x000000aa" if target.addr_size == 4 else "0x00000000000000aa", 264710276a2SWalter Erquinigo ) 265096c530aSJonas Devlieghere self.runCmd( 266096c530aSJonas Devlieghere "settings set target.show-hex-variable-values-with-leading-zeroes false" 267096c530aSJonas Devlieghere ) 268710276a2SWalter Erquinigo self.assertEqual( 269710276a2SWalter Erquinigo frame0.FindVariable("another_fixed_int_ptr").GetValue(), 270710276a2SWalter Erquinigo "0xaa", 271710276a2SWalter Erquinigo ) 272710276a2SWalter Erquinigo self.assertEqual( 273710276a2SWalter Erquinigo frame0.FindVariable("a_null_int_ptr").GetValue(), 274710276a2SWalter Erquinigo "0x0", 275710276a2SWalter Erquinigo ) 276