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