1da816ca0SGreg Clayton"""Test the LLDB module cache funcionality."""
2da816ca0SGreg Clayton
3da816ca0SGreg Claytonimport glob
4da816ca0SGreg Claytonimport lldb
5da816ca0SGreg Claytonfrom lldbsuite.test.decorators import *
6da816ca0SGreg Claytonfrom lldbsuite.test.lldbtest import *
7da816ca0SGreg Claytonfrom lldbsuite.test import lldbutil
8da816ca0SGreg Claytonimport os
9da816ca0SGreg Claytonimport time
10da816ca0SGreg Clayton
11da816ca0SGreg Clayton
12da816ca0SGreg Claytonclass ModuleCacheTestcaseBSD(TestBase):
13da816ca0SGreg Clayton
14da816ca0SGreg Clayton    mydir = TestBase.compute_mydir(__file__)
15da816ca0SGreg Clayton
16da816ca0SGreg Clayton    def setUp(self):
17da816ca0SGreg Clayton        # Call super's setUp().
18da816ca0SGreg Clayton        TestBase.setUp(self)
19da816ca0SGreg Clayton        # Find the line number in a(int) to break at.
20da816ca0SGreg Clayton        self.line_a = line_number(
21da816ca0SGreg Clayton            'a.c', '// Set file and line breakpoint inside a().')
22da816ca0SGreg Clayton        self.line_b = line_number(
23da816ca0SGreg Clayton            'b.c', '// Set file and line breakpoint inside b().')
24da816ca0SGreg Clayton        self.line_c = line_number(
25da816ca0SGreg Clayton            'c.c', '// Set file and line breakpoint inside c().')
26da816ca0SGreg Clayton        self.cache_dir = os.path.join(self.getBuildDir(), 'lldb-module-cache')
27da816ca0SGreg Clayton        # Set the lldb module cache directory to a directory inside the build
28da816ca0SGreg Clayton        # artifacts directory so no other tests are interfered with.
29da816ca0SGreg Clayton        self.runCmd('settings set symbols.lldb-index-cache-path "%s"' % (self.cache_dir))
30da816ca0SGreg Clayton        self.runCmd('settings set symbols.enable-lldb-index-cache true')
31da816ca0SGreg Clayton        self.build()
32da816ca0SGreg Clayton
33da816ca0SGreg Clayton
34da816ca0SGreg Clayton    def get_module_cache_files(self, basename):
35da816ca0SGreg Clayton        module_cache_glob = os.path.join(self.cache_dir, "llvmcache-*%s*symtab*" % (basename))
36da816ca0SGreg Clayton        return glob.glob(module_cache_glob)
37da816ca0SGreg Clayton
38da816ca0SGreg Clayton
39da816ca0SGreg Clayton    # Requires no dSYM, so we let the Makefile make the right stuff for us
40da816ca0SGreg Clayton    @no_debug_info_test
41da816ca0SGreg Clayton    @skipUnlessDarwin
42da816ca0SGreg Clayton    def test(self):
43da816ca0SGreg Clayton        """
44*b6087ba7SGreg Clayton            This test has been modified to make sure .o files that don't have
45*b6087ba7SGreg Clayton            UUIDs are not cached after discovering build systems that play with
46*b6087ba7SGreg Clayton            modification times of .o files that the modification times are not
47*b6087ba7SGreg Clayton            unique enough to ensure the .o file within the .a file are the right
48*b6087ba7SGreg Clayton            files as this was causing older cache files to be accepted for new
49*b6087ba7SGreg Clayton            updated .o files.
50*b6087ba7SGreg Clayton
51*b6087ba7SGreg Clayton            ELF .o files do calculate a UUID from the contents of the file,
52*b6087ba7SGreg Clayton            which is expensive, but no one loads .o files into a debug sessions
53*b6087ba7SGreg Clayton            when using ELF files. Mach-o .o files do not have UUID values and do
54*b6087ba7SGreg Clayton            no calculate one as they _are_ used during debug sessions when no
55*b6087ba7SGreg Clayton            dSYM file is generated. If we can find a way to uniquely and cheaply
56*b6087ba7SGreg Clayton            create UUID values for mach-o .o files in the future, this test will
57*b6087ba7SGreg Clayton            be updated to test this functionality. This test will now make sure
58*b6087ba7SGreg Clayton            there are no cache entries for any .o files in BSD archives.
59*b6087ba7SGreg Clayton
60*b6087ba7SGreg Clayton            The old test case description is below in case we enable caching for
61*b6087ba7SGreg Clayton            .o files again:
62*b6087ba7SGreg Clayton
63da816ca0SGreg Clayton            Test module cache functionality for bsd archive object files.
64da816ca0SGreg Clayton
65da816ca0SGreg Clayton            This will test that if we enable the module cache, we have a
66da816ca0SGreg Clayton            corresponding cache entry for the .o files in libfoo.a.
67da816ca0SGreg Clayton
68da816ca0SGreg Clayton            The static library has two entries for "a.o":
69da816ca0SGreg Clayton            - one from a.c
70da816ca0SGreg Clayton            - one from c.c which had c.o renamed to a.o and then put into the
71da816ca0SGreg Clayton              libfoo.a as an extra .o file with different contents from the
72da816ca0SGreg Clayton              original a.o
73da816ca0SGreg Clayton
74da816ca0SGreg Clayton            We do this to test that we can correctly cache duplicate .o files
75da816ca0SGreg Clayton            that appear in .a files.
76da816ca0SGreg Clayton
77da816ca0SGreg Clayton            This test only works on darwin because of the way DWARF is stored
78da816ca0SGreg Clayton            where the debug map will refer to .o files inside of .a files.
79da816ca0SGreg Clayton        """
80da816ca0SGreg Clayton        exe = self.getBuildArtifact("a.out")
81da816ca0SGreg Clayton
82da816ca0SGreg Clayton        # Create a module with no depedencies.
83da816ca0SGreg Clayton        target = self.createTestTarget(load_dependent_modules=False)
84da816ca0SGreg Clayton
85da816ca0SGreg Clayton        self.runCmd('breakpoint set -f a.c -l %d' % (self.line_a))
86da816ca0SGreg Clayton        self.runCmd('breakpoint set -f b.c -l %d' % (self.line_b))
87da816ca0SGreg Clayton        self.runCmd('breakpoint set -f c.c -l %d' % (self.line_c))
88da816ca0SGreg Clayton
89da816ca0SGreg Clayton        # Get the executable module and get the number of symbols to make
90da816ca0SGreg Clayton        # sure the symbol table gets parsed and cached. The module cache is
91da816ca0SGreg Clayton        # enabled in the setUp() function.
92da816ca0SGreg Clayton        main_module = target.GetModuleAtIndex(0)
93da816ca0SGreg Clayton        self.assertTrue(main_module.IsValid())
94da816ca0SGreg Clayton        # Make sure the symbol table gets loaded and cached
95da816ca0SGreg Clayton        main_module.GetNumSymbols()
96da816ca0SGreg Clayton        a_o_cache_files = self.get_module_cache_files("libfoo.a(a.o)")
97da816ca0SGreg Clayton        b_o_cache_files = self.get_module_cache_files("libfoo.a(b.o)")
98*b6087ba7SGreg Clayton
99*b6087ba7SGreg Clayton
100da816ca0SGreg Clayton        # We expect the directory for a.o to have two cache directories:
101da816ca0SGreg Clayton        # - 1 for the a.o with a earlier mod time
102da816ca0SGreg Clayton        # - 1 for the a.o that was renamed from c.o that should be 2 seconds older
103*b6087ba7SGreg Clayton        # self.assertEqual(len(a_o_cache_files), 2,
104*b6087ba7SGreg Clayton        #         "make sure there are two files in the module cache directory (%s) for libfoo.a(a.o)" % (self.cache_dir))
105*b6087ba7SGreg Clayton        # self.assertEqual(len(b_o_cache_files), 1,
106*b6087ba7SGreg Clayton        #         "make sure there are two files in the module cache directory (%s) for libfoo.a(b.o)" % (self.cache_dir))
107*b6087ba7SGreg Clayton
108*b6087ba7SGreg Clayton        # We are no longer caching .o files in the lldb index cache. If we ever
109*b6087ba7SGreg Clayton        # re-enable this functionality, we can uncomment out the above lines of
110*b6087ba7SGreg Clayton        # code.
111*b6087ba7SGreg Clayton        self.assertEqual(len(a_o_cache_files), 0,
112*b6087ba7SGreg Clayton                "make sure there are no files in the module cache directory (%s) for libfoo.a(a.o)" % (self.cache_dir))
113*b6087ba7SGreg Clayton        self.assertEqual(len(b_o_cache_files), 0,
114*b6087ba7SGreg Clayton                "make sure there are no files in the module cache directory (%s) for libfoo.a(b.o)" % (self.cache_dir))
115