199451b44SJordan Rupprecht""" 299451b44SJordan RupprechtTest display and Python APIs on file and class static variables. 399451b44SJordan Rupprecht""" 499451b44SJordan Rupprecht 599451b44SJordan Rupprecht 699451b44SJordan Rupprecht 799451b44SJordan Rupprechtimport lldb 899451b44SJordan Rupprechtfrom lldbsuite.test.decorators import * 999451b44SJordan Rupprechtfrom lldbsuite.test.lldbtest import * 1099451b44SJordan Rupprechtfrom lldbsuite.test import lldbutil 1199451b44SJordan Rupprecht 1299451b44SJordan Rupprecht 1399451b44SJordan Rupprechtclass StaticVariableTestCase(TestBase): 1499451b44SJordan Rupprecht 1599451b44SJordan Rupprecht mydir = TestBase.compute_mydir(__file__) 1699451b44SJordan Rupprecht 1799451b44SJordan Rupprecht def setUp(self): 1899451b44SJordan Rupprecht # Call super's setUp(). 1999451b44SJordan Rupprecht TestBase.setUp(self) 2099451b44SJordan Rupprecht # Find the line number to break at. 2199451b44SJordan Rupprecht self.line = line_number('main.cpp', '// Set break point at this line.') 2299451b44SJordan Rupprecht 2399451b44SJordan Rupprecht def test_with_run_command(self): 2499451b44SJordan Rupprecht """Test that file and class static variables display correctly.""" 2599451b44SJordan Rupprecht self.build() 2699451b44SJordan Rupprecht self.runCmd("file " + self.getBuildArtifact("a.out"), CURRENT_EXECUTABLE_SET) 2799451b44SJordan Rupprecht 2899451b44SJordan Rupprecht lldbutil.run_break_set_by_file_and_line( 2999451b44SJordan Rupprecht self, "main.cpp", self.line, num_expected_locations=1, loc_exact=True) 3099451b44SJordan Rupprecht 3199451b44SJordan Rupprecht self.runCmd("run", RUN_SUCCEEDED) 3299451b44SJordan Rupprecht 3399451b44SJordan Rupprecht # The stop reason of the thread should be breakpoint. 3499451b44SJordan Rupprecht self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, 3599451b44SJordan Rupprecht substrs=['stopped', 3699451b44SJordan Rupprecht 'stop reason = breakpoint']) 3799451b44SJordan Rupprecht 3899451b44SJordan Rupprecht # Global variables are no longer displayed with the "frame variable" 3999451b44SJordan Rupprecht # command. 4099451b44SJordan Rupprecht self.expect( 4199451b44SJordan Rupprecht 'target variable A::g_points', 4299451b44SJordan Rupprecht VARIABLES_DISPLAYED_CORRECTLY, 4399451b44SJordan Rupprecht patterns=['\(PointType \[[1-9]*\]\) A::g_points = {']) 4499451b44SJordan Rupprecht self.expect('target variable g_points', VARIABLES_DISPLAYED_CORRECTLY, 4599451b44SJordan Rupprecht substrs=['(PointType [2]) g_points']) 4699451b44SJordan Rupprecht 4799451b44SJordan Rupprecht # On Mac OS X, gcc 4.2 emits the wrong debug info for A::g_points. 4899451b44SJordan Rupprecht # A::g_points is an array of two elements. 4999451b44SJordan Rupprecht if self.platformIsDarwin() or self.getPlatform() == "linux": 5099451b44SJordan Rupprecht self.expect( 5199451b44SJordan Rupprecht "target variable A::g_points[1].x", 5299451b44SJordan Rupprecht VARIABLES_DISPLAYED_CORRECTLY, 5399451b44SJordan Rupprecht startstr="(int) A::g_points[1].x = 11") 5499451b44SJordan Rupprecht 5599451b44SJordan Rupprecht @expectedFailureAll( 5699451b44SJordan Rupprecht compiler=["gcc"], 5799451b44SJordan Rupprecht bugnumber="Compiler emits incomplete debug info") 5899451b44SJordan Rupprecht @expectedFailureAll( 5999451b44SJordan Rupprecht compiler=["clang"], 6099451b44SJordan Rupprecht compiler_version=["<", "3.9"], 6199451b44SJordan Rupprecht bugnumber='llvm.org/pr20550') 6299451b44SJordan Rupprecht def test_with_run_command_complete(self): 6399451b44SJordan Rupprecht """ 6499451b44SJordan Rupprecht Test that file and class static variables display correctly with 6599451b44SJordan Rupprecht complete debug information. 6699451b44SJordan Rupprecht """ 6799451b44SJordan Rupprecht self.build() 6899451b44SJordan Rupprecht target = self.dbg.CreateTarget(self.getBuildArtifact("a.out")) 6999451b44SJordan Rupprecht self.assertTrue(target, VALID_TARGET) 7099451b44SJordan Rupprecht 7199451b44SJordan Rupprecht # Global variables are no longer displayed with the "frame variable" 7299451b44SJordan Rupprecht # command. 7399451b44SJordan Rupprecht self.expect( 7499451b44SJordan Rupprecht 'target variable A::g_points', 7599451b44SJordan Rupprecht VARIABLES_DISPLAYED_CORRECTLY, 7699451b44SJordan Rupprecht patterns=[ 7799451b44SJordan Rupprecht '\(PointType \[[1-9]*\]\) A::g_points = {', '(x = 1, y = 2)', 7899451b44SJordan Rupprecht '(x = 11, y = 22)' 7999451b44SJordan Rupprecht ]) 8099451b44SJordan Rupprecht 8199451b44SJordan Rupprecht # Ensure that we take the context into account and only print 8299451b44SJordan Rupprecht # A::g_points. 8399451b44SJordan Rupprecht self.expect( 8499451b44SJordan Rupprecht 'target variable A::g_points', 8599451b44SJordan Rupprecht VARIABLES_DISPLAYED_CORRECTLY, 8699451b44SJordan Rupprecht matching=False, 8799451b44SJordan Rupprecht patterns=['(x = 3, y = 4)', '(x = 33, y = 44)']) 8899451b44SJordan Rupprecht 8999451b44SJordan Rupprecht # Finally, ensure that we print both points when not specifying a 9099451b44SJordan Rupprecht # context. 9199451b44SJordan Rupprecht self.expect( 9299451b44SJordan Rupprecht 'target variable g_points', 9399451b44SJordan Rupprecht VARIABLES_DISPLAYED_CORRECTLY, 9499451b44SJordan Rupprecht substrs=[ 9599451b44SJordan Rupprecht '(PointType [2]) g_points', '(x = 1, y = 2)', 9699451b44SJordan Rupprecht '(x = 11, y = 22)', '(x = 3, y = 4)', '(x = 33, y = 44)' 9799451b44SJordan Rupprecht ]) 9899451b44SJordan Rupprecht 9999451b44SJordan Rupprecht @expectedFailureAll( 10099451b44SJordan Rupprecht compiler=["gcc"], 10199451b44SJordan Rupprecht bugnumber="Compiler emits incomplete debug info") 10299451b44SJordan Rupprecht @expectedFailureAll( 10399451b44SJordan Rupprecht compiler=["clang"], 10499451b44SJordan Rupprecht compiler_version=["<", "3.9"], 10599451b44SJordan Rupprecht bugnumber='llvm.org/pr20550') 10699451b44SJordan Rupprecht @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24764") 10799451b44SJordan Rupprecht @add_test_categories(['pyapi']) 10899451b44SJordan Rupprecht def test_with_python_api(self): 10999451b44SJordan Rupprecht """Test Python APIs on file and class static variables.""" 11099451b44SJordan Rupprecht self.build() 11199451b44SJordan Rupprecht exe = self.getBuildArtifact("a.out") 11299451b44SJordan Rupprecht 11399451b44SJordan Rupprecht target = self.dbg.CreateTarget(exe) 11499451b44SJordan Rupprecht self.assertTrue(target, VALID_TARGET) 11599451b44SJordan Rupprecht 11699451b44SJordan Rupprecht breakpoint = target.BreakpointCreateByLocation("main.cpp", self.line) 11799451b44SJordan Rupprecht self.assertTrue(breakpoint, VALID_BREAKPOINT) 11899451b44SJordan Rupprecht 11999451b44SJordan Rupprecht # Now launch the process, and do not stop at entry point. 12099451b44SJordan Rupprecht process = target.LaunchSimple( 12199451b44SJordan Rupprecht None, None, self.get_process_working_directory()) 12299451b44SJordan Rupprecht self.assertTrue(process, PROCESS_IS_VALID) 12399451b44SJordan Rupprecht 12499451b44SJordan Rupprecht # The stop reason of the thread should be breakpoint. 12599451b44SJordan Rupprecht thread = lldbutil.get_stopped_thread( 12699451b44SJordan Rupprecht process, lldb.eStopReasonBreakpoint) 12799451b44SJordan Rupprecht self.assertIsNotNone(thread) 12899451b44SJordan Rupprecht 12999451b44SJordan Rupprecht # Get the SBValue of 'A::g_points' and 'g_points'. 13099451b44SJordan Rupprecht frame = thread.GetFrameAtIndex(0) 13199451b44SJordan Rupprecht 13299451b44SJordan Rupprecht # arguments => False 13399451b44SJordan Rupprecht # locals => False 13499451b44SJordan Rupprecht # statics => True 13599451b44SJordan Rupprecht # in_scope_only => False 13699451b44SJordan Rupprecht valList = frame.GetVariables(False, False, True, False) 13799451b44SJordan Rupprecht 13899451b44SJordan Rupprecht for val in valList: 13999451b44SJordan Rupprecht self.DebugSBValue(val) 14099451b44SJordan Rupprecht name = val.GetName() 14199451b44SJordan Rupprecht self.assertTrue(name in ['g_points', 'A::g_points']) 14299451b44SJordan Rupprecht if name == 'g_points': 14399451b44SJordan Rupprecht self.assertTrue( 14499451b44SJordan Rupprecht val.GetValueType() == lldb.eValueTypeVariableStatic) 14599451b44SJordan Rupprecht self.assertEqual(val.GetNumChildren(), 2) 14699451b44SJordan Rupprecht elif name == 'A::g_points': 14799451b44SJordan Rupprecht self.assertTrue( 14899451b44SJordan Rupprecht val.GetValueType() == lldb.eValueTypeVariableGlobal) 14999451b44SJordan Rupprecht self.assertEqual(val.GetNumChildren(), 2) 15099451b44SJordan Rupprecht child1 = val.GetChildAtIndex(1) 15199451b44SJordan Rupprecht self.DebugSBValue(child1) 15299451b44SJordan Rupprecht child1_x = child1.GetChildAtIndex(0) 15399451b44SJordan Rupprecht self.DebugSBValue(child1_x) 15499451b44SJordan Rupprecht self.assertTrue(child1_x.GetTypeName() == 'int' and 15599451b44SJordan Rupprecht child1_x.GetValue() == '11') 15699451b44SJordan Rupprecht 15799451b44SJordan Rupprecht # SBFrame.FindValue() should also work. 15899451b44SJordan Rupprecht val = frame.FindValue("A::g_points", lldb.eValueTypeVariableGlobal) 15999451b44SJordan Rupprecht self.DebugSBValue(val) 160*619e2e09SDave Lee self.assertEqual(val.GetName(), 'A::g_points') 16199451b44SJordan Rupprecht 16299451b44SJordan Rupprecht # Also exercise the "parameter" and "local" scopes while we are at it. 16399451b44SJordan Rupprecht val = frame.FindValue("argc", lldb.eValueTypeVariableArgument) 16499451b44SJordan Rupprecht self.DebugSBValue(val) 165*619e2e09SDave Lee self.assertEqual(val.GetName(), 'argc') 16699451b44SJordan Rupprecht 16799451b44SJordan Rupprecht val = frame.FindValue("argv", lldb.eValueTypeVariableArgument) 16899451b44SJordan Rupprecht self.DebugSBValue(val) 169*619e2e09SDave Lee self.assertEqual(val.GetName(), 'argv') 17099451b44SJordan Rupprecht 17199451b44SJordan Rupprecht val = frame.FindValue("hello_world", lldb.eValueTypeVariableLocal) 17299451b44SJordan Rupprecht self.DebugSBValue(val) 173*619e2e09SDave Lee self.assertEqual(val.GetName(), 'hello_world') 174