1"""
2Test symbol table access for main.m.
3"""
4
5import lldb
6from lldbsuite.test.decorators import *
7from lldbsuite.test.lldbtest import *
8from lldbsuite.test import lldbutil
9
10
11@skipUnlessDarwin
12class FoundationSymtabTestCase(TestBase):
13
14    mydir = TestBase.compute_mydir(__file__)
15
16    symbols_list = ['-[MyString initWithNSString:]',
17                    '-[MyString dealloc]',
18                    '-[MyString description]',
19                    '-[MyString descriptionPauses]',     # synthesized property
20                    '-[MyString setDescriptionPauses:]', # synthesized property
21                    'Test_Selector',
22                    'Test_NSString',
23                    'Test_MyString',
24                    'Test_NSArray',
25                    'main'
26                    ]
27
28    @add_test_categories(['pyapi'])
29    def test_with_python_api(self):
30        """Test symbol table access with Python APIs."""
31        self.build()
32        exe = self.getBuildArtifact("a.out")
33        target = self.dbg.CreateTarget(exe)
34        self.assertTrue(target, VALID_TARGET)
35
36        # Launch the process, and do not stop at the entry point.
37        process = target.LaunchSimple(
38            None, None, self.get_process_working_directory())
39        self.assertTrue(process, PROCESS_IS_VALID)
40
41        # Create the filespec by which to locate our a.out module.
42        #
43        #  - Use the absolute path to get the module for the current variant.
44        #  - Use the relative path for reproducers. The modules are never
45        #    orphaned because the SB objects are leaked intentionally. This
46        #    causes LLDB to reuse the same module for every variant, because the
47        #    UUID is the same for all the inferiors. FindModule below only
48        #    compares paths and is oblivious to the fact that the UUIDs are the
49        #    same.
50        if configuration.is_reproducer():
51            filespec = lldb.SBFileSpec('a.out', False)
52        else:
53            filespec = lldb.SBFileSpec(exe, False)
54
55        module = target.FindModule(filespec)
56        self.assertTrue(module, VALID_MODULE)
57
58        # Create the set of known symbols.  As we iterate through the symbol
59        # table, remove the symbol from the set if it is a known symbol.
60        expected_symbols = set(self.symbols_list)
61        for symbol in module:
62            self.assertTrue(symbol, VALID_SYMBOL)
63            self.trace("symbol:", symbol)
64            name = symbol.GetName()
65            if name in expected_symbols:
66                self.trace("Removing %s from known_symbols %s" % (name, expected_symbols))
67                expected_symbols.remove(name)
68
69        # At this point, the known_symbols set should have become an empty set.
70        # If not, raise an error.
71        self.trace("symbols unaccounted for:", expected_symbols)
72        self.assertTrue(len(expected_symbols) == 0,
73                        "All the known symbols are accounted for")
74