1*99451b44SJordan Rupprecht""" 2*99451b44SJordan RupprechtTest display and Python APIs on file and class static variables. 3*99451b44SJordan Rupprecht""" 4*99451b44SJordan Rupprecht 5*99451b44SJordan Rupprecht 6*99451b44SJordan Rupprecht 7*99451b44SJordan Rupprechtimport lldb 8*99451b44SJordan Rupprechtfrom lldbsuite.test.decorators import * 9*99451b44SJordan Rupprechtfrom lldbsuite.test.lldbtest import * 10*99451b44SJordan Rupprechtfrom lldbsuite.test import lldbutil 11*99451b44SJordan Rupprecht 12*99451b44SJordan Rupprecht 13*99451b44SJordan Rupprechtclass StaticVariableTestCase(TestBase): 14*99451b44SJordan Rupprecht 15*99451b44SJordan Rupprecht mydir = TestBase.compute_mydir(__file__) 16*99451b44SJordan Rupprecht 17*99451b44SJordan Rupprecht def setUp(self): 18*99451b44SJordan Rupprecht # Call super's setUp(). 19*99451b44SJordan Rupprecht TestBase.setUp(self) 20*99451b44SJordan Rupprecht # Find the line number to break at. 21*99451b44SJordan Rupprecht self.line = line_number('main.cpp', '// Set break point at this line.') 22*99451b44SJordan Rupprecht 23*99451b44SJordan Rupprecht def test_with_run_command(self): 24*99451b44SJordan Rupprecht """Test that file and class static variables display correctly.""" 25*99451b44SJordan Rupprecht self.build() 26*99451b44SJordan Rupprecht self.runCmd("file " + self.getBuildArtifact("a.out"), CURRENT_EXECUTABLE_SET) 27*99451b44SJordan Rupprecht 28*99451b44SJordan Rupprecht lldbutil.run_break_set_by_file_and_line( 29*99451b44SJordan Rupprecht self, "main.cpp", self.line, num_expected_locations=1, loc_exact=True) 30*99451b44SJordan Rupprecht 31*99451b44SJordan Rupprecht self.runCmd("run", RUN_SUCCEEDED) 32*99451b44SJordan Rupprecht 33*99451b44SJordan Rupprecht # The stop reason of the thread should be breakpoint. 34*99451b44SJordan Rupprecht self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, 35*99451b44SJordan Rupprecht substrs=['stopped', 36*99451b44SJordan Rupprecht 'stop reason = breakpoint']) 37*99451b44SJordan Rupprecht 38*99451b44SJordan Rupprecht # Global variables are no longer displayed with the "frame variable" 39*99451b44SJordan Rupprecht # command. 40*99451b44SJordan Rupprecht self.expect( 41*99451b44SJordan Rupprecht 'target variable A::g_points', 42*99451b44SJordan Rupprecht VARIABLES_DISPLAYED_CORRECTLY, 43*99451b44SJordan Rupprecht patterns=['\(PointType \[[1-9]*\]\) A::g_points = {']) 44*99451b44SJordan Rupprecht self.expect('target variable g_points', VARIABLES_DISPLAYED_CORRECTLY, 45*99451b44SJordan Rupprecht substrs=['(PointType [2]) g_points']) 46*99451b44SJordan Rupprecht 47*99451b44SJordan Rupprecht # On Mac OS X, gcc 4.2 emits the wrong debug info for A::g_points. 48*99451b44SJordan Rupprecht # A::g_points is an array of two elements. 49*99451b44SJordan Rupprecht if self.platformIsDarwin() or self.getPlatform() == "linux": 50*99451b44SJordan Rupprecht self.expect( 51*99451b44SJordan Rupprecht "target variable A::g_points[1].x", 52*99451b44SJordan Rupprecht VARIABLES_DISPLAYED_CORRECTLY, 53*99451b44SJordan Rupprecht startstr="(int) A::g_points[1].x = 11") 54*99451b44SJordan Rupprecht 55*99451b44SJordan Rupprecht @expectedFailureAll( 56*99451b44SJordan Rupprecht compiler=["gcc"], 57*99451b44SJordan Rupprecht bugnumber="Compiler emits incomplete debug info") 58*99451b44SJordan Rupprecht @expectedFailureAll( 59*99451b44SJordan Rupprecht compiler=["clang"], 60*99451b44SJordan Rupprecht compiler_version=["<", "3.9"], 61*99451b44SJordan Rupprecht bugnumber='llvm.org/pr20550') 62*99451b44SJordan Rupprecht def test_with_run_command_complete(self): 63*99451b44SJordan Rupprecht """ 64*99451b44SJordan Rupprecht Test that file and class static variables display correctly with 65*99451b44SJordan Rupprecht complete debug information. 66*99451b44SJordan Rupprecht """ 67*99451b44SJordan Rupprecht self.build() 68*99451b44SJordan Rupprecht target = self.dbg.CreateTarget(self.getBuildArtifact("a.out")) 69*99451b44SJordan Rupprecht self.assertTrue(target, VALID_TARGET) 70*99451b44SJordan Rupprecht 71*99451b44SJordan Rupprecht # Global variables are no longer displayed with the "frame variable" 72*99451b44SJordan Rupprecht # command. 73*99451b44SJordan Rupprecht self.expect( 74*99451b44SJordan Rupprecht 'target variable A::g_points', 75*99451b44SJordan Rupprecht VARIABLES_DISPLAYED_CORRECTLY, 76*99451b44SJordan Rupprecht patterns=[ 77*99451b44SJordan Rupprecht '\(PointType \[[1-9]*\]\) A::g_points = {', '(x = 1, y = 2)', 78*99451b44SJordan Rupprecht '(x = 11, y = 22)' 79*99451b44SJordan Rupprecht ]) 80*99451b44SJordan Rupprecht 81*99451b44SJordan Rupprecht # Ensure that we take the context into account and only print 82*99451b44SJordan Rupprecht # A::g_points. 83*99451b44SJordan Rupprecht self.expect( 84*99451b44SJordan Rupprecht 'target variable A::g_points', 85*99451b44SJordan Rupprecht VARIABLES_DISPLAYED_CORRECTLY, 86*99451b44SJordan Rupprecht matching=False, 87*99451b44SJordan Rupprecht patterns=['(x = 3, y = 4)', '(x = 33, y = 44)']) 88*99451b44SJordan Rupprecht 89*99451b44SJordan Rupprecht # Finally, ensure that we print both points when not specifying a 90*99451b44SJordan Rupprecht # context. 91*99451b44SJordan Rupprecht self.expect( 92*99451b44SJordan Rupprecht 'target variable g_points', 93*99451b44SJordan Rupprecht VARIABLES_DISPLAYED_CORRECTLY, 94*99451b44SJordan Rupprecht substrs=[ 95*99451b44SJordan Rupprecht '(PointType [2]) g_points', '(x = 1, y = 2)', 96*99451b44SJordan Rupprecht '(x = 11, y = 22)', '(x = 3, y = 4)', '(x = 33, y = 44)' 97*99451b44SJordan Rupprecht ]) 98*99451b44SJordan Rupprecht 99*99451b44SJordan Rupprecht @expectedFailureAll( 100*99451b44SJordan Rupprecht compiler=["gcc"], 101*99451b44SJordan Rupprecht bugnumber="Compiler emits incomplete debug info") 102*99451b44SJordan Rupprecht @expectedFailureAll( 103*99451b44SJordan Rupprecht compiler=["clang"], 104*99451b44SJordan Rupprecht compiler_version=["<", "3.9"], 105*99451b44SJordan Rupprecht bugnumber='llvm.org/pr20550') 106*99451b44SJordan Rupprecht @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24764") 107*99451b44SJordan Rupprecht @add_test_categories(['pyapi']) 108*99451b44SJordan Rupprecht def test_with_python_api(self): 109*99451b44SJordan Rupprecht """Test Python APIs on file and class static variables.""" 110*99451b44SJordan Rupprecht self.build() 111*99451b44SJordan Rupprecht exe = self.getBuildArtifact("a.out") 112*99451b44SJordan Rupprecht 113*99451b44SJordan Rupprecht target = self.dbg.CreateTarget(exe) 114*99451b44SJordan Rupprecht self.assertTrue(target, VALID_TARGET) 115*99451b44SJordan Rupprecht 116*99451b44SJordan Rupprecht breakpoint = target.BreakpointCreateByLocation("main.cpp", self.line) 117*99451b44SJordan Rupprecht self.assertTrue(breakpoint, VALID_BREAKPOINT) 118*99451b44SJordan Rupprecht 119*99451b44SJordan Rupprecht # Now launch the process, and do not stop at entry point. 120*99451b44SJordan Rupprecht process = target.LaunchSimple( 121*99451b44SJordan Rupprecht None, None, self.get_process_working_directory()) 122*99451b44SJordan Rupprecht self.assertTrue(process, PROCESS_IS_VALID) 123*99451b44SJordan Rupprecht 124*99451b44SJordan Rupprecht # The stop reason of the thread should be breakpoint. 125*99451b44SJordan Rupprecht thread = lldbutil.get_stopped_thread( 126*99451b44SJordan Rupprecht process, lldb.eStopReasonBreakpoint) 127*99451b44SJordan Rupprecht self.assertIsNotNone(thread) 128*99451b44SJordan Rupprecht 129*99451b44SJordan Rupprecht # Get the SBValue of 'A::g_points' and 'g_points'. 130*99451b44SJordan Rupprecht frame = thread.GetFrameAtIndex(0) 131*99451b44SJordan Rupprecht 132*99451b44SJordan Rupprecht # arguments => False 133*99451b44SJordan Rupprecht # locals => False 134*99451b44SJordan Rupprecht # statics => True 135*99451b44SJordan Rupprecht # in_scope_only => False 136*99451b44SJordan Rupprecht valList = frame.GetVariables(False, False, True, False) 137*99451b44SJordan Rupprecht 138*99451b44SJordan Rupprecht for val in valList: 139*99451b44SJordan Rupprecht self.DebugSBValue(val) 140*99451b44SJordan Rupprecht name = val.GetName() 141*99451b44SJordan Rupprecht self.assertTrue(name in ['g_points', 'A::g_points']) 142*99451b44SJordan Rupprecht if name == 'g_points': 143*99451b44SJordan Rupprecht self.assertTrue( 144*99451b44SJordan Rupprecht val.GetValueType() == lldb.eValueTypeVariableStatic) 145*99451b44SJordan Rupprecht self.assertEqual(val.GetNumChildren(), 2) 146*99451b44SJordan Rupprecht elif name == 'A::g_points': 147*99451b44SJordan Rupprecht self.assertTrue( 148*99451b44SJordan Rupprecht val.GetValueType() == lldb.eValueTypeVariableGlobal) 149*99451b44SJordan Rupprecht self.assertEqual(val.GetNumChildren(), 2) 150*99451b44SJordan Rupprecht child1 = val.GetChildAtIndex(1) 151*99451b44SJordan Rupprecht self.DebugSBValue(child1) 152*99451b44SJordan Rupprecht child1_x = child1.GetChildAtIndex(0) 153*99451b44SJordan Rupprecht self.DebugSBValue(child1_x) 154*99451b44SJordan Rupprecht self.assertTrue(child1_x.GetTypeName() == 'int' and 155*99451b44SJordan Rupprecht child1_x.GetValue() == '11') 156*99451b44SJordan Rupprecht 157*99451b44SJordan Rupprecht # SBFrame.FindValue() should also work. 158*99451b44SJordan Rupprecht val = frame.FindValue("A::g_points", lldb.eValueTypeVariableGlobal) 159*99451b44SJordan Rupprecht self.DebugSBValue(val) 160*99451b44SJordan Rupprecht self.assertTrue(val.GetName() == 'A::g_points') 161*99451b44SJordan Rupprecht 162*99451b44SJordan Rupprecht # Also exercise the "parameter" and "local" scopes while we are at it. 163*99451b44SJordan Rupprecht val = frame.FindValue("argc", lldb.eValueTypeVariableArgument) 164*99451b44SJordan Rupprecht self.DebugSBValue(val) 165*99451b44SJordan Rupprecht self.assertTrue(val.GetName() == 'argc') 166*99451b44SJordan Rupprecht 167*99451b44SJordan Rupprecht val = frame.FindValue("argv", lldb.eValueTypeVariableArgument) 168*99451b44SJordan Rupprecht self.DebugSBValue(val) 169*99451b44SJordan Rupprecht self.assertTrue(val.GetName() == 'argv') 170*99451b44SJordan Rupprecht 171*99451b44SJordan Rupprecht val = frame.FindValue("hello_world", lldb.eValueTypeVariableLocal) 172*99451b44SJordan Rupprecht self.DebugSBValue(val) 173*99451b44SJordan Rupprecht self.assertTrue(val.GetName() == 'hello_world') 174