1 """ 2 Test lldb Python API SBValue::Cast(SBType) for C++ types. 3 """ 4 5 import os, time 6 import re 7 import unittest2 8 import lldb, lldbutil 9 from lldbtest import * 10 11 class CppValueCastTestCase(TestBase): 12 13 mydir = os.path.join("lang", "cpp", "dynamic-value") 14 15 # rdar://problem/10808472 SBValue::Cast test case is failing (virtual inheritance) 16 @unittest2.expectedFailure 17 @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin") 18 @python_api_test 19 @dsym_test 20 def test_value_cast_with_dsym_and_virtual_inheritance(self): 21 """Test SBValue::Cast(SBType) API for C++ types with virtual inheritance.""" 22 self.buildDsym(dictionary=self.d_virtual) 23 self.setTearDownCleanup(dictionary=self.d_virtual) 24 self.do_sbvalue_cast(self.exe_name) 25 26 # rdar://problem/10808472 SBValue::Cast test case is failing (virtual inheritance) 27 @unittest2.expectedFailure 28 @python_api_test 29 @dwarf_test 30 def test_value_cast_with_dwarf_and_virtual_inheritance(self): 31 """Test SBValue::Cast(SBType) API for C++ types with virtual inheritance.""" 32 self.buildDwarf(dictionary=self.d_virtual) 33 self.setTearDownCleanup(dictionary=self.d_virtual) 34 self.do_sbvalue_cast(self.exe_name) 35 36 @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin") 37 @python_api_test 38 @dsym_test 39 def test_value_cast_with_dsym_and_regular_inheritance(self): 40 """Test SBValue::Cast(SBType) API for C++ types with regular inheritance.""" 41 self.buildDsym(dictionary=self.d_regular) 42 self.setTearDownCleanup(dictionary=self.d_regular) 43 self.do_sbvalue_cast(self.exe_name) 44 45 @python_api_test 46 @dwarf_test 47 def test_value_cast_with_dwarf_and_regular_inheritance(self): 48 """Test SBValue::Cast(SBType) API for C++ types with regular inheritance.""" 49 self.buildDwarf(dictionary=self.d_regular) 50 self.setTearDownCleanup(dictionary=self.d_regular) 51 self.do_sbvalue_cast(self.exe_name) 52 53 def setUp(self): 54 # Call super's setUp(). 55 TestBase.setUp(self) 56 57 # Find the line number to break for main.c. 58 self.source = 'sbvalue-cast.cpp'; 59 self.line = line_number(self.source, '// Set breakpoint here.') 60 self.exe_name = self.testMethodName 61 self.d_virtual = {'CXX_SOURCES': self.source, 'EXE': self.exe_name, 'CFLAGS_EXTRAS': '-DDO_VIRTUAL_INHERITANCE'} 62 self.d_regular = {'CXX_SOURCES': self.source, 'EXE': self.exe_name} 63 64 def do_sbvalue_cast (self, exe_name): 65 """Test SBValue::Cast(SBType) API for C++ types.""" 66 exe = os.path.join(os.getcwd(), exe_name) 67 68 # Create a target from the debugger. 69 70 target = self.dbg.CreateTarget (exe) 71 self.assertTrue(target, VALID_TARGET) 72 73 # Set up our breakpoints: 74 75 breakpoint = target.BreakpointCreateByLocation(self.source, self.line) 76 self.assertTrue(breakpoint, VALID_BREAKPOINT) 77 78 # Now launch the process, and do not stop at the entry point. 79 process = target.LaunchSimple (None, None, os.getcwd()) 80 81 self.assertTrue(process.GetState() == lldb.eStateStopped, 82 PROCESS_STOPPED) 83 84 # Find DerivedA and DerivedB types. 85 typeA = target.FindFirstType('DerivedA') 86 typeB = target.FindFirstType('DerivedB') 87 self.DebugSBType(typeA) 88 self.DebugSBType(typeB) 89 self.assertTrue(typeA) 90 self.assertTrue(typeB) 91 error = lldb.SBError() 92 93 # First stop is for DerivedA instance. 94 threads = lldbutil.get_threads_stopped_at_breakpoint (process, breakpoint) 95 self.assertTrue (len(threads) == 1) 96 thread = threads[0] 97 frame0 = thread.GetFrameAtIndex(0) 98 99 tellerA = frame0.FindVariable('teller', lldb.eNoDynamicValues) 100 self.DebugSBValue(tellerA) 101 self.assertTrue(tellerA.GetChildMemberWithName('m_base_val').GetValueAsUnsigned(error, 0) == 20) 102 103 if self.TraceOn(): 104 for child in tellerA: 105 print "child name:", child.GetName() 106 print child 107 108 # Call SBValue.Cast() to obtain instanceA. 109 instanceA = tellerA.Cast(typeA.GetPointerType()) 110 self.DebugSBValue(instanceA) 111 112 # Iterate through all the children and print their values. 113 if self.TraceOn(): 114 for child in instanceA: 115 print "child name:", child.GetName() 116 print child 117 a_member_val = instanceA.GetChildMemberWithName('m_a_val') 118 self.DebugSBValue(a_member_val) 119 self.assertTrue(a_member_val.GetValueAsUnsigned(error, 0) == 10) 120 121 # Second stop is for DerivedB instance. 122 threads = lldbutil.continue_to_breakpoint (process, breakpoint) 123 self.assertTrue (len(threads) == 1) 124 thread = threads[0] 125 frame0 = thread.GetFrameAtIndex(0) 126 127 tellerB = frame0.FindVariable('teller', lldb.eNoDynamicValues) 128 self.DebugSBValue(tellerB) 129 self.assertTrue(tellerB.GetChildMemberWithName('m_base_val').GetValueAsUnsigned(error, 0) == 12) 130 131 if self.TraceOn(): 132 for child in tellerB: 133 print "child name:", child.GetName() 134 print child 135 136 # Call SBValue.Cast() to obtain instanceB. 137 instanceB = tellerB.Cast(typeB.GetPointerType()) 138 self.DebugSBValue(instanceB) 139 140 # Iterate through all the children and print their values. 141 if self.TraceOn(): 142 for child in instanceB: 143 print "child name:", child.GetName() 144 print child 145 b_member_val = instanceB.GetChildMemberWithName('m_b_val') 146 self.DebugSBValue(b_member_val) 147 self.assertTrue(b_member_val.GetValueAsUnsigned(error, 0) == 36) 148 149 150 if __name__ == '__main__': 151 import atexit 152 lldb.SBDebugger.Initialize() 153 atexit.register(lambda: lldb.SBDebugger.Terminate()) 154 unittest2.main() 155