1""" 2Test display and Python APIs on file and class static variables. 3""" 4 5import os, time 6import unittest2 7import lldb 8from lldbtest import * 9import lldbutil 10 11class StaticVariableTestCase(TestBase): 12 13 mydir = os.path.join("lang", "cpp", "class_static") 14 failing_compilers = ['clang', 'gcc'] 15 16 @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin") 17 @dsym_test 18 def test_with_dsym_and_run_command(self): 19 """Test that file and class static variables display correctly.""" 20 self.buildDsym() 21 self.static_variable_commands() 22 23 @expectedFailureLinux('llvm.org/pr15261', failing_compilers) # lldb on Linux does not display the size of (class or file)static arrays 24 @dwarf_test 25 def test_with_dwarf_and_run_command(self): 26 """Test that file and class static variables display correctly.""" 27 self.buildDwarf() 28 self.static_variable_commands() 29 30 @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin") 31 @expectedFailureClang(9980907) 32 @expectedFailureGcc(9980907) 33 @python_api_test 34 @dsym_test 35 def test_with_dsym_and_python_api(self): 36 """Test Python APIs on file and class static variables.""" 37 self.buildDsym() 38 self.static_variable_python() 39 40 @expectedFailureClang(9980907) 41 @python_api_test 42 @dwarf_test 43 def test_with_dwarf_and_python_api(self): 44 """Test Python APIs on file and class static variables.""" 45 self.buildDwarf() 46 self.static_variable_python() 47 48 def setUp(self): 49 # Call super's setUp(). 50 TestBase.setUp(self) 51 # Find the line number to break at. 52 self.line = line_number('main.cpp', '// Set break point at this line.') 53 54 def static_variable_commands(self): 55 """Test that that file and class static variables display correctly.""" 56 self.runCmd("file a.out", CURRENT_EXECUTABLE_SET) 57 58 lldbutil.run_break_set_by_file_and_line (self, "main.cpp", self.line, num_expected_locations=1, loc_exact=True) 59 60 self.runCmd("run", RUN_SUCCEEDED) 61 62 # The stop reason of the thread should be breakpoint. 63 self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, 64 substrs = ['stopped', 65 'stop reason = breakpoint']) 66 67 # global variables are no longer displayed with the "frame variable" command. 68 self.expect('target variable A::g_points', VARIABLES_DISPLAYED_CORRECTLY, 69 substrs = ['(PointType [2]) A::g_points']) 70 self.expect('target variable g_points', VARIABLES_DISPLAYED_CORRECTLY, 71 substrs = ['(PointType [2]) g_points']) 72 73 # On Mac OS X, gcc 4.2 emits the wrong debug info for A::g_points. 74 # A::g_points is an array of two elements. 75 if sys.platform.startswith("darwin") and self.getCompiler() in ['clang', 'llvm-gcc']: 76 self.expect("target variable A::g_points[1].x", VARIABLES_DISPLAYED_CORRECTLY, 77 startstr = "(int) A::g_points[1].x = 11") 78 79 def static_variable_python(self): 80 """Test Python APIs on file and class static variables.""" 81 exe = os.path.join(os.getcwd(), "a.out") 82 83 target = self.dbg.CreateTarget(exe) 84 self.assertTrue(target, VALID_TARGET) 85 86 breakpoint = target.BreakpointCreateByLocation("main.cpp", self.line) 87 self.assertTrue(breakpoint, VALID_BREAKPOINT) 88 89 # Now launch the process, and do not stop at entry point. 90 process = target.LaunchSimple(None, None, os.getcwd()) 91 self.assertTrue(process, PROCESS_IS_VALID) 92 93 # The stop reason of the thread should be breakpoint. 94 thread = process.GetThreadAtIndex(0) 95 if thread.GetStopReason() != lldb.eStopReasonBreakpoint: 96 from lldbutil import stop_reason_to_str 97 self.fail(STOPPED_DUE_TO_BREAKPOINT_WITH_STOP_REASON_AS % 98 stop_reason_to_str(thread.GetStopReason())) 99 100 # Get the SBValue of 'A::g_points' and 'g_points'. 101 frame = thread.GetFrameAtIndex(0) 102 103 # arguments => False 104 # locals => False 105 # statics => True 106 # in_scope_only => False 107 valList = frame.GetVariables(False, False, True, False) 108 109 for val in valList: 110 self.DebugSBValue(val) 111 name = val.GetName() 112 self.assertTrue(name in ['g_points', 'A::g_points']) 113 if name == 'g_points': 114 self.assertTrue(val.GetValueType() == lldb.eValueTypeVariableStatic) 115 self.assertTrue(val.GetNumChildren() == 2) 116 elif name == 'A::g_points' and self.getCompiler() in ['clang', 'llvm-gcc']: 117 # On Mac OS X, gcc 4.2 emits the wrong debug info for A::g_points. 118 self.assertTrue(val.GetValueType() == lldb.eValueTypeVariableGlobal) 119 self.assertTrue(val.GetNumChildren() == 2) 120 child1 = val.GetChildAtIndex(1) 121 self.DebugSBValue(child1) 122 child1_x = child1.GetChildAtIndex(0) 123 self.DebugSBValue(child1_x) 124 self.assertTrue(child1_x.GetTypeName() == 'int' and 125 child1_x.GetValue() == '11') 126 127 # SBFrame.FindValue() should also work. 128 val = frame.FindValue("A::g_points", lldb.eValueTypeVariableGlobal) 129 self.DebugSBValue(val) 130 self.assertTrue(val.GetName() == 'A::g_points') 131 132 # Also exercise the "parameter" and "local" scopes while we are at it. 133 val = frame.FindValue("argc", lldb.eValueTypeVariableArgument) 134 self.DebugSBValue(val) 135 self.assertTrue(val.GetName() == 'argc') 136 137 val = frame.FindValue("argv", lldb.eValueTypeVariableArgument) 138 self.DebugSBValue(val) 139 self.assertTrue(val.GetName() == 'argv') 140 141 val = frame.FindValue("hello_world", lldb.eValueTypeVariableLocal) 142 self.DebugSBValue(val) 143 self.assertTrue(val.GetName() == 'hello_world') 144 145 146if __name__ == '__main__': 147 import atexit 148 lldb.SBDebugger.Initialize() 149 atexit.register(lambda: lldb.SBDebugger.Terminate()) 150 unittest2.main() 151