1import lldb
2from lldbsuite.test.lldbtest import *
3from lldbsuite.test.decorators import *
4import os
5
6
7class TestTargetSourceMap(TestBase):
8
9    mydir = TestBase.compute_mydir(__file__)
10
11    @no_debug_info_test
12    def test_source_map(self):
13        """Test target.source-map' functionality."""
14
15        def assertBreakpointWithSourceMap(src_path):
16            # Set a breakpoint after we remap source and verify that it succeeds
17            bp = target.BreakpointCreateByLocation(src_path, 2)
18            self.assertEquals(bp.GetNumLocations(), 1,
19                            "make sure breakpoint was resolved with map")
20
21            # Now make sure that we can actually FIND the source file using this
22            # remapping:
23            retval = lldb.SBCommandReturnObject()
24            self.dbg.GetCommandInterpreter().HandleCommand("source list -f main.c -l 2", retval)
25            self.assertTrue(retval.Succeeded(), "source list didn't succeed.")
26            self.assertNotEqual(retval.GetOutput(), None, "We got no ouput from source list")
27            self.assertTrue("return" in retval.GetOutput(), "We didn't find the source file...")
28
29        # Set the target soure map to map "./" to the current test directory
30        src_dir = self.getSourceDir()
31        src_path = os.path.join(src_dir, "main.c")
32        yaml_path = os.path.join(src_dir, "a.yaml")
33        yaml_base, ext = os.path.splitext(yaml_path)
34        obj_path = self.getBuildArtifact("main.o")
35        self.yaml2obj(yaml_path, obj_path)
36
37        # Create a target with the object file we just created from YAML
38        target = self.dbg.CreateTarget(obj_path)
39
40        # Set a breakpoint before we remap source and verify that it fails
41        bp = target.BreakpointCreateByLocation(src_path, 2)
42        self.assertEquals(bp.GetNumLocations(), 0,
43                        "make sure no breakpoints were resolved without map")
44
45        valid_path = os.path.dirname(src_dir)
46        valid_path2 = os.path.dirname(valid_path)
47        invalid_path = src_dir + "invalid_path"
48        invalid_path2 = src_dir + "invalid_path2"
49
50        # We make sure the error message contains all the invalid paths
51        self.expect(
52            'settings set target.source-map . "%s" . "%s" . "%s" . "%s' \
53                % (invalid_path, src_dir, invalid_path2, valid_path),
54            substrs=[
55                'error: the replacement path doesn\'t exist: "%s"' % (invalid_path),
56                'the replacement path doesn\'t exist: "%s"' % (invalid_path2),
57            ],
58            error=True,
59        )
60        self.expect(
61            'settings show target.source-map',
62            substrs=[
63                '[0] "." -> "%s"' % (src_dir),
64                '[1] "." -> "%s"' % (valid_path),
65            ],
66        )
67        assertBreakpointWithSourceMap(src_path)
68
69        # Attempts to replace an index to an invalid mapping should have no effect.
70        # Modifications to valid mappings should work.
71        self.expect(
72            'settings replace target.source-map 0 . "%s" . "%s"' % (invalid_path, valid_path2),
73            substrs=[
74                'error: the replacement path doesn\'t exist: "%s"' % (invalid_path),
75            ],
76            error=True,
77        )
78        self.expect(
79            'settings show target.source-map',
80            substrs=[
81                '[0] "." -> "%s"' % (src_dir),
82                '[1] "." -> "%s"' % (valid_path2),
83            ]
84        )
85        assertBreakpointWithSourceMap(src_path)
86
87        # Let's clear and add the mapping back with insert-after
88        self.runCmd('settings remove target.source-map 0')
89        self.expect(
90            'settings show target.source-map',
91            substrs=['[0] "." -> "%s"' % (valid_path2)],
92        )
93
94        self.expect(
95            'settings insert-after target.source-map 0 . "%s" . "%s" . "%s"' \
96                % (invalid_path, invalid_path2, src_dir),
97            substrs=[
98                'error: the replacement path doesn\'t exist: "%s"' % (invalid_path),
99                'the replacement path doesn\'t exist: "%s"' % (invalid_path2),
100            ],
101            error=True,
102        )
103        self.expect(
104            'settings show target.source-map',
105            substrs=[
106                '[0] "." -> "%s"' % (valid_path2),
107                '[1] "." -> "%s"' % (src_dir),
108            ]
109        )
110
111        # Let's clear using remove and add the mapping in with append
112        self.runCmd('settings remove target.source-map 1')
113        self.expect(
114            'settings show target.source-map',
115            substrs=[
116                '[0] "." -> "%s"' % (valid_path2),
117            ]
118        )
119        self.runCmd('settings clear target.source-map')
120        self.expect(
121            'settings append target.source-map . "%s" . "%s" . "%s"' % (invalid_path, src_dir, invalid_path2),
122            substrs=[
123                'error: the replacement path doesn\'t exist: "%s"' % (invalid_path),
124                'the replacement path doesn\'t exist: "%s"' % (invalid_path2),
125            ],
126            error=True,
127        )
128        self.expect(
129            'settings show target.source-map',
130            substrs=[
131                '[0] "." -> "%s"' % (src_dir),
132            ]
133        )
134        assertBreakpointWithSourceMap(src_path)
135