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