1d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan"""Test printing ObjC objects that use unbacked properties - so that the static ivar offsets are incorrect."""
2d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan
3d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callananimport os, time
4d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callananimport unittest2
5d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callananimport lldb
6d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callananfrom lldbtest import *
7d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callananimport lldbutil
8d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan
9d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callananclass TestObjCIvarStripped(TestBase):
10d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan
11d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan    mydir = os.path.join("lang", "objc", "objc-ivar-stripped")
12d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan
13d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan    @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
14d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan    @python_api_test
15d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan    @dsym_test
16d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan    def test_with_dsym_and_python_api(self):
17d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan        """Test that we can find stripped Objective-C ivars in the runtime"""
18d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan        self.buildDsym()
19d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan        self.objc_ivar_offsets()
20d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan
21d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan    def setUp(self):
22d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan        # Call super's setUp().
23d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan        TestBase.setUp(self)
24d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan        # Find the line numbers to break inside main().
25d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan        self.main_source = "main.m"
26d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan        self.stop_line = line_number(self.main_source, '// Set breakpoint here.')
27d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan
28d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan    def objc_ivar_offsets(self):
29d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan        """Test that we can find stripped Objective-C ivars in the runtime"""
30d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan        exe = os.path.join(os.getcwd(), "a.out.stripped")
31d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan
32d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan        target = self.dbg.CreateTarget(exe)
33d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan        self.assertTrue(target, VALID_TARGET)
34d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan
35d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan        breakpoint = target.BreakpointCreateByLocation(self.main_source, self.stop_line)
36d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan        self.assertTrue(breakpoint, VALID_BREAKPOINT)
37d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan
38d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan        process = target.LaunchSimple (None, None, os.getcwd())
39d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan        self.assertTrue (process, "Created a process.")
40d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan        self.assertTrue (process.GetState() == lldb.eStateStopped, "Stopped it too.")
41d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan
42d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan        thread_list = lldbutil.get_threads_stopped_at_breakpoint (process, breakpoint)
43d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan        self.assertTrue (len(thread_list) == 1)
44d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan        thread = thread_list[0]
45d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan
46d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan        frame = thread.GetFrameAtIndex(0)
47d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan        self.assertTrue (frame, "frame 0 is valid")
48d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan
49d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan        # Test the expression for mc->_foo
50d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan
51d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan        error = lldb.SBError()
52d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan
53d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan        ivar = frame.EvaluateExpression ("(mc->_foo)")
54d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan        self.assertTrue(ivar, "Got result for mc->_foo")
55d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan        ivar_value = ivar.GetValueAsSigned (error)
56d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan        self.assertTrue (error.Success())
57d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan        self.assertTrue (ivar_value == 3)
58d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan
59d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callananif __name__ == '__main__':
60d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan    import atexit
61d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan    lldb.SBDebugger.Initialize()
62d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan    atexit.register(lambda: lldb.SBDebugger.Terminate())
63d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan    unittest2.main()
64