xref: /llvm-project/lldb/test/API/functionalities/source-map/TestTargetSourceMap.py (revision d5f54751048b59cc101125e03dabc57536fc1d2d)
1import lldb
2from lldbsuite.test.lldbtest import *
3from lldbsuite.test.decorators import *
4import json
5import os
6
7
8class TestTargetSourceMap(TestBase):
9
10    @no_debug_info_test
11    def test_source_map_via_setting_api(self):
12        """
13            Test that ensures SBDebugger::GetSetting("target.source-map") API
14            can correctly fetch source mapping entries.
15        """
16        # Set the target soure map to map "./" to the current test directory
17        src_dir = self.getSourceDir()
18
19        source_map_setting_path = "target.source-map"
20        initial_source_map = self.dbg.GetSetting(source_map_setting_path)
21        self.assertEquals(initial_source_map.GetSize(), 0,
22            "Initial source map should be empty")
23
24        src_dir = self.getSourceDir()
25        self.runCmd('settings set %s . "%s"' % (source_map_setting_path, src_dir))
26
27        source_map = self.dbg.GetSetting(source_map_setting_path)
28        self.assertEquals(source_map.GetSize(), 1,
29            "source map should be have one appended entry")
30
31        stream = lldb.SBStream()
32        source_map.GetAsJSON(stream)
33        serialized_source_map = json.loads(stream.GetData())
34
35        self.assertEquals(len(serialized_source_map[0]), 2,
36            "source map entry should have two parts")
37        self.assertEquals(serialized_source_map[0][0], ".",
38            "source map entry's first part does not match")
39        self.assertEquals(serialized_source_map[0][1], src_dir,
40            "source map entry's second part does not match")
41
42
43    @no_debug_info_test
44    def test_source_map(self):
45        """Test target.source-map' functionality."""
46
47        def assertBreakpointWithSourceMap(src_path):
48            # Set a breakpoint after we remap source and verify that it succeeds
49            bp = target.BreakpointCreateByLocation(src_path, 2)
50            self.assertEquals(bp.GetNumLocations(), 1,
51                            "make sure breakpoint was resolved with map")
52
53            # Now make sure that we can actually FIND the source file using this
54            # remapping:
55            retval = lldb.SBCommandReturnObject()
56            self.dbg.GetCommandInterpreter().HandleCommand("source list -f main.c -l 2", retval)
57            self.assertTrue(retval.Succeeded(), "source list didn't succeed.")
58            self.assertNotEqual(retval.GetOutput(), None, "We got no ouput from source list")
59            self.assertIn("return", retval.GetOutput(), "We didn't find the source file...")
60
61        # Set the target soure map to map "./" to the current test directory
62        src_dir = self.getSourceDir()
63        src_path = os.path.join(src_dir, "main.c")
64        yaml_path = os.path.join(src_dir, "a.yaml")
65        yaml_base, ext = os.path.splitext(yaml_path)
66        obj_path = self.getBuildArtifact("main.o")
67        self.yaml2obj(yaml_path, obj_path)
68
69        # Create a target with the object file we just created from YAML
70        target = self.dbg.CreateTarget(obj_path)
71
72        # Set a breakpoint before we remap source and verify that it fails
73        bp = target.BreakpointCreateByLocation(src_path, 2)
74        self.assertEquals(bp.GetNumLocations(), 0,
75                        "make sure no breakpoints were resolved without map")
76
77        valid_path = os.path.dirname(src_dir)
78        valid_path2 = os.path.dirname(valid_path)
79        invalid_path = src_dir + "invalid_path"
80        invalid_path2 = src_dir + "invalid_path2"
81
82        # We make sure the error message contains all the invalid paths
83        self.expect(
84            'settings set target.source-map . "%s" . "%s" . "%s" . "%s' \
85                % (invalid_path, src_dir, invalid_path2, valid_path),
86            substrs=[
87                'error: the replacement path doesn\'t exist: "%s"' % (invalid_path),
88                'the replacement path doesn\'t exist: "%s"' % (invalid_path2),
89            ],
90            error=True,
91        )
92        self.expect(
93            'settings show target.source-map',
94            substrs=[
95                '[0] "." -> "%s"' % (src_dir),
96                '[1] "." -> "%s"' % (valid_path),
97            ],
98        )
99        assertBreakpointWithSourceMap(src_path)
100
101        # Attempts to replace an index to an invalid mapping should have no effect.
102        # Modifications to valid mappings should work.
103        self.expect(
104            'settings replace target.source-map 0 . "%s" . "%s"' % (invalid_path, valid_path2),
105            substrs=[
106                'error: the replacement path doesn\'t exist: "%s"' % (invalid_path),
107            ],
108            error=True,
109        )
110        self.expect(
111            'settings show target.source-map',
112            substrs=[
113                '[0] "." -> "%s"' % (src_dir),
114                '[1] "." -> "%s"' % (valid_path2),
115            ]
116        )
117        assertBreakpointWithSourceMap(src_path)
118
119        # Let's clear and add the mapping back with insert-after
120        self.runCmd('settings remove target.source-map 0')
121        self.expect(
122            'settings show target.source-map',
123            substrs=['[0] "." -> "%s"' % (valid_path2)],
124        )
125
126        self.expect(
127            'settings insert-after target.source-map 0 . "%s" . "%s" . "%s"' \
128                % (invalid_path, invalid_path2, src_dir),
129            substrs=[
130                'error: the replacement path doesn\'t exist: "%s"' % (invalid_path),
131                'the replacement path doesn\'t exist: "%s"' % (invalid_path2),
132            ],
133            error=True,
134        )
135        self.expect(
136            'settings show target.source-map',
137            substrs=[
138                '[0] "." -> "%s"' % (valid_path2),
139                '[1] "." -> "%s"' % (src_dir),
140            ]
141        )
142
143        # Let's clear using remove and add the mapping in with append
144        self.runCmd('settings remove target.source-map 1')
145        self.expect(
146            'settings show target.source-map',
147            substrs=[
148                '[0] "." -> "%s"' % (valid_path2),
149            ]
150        )
151        self.runCmd('settings clear target.source-map')
152        self.expect(
153            'settings append target.source-map . "%s" . "%s" . "%s"' % (invalid_path, src_dir, invalid_path2),
154            substrs=[
155                'error: the replacement path doesn\'t exist: "%s"' % (invalid_path),
156                'the replacement path doesn\'t exist: "%s"' % (invalid_path2),
157            ],
158            error=True,
159        )
160        self.expect(
161            'settings show target.source-map',
162            substrs=[
163                '[0] "." -> "%s"' % (src_dir),
164            ]
165        )
166        assertBreakpointWithSourceMap(src_path)
167