TestClassTypes.py revision b794017ee4b085b28249af1511b3bdcaef8924ce
1"""Test breakpoint on a class constructor; and variable list the this object.""" 2 3import os, time 4import unittest2 5import lldb 6import lldbutil 7from lldbtest import * 8 9class ClassTypesTestCase(TestBase): 10 11 mydir = os.path.join("lang", "cpp", "class_types") 12 13 @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin") 14 def test_with_dsym_and_run_command(self): 15 """Test 'frame variable this' when stopped on a class constructor.""" 16 self.buildDsym() 17 self.class_types() 18 19 @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin") 20 @python_api_test 21 def test_with_dsym_and_python_api(self): 22 """Use Python APIs to create a breakpoint by (filespec, line).""" 23 self.buildDsym() 24 self.breakpoint_creation_by_filespec_python() 25 26 # rdar://problem/8378863 27 # "frame variable this" returns 28 # error: unable to find any variables named 'this' 29 def test_with_dwarf_and_run_command(self): 30 """Test 'frame variable this' when stopped on a class constructor.""" 31 self.buildDwarf() 32 self.class_types() 33 34 @python_api_test 35 def test_with_dwarf_and_python_api(self): 36 """Use Python APIs to create a breakpoint by (filespec, line).""" 37 self.buildDwarf() 38 self.breakpoint_creation_by_filespec_python() 39 40 @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin") 41 # rdar://problem/8557478 42 # test/class_types test failures: runCmd: expr this->m_c_int 43 def test_with_dsym_and_expr_parser(self): 44 """Test 'frame variable this' and 'expr this' when stopped inside a constructor.""" 45 self.buildDsym() 46 self.class_types_expr_parser() 47 48 # rdar://problem/8557478 49 # test/class_types test failures: runCmd: expr this->m_c_int 50 def test_with_dwarf_and_expr_parser(self): 51 """Test 'frame variable this' and 'expr this' when stopped inside a constructor.""" 52 self.buildDwarf() 53 self.class_types_expr_parser() 54 55 def setUp(self): 56 # Call super's setUp(). 57 TestBase.setUp(self) 58 # Find the line number to break for main.cpp. 59 self.line = line_number('main.cpp', '// Set break point at this line.') 60 61 def class_types(self): 62 """Test 'frame variable this' when stopped on a class constructor.""" 63 exe = os.path.join(os.getcwd(), "a.out") 64 self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) 65 66 # Break on the ctor function of class C. 67 self.expect("breakpoint set -f main.cpp -l %d" % self.line, 68 BREAKPOINT_CREATED, 69 startstr = "Breakpoint created: 1: file ='main.cpp', line = %d" % 70 self.line) 71 72 self.runCmd("run", RUN_SUCCEEDED) 73 74 # The test suite sometimes shows that the process has exited without stopping. 75 # 76 # CC=clang ./dotest.py -v -t class_types 77 # ... 78 # Process 76604 exited with status = 0 (0x00000000) 79 self.runCmd("process status") 80 81 # The stop reason of the thread should be breakpoint. 82 self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, 83 substrs = ['stopped', 84 'stop reason = breakpoint']) 85 86 # The breakpoint should have a hit count of 1. 87 self.expect("breakpoint list -f", BREAKPOINT_HIT_ONCE, 88 substrs = [' resolved, hit count = 1']) 89 90 # We should be stopped on the ctor function of class C. 91 self.expect("frame variable -T this", VARIABLES_DISPLAYED_CORRECTLY, 92 substrs = ['C *', 93 ' this = ']) 94 95 def breakpoint_creation_by_filespec_python(self): 96 """Use Python APIs to create a breakpoint by (filespec, line).""" 97 exe = os.path.join(os.getcwd(), "a.out") 98 99 target = self.dbg.CreateTarget(exe) 100 self.assertTrue(target, VALID_TARGET) 101 102 filespec = target.GetExecutable() 103 self.assertTrue(filespec, VALID_FILESPEC) 104 105 fsDir = filespec.GetDirectory() 106 fsFile = filespec.GetFilename() 107 108 self.assertTrue(fsDir == os.getcwd() and fsFile == "a.out", 109 "FileSpec matches the executable") 110 111 bpfilespec = lldb.SBFileSpec("main.cpp", False) 112 113 breakpoint = target.BreakpointCreateByLocation(bpfilespec, self.line) 114 self.assertTrue(breakpoint, VALID_BREAKPOINT) 115 116 # Verify the breakpoint just created. 117 self.expect(repr(breakpoint), BREAKPOINT_CREATED, exe=False, 118 substrs = ['main.cpp', 119 str(self.line)]) 120 121 # Now launch the process, and do not stop at entry point. 122 error = lldb.SBError() 123 process = target.Launch (self.dbg.GetListener(), None, None, os.ctermid(), os.ctermid(), os.ctermid(), None, 0, False, error) 124 125 if not error.Success() or not process: 126 self.fail("SBTarget.Launch() failed") 127 128 if process.GetState() != lldb.eStateStopped: 129 self.fail("Process should be in the 'stopped' state, " 130 "instead the actual state is: '%s'" % 131 lldbutil.state_type_to_str(process.GetState())) 132 133 # The stop reason of the thread should be breakpoint. 134 thread = process.GetThreadAtIndex(0) 135 if thread.GetStopReason() != lldb.eStopReasonBreakpoint: 136 from lldbutil import stop_reason_to_str 137 self.fail(STOPPED_DUE_TO_BREAKPOINT_WITH_STOP_REASON_AS % 138 stop_reason_to_str(thread.GetStopReason())) 139 140 # The filename of frame #0 should be 'main.cpp' and the line number 141 # should be 93. 142 self.expect("%s:%d" % (lldbutil.get_filenames(thread)[0], 143 lldbutil.get_line_numbers(thread)[0]), 144 "Break correctly at main.cpp:%d" % self.line, exe=False, 145 startstr = "main.cpp:") 146 ### clang compiled code reported main.cpp:94? 147 ### startstr = "main.cpp:93") 148 149 # We should be stopped on the breakpoint with a hit count of 1. 150 self.assertTrue(breakpoint.GetHitCount() == 1, BREAKPOINT_HIT_ONCE) 151 152 process.Continue() 153 154 def class_types_expr_parser(self): 155 """Test 'frame variable this' and 'expr this' when stopped inside a constructor.""" 156 exe = os.path.join(os.getcwd(), "a.out") 157 self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) 158 159 # rdar://problem/8516141 160 # Is this a case of clang (116.1) generating bad debug info? 161 # 162 # Break on the ctor function of class C. 163 self.expect("breakpoint set -M C", BREAKPOINT_CREATED, 164 startstr = "Breakpoint created: 1: name = 'C', locations = 1") 165 166 self.runCmd("run", RUN_SUCCEEDED) 167 168 # The stop reason of the thread should be breakpoint. 169 self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, 170 substrs = ['stopped', 171 'stop reason = breakpoint']) 172 173 # The breakpoint should have a hit count of 1. 174 self.expect("breakpoint list -f", BREAKPOINT_HIT_ONCE, 175 substrs = [' resolved, hit count = 1']) 176 177 # Continue on inside the ctor() body... 178 self.runCmd("thread step-over") 179 180 # Verify that 'frame variable this' gets the data type correct. 181 self.expect("frame variable this",VARIABLES_DISPLAYED_CORRECTLY, 182 substrs = ['C *']) 183 184 # Verify that frame variable -T this->m_c_int behaves correctly. 185 self.expect("frame variable -T this->m_c_int", VARIABLES_DISPLAYED_CORRECTLY, 186 startstr = '(int) this->m_c_int = 66') 187 188 # Verify that 'expression this' gets the data type correct. 189 self.expect("expression this", VARIABLES_DISPLAYED_CORRECTLY, 190 substrs = ['C *']) 191 192 # rdar://problem/8430916 193 # expr this->m_c_int returns an incorrect value 194 # 195 # Verify that expr this->m_c_int behaves correctly. 196 self.expect("expression this->m_c_int", VARIABLES_DISPLAYED_CORRECTLY, 197 patterns = ['\(int\) \$[0-9]+ = 66']) 198 199 200if __name__ == '__main__': 201 import atexit 202 lldb.SBDebugger.Initialize() 203 atexit.register(lambda: lldb.SBDebugger.Terminate()) 204 unittest2.main() 205