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