1"""Test that types defined in shared libraries work correctly."""
2
3
4
5import lldb
6from lldbsuite.test.decorators import *
7from lldbsuite.test.lldbtest import *
8from lldbsuite.test import lldbutil
9
10
11class TestRealDefinition(TestBase):
12
13    mydir = TestBase.compute_mydir(__file__)
14
15    def test_frame_var_after_stop_at_interface(self):
16        """Test that we can find the implementation for an objective C type"""
17        if self.getArchitecture() == 'i386':
18            self.skipTest("requires modern objc runtime")
19        self.build()
20        self.common_setup()
21
22        line = line_number(
23            'Foo.m', '// Set breakpoint where Bar is an interface')
24        lldbutil.run_break_set_by_file_and_line(
25            self, 'Foo.m', line, num_expected_locations=1, loc_exact=True)
26
27        self.runCmd("run", RUN_SUCCEEDED)
28
29        # The stop reason of the thread should be breakpoint.
30        self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
31                    substrs=['stopped',
32                             'stop reason = breakpoint'])
33
34        # Run and stop at Foo
35        self.expect("breakpoint list -f", BREAKPOINT_HIT_ONCE,
36                    substrs=[' resolved, hit count = 1'])
37
38        self.runCmd("continue", RUN_SUCCEEDED)
39
40        # Run at stop at main
41        self.expect("breakpoint list -f", BREAKPOINT_HIT_ONCE,
42                    substrs=[' resolved, hit count = 1'])
43
44        # This should display correctly.
45        self.expect(
46            "frame variable foo->_bar->_hidden_ivar",
47            VARIABLES_DISPLAYED_CORRECTLY,
48            substrs=[
49                "(NSString *)",
50                "foo->_bar->_hidden_ivar = 0x"])
51
52    def test_frame_var_after_stop_at_implementation(self):
53        """Test that we can find the implementation for an objective C type"""
54        if self.getArchitecture() == 'i386':
55            self.skipTest("requires modern objc runtime")
56        self.build()
57        self.common_setup()
58
59        line = line_number(
60            'Bar.m', '// Set breakpoint where Bar is an implementation')
61        lldbutil.run_break_set_by_file_and_line(
62            self, 'Bar.m', line, num_expected_locations=1, loc_exact=True)
63
64        self.runCmd("run", RUN_SUCCEEDED)
65
66        # The stop reason of the thread should be breakpoint.
67        self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
68                    substrs=['stopped',
69                             'stop reason = breakpoint'])
70
71        # Run and stop at Foo
72        self.expect("breakpoint list -f", BREAKPOINT_HIT_ONCE,
73                    substrs=[' resolved, hit count = 1'])
74
75        self.runCmd("continue", RUN_SUCCEEDED)
76
77        # Run at stop at main
78        self.expect("breakpoint list -f", BREAKPOINT_HIT_ONCE,
79                    substrs=[' resolved, hit count = 1'])
80
81        # This should display correctly.
82        self.expect(
83            "frame variable foo->_bar->_hidden_ivar",
84            VARIABLES_DISPLAYED_CORRECTLY,
85            substrs=[
86                "(NSString *)",
87                "foo->_bar->_hidden_ivar = 0x"])
88
89    def common_setup(self):
90        exe = self.getBuildArtifact("a.out")
91        self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
92
93        # Break inside the foo function which takes a bar_ptr argument.
94        line = line_number('main.m', '// Set breakpoint in main')
95        lldbutil.run_break_set_by_file_and_line(
96            self, "main.m", line, num_expected_locations=1, loc_exact=True)
97