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