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