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