TestCppValueCast.py revision 21b1984e161b0cadee331d32bfd721eccfdf4b1f
1"""
2Test lldb Python API SBValue::Cast(SBType) for C++ types.
3"""
4
5import os, time
6import re
7import unittest2
8import lldb, lldbutil
9from lldbtest import *
10
11class 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
150if __name__ == '__main__':
151    import atexit
152    lldb.SBDebugger.Initialize()
153    atexit.register(lambda: lldb.SBDebugger.Terminate())
154    unittest2.main()
155