public void LoadBinary_NullModule() { SbModule module = null; Assert.ThrowsAsync <ArgumentNullException>( () => binaryLoader.LoadBinaryAsync(module, searchLog)); }
public SbError SetModuleLoadAddress(SbModule module, long sectionsOffset) { SetModuleLoadAddressResponse response = null; if (connection.InvokeRpc(() => { response = client.SetModuleLoadAddress( new SetModuleLoadAddressRequest { Target = grpcSbTarget, Module = new GrpcSbModule { Id = module.GetId() }, SectionsOffset = sectionsOffset, }); })) { return(errorFactory.Create(response.Error)); } var grpcSbError = new GrpcSbError { Success = false, Error = "Rpc error while calling SetModuleLoadAddress." }; return(errorFactory.Create(grpcSbError)); }
public async Task LoadModuleFilesWithExclusionSettingsAsync() { SbModule includedModule = CreateMockModule(true, true, "included"); SbModule excludedModule = CreateMockModule(true, true, "excluded"); var modules = new List <SbModule>() { includedModule, excludedModule }; bool useIncludeList = false; var excludeList = new List <string>() { "excluded" }; var settings = new SymbolInclusionSettings(useIncludeList, excludeList, new List <string>()); Assert.That( await moduleFileLoader.LoadModuleFilesAsync( modules, settings, true, mockTask, fakeModuleFileLoadRecorder), Is.EqualTo(VSConstants.S_OK)); await AssertLoadBinaryReceivedAsync(includedModule); await AssertLoadSymbolsReceivedAsync(includedModule); await AssertLoadBinaryNotReceivedAsync(excludedModule); await AssertLoadSymbolsNotReceivedAsync(excludedModule); }
public PlaceholderModuleProperties GetPlaceholderProperties(SbModule placeholderModule, RemoteTarget lldbTarget) { SbSection placeholderSection = placeholderModule.FindSection(".module_image"); if (placeholderSection == null) { // Could be either an RPC error or a usage error. Hmm... throw new ArgumentException( "Placeholder properties can only be copied from placeholder modules."); } // The load address of the placeholder section represents the base load address of the // module as a whole in the original process. ulong placeholderBaseLoadAddress = placeholderSection.GetLoadAddress(lldbTarget); if (placeholderBaseLoadAddress == DebuggerConstants.INVALID_ADDRESS) { Trace.WriteLine("Failed to get load address from the placeholder section."); return(null); } // |slide| is how much we need to offset the module's load address by long slide = (long)placeholderBaseLoadAddress; SbFileSpec fileSpec = placeholderModule.GetPlatformFileSpec(); if (fileSpec == null) { Trace.WriteLine("Failed to get file spec from placeholder module."); return(null); } return(new PlaceholderModuleProperties(slide, fileSpec)); }
bool AddSymbolFile(string filepath, SbModule module, TextWriter searchLog) { var command = "target symbols add"; var platformFileSpec = module.GetPlatformFileSpec(); if (platformFileSpec != null) { var platformPath = FileUtil.PathCombineLinux(platformFileSpec.GetDirectory(), platformFileSpec.GetFilename()); // The -s flag specifies the path of the module to add symbols to. command += " -s " + LldbCommandUtil.QuoteArgument(platformPath); } command += " " + LldbCommandUtil.QuoteArgument(filepath); SbCommandReturnObject commandResult; lldbCommandInterpreter.HandleCommand(command, out commandResult); Trace.WriteLine($"Executed LLDB command '{command}' with result:" + Environment.NewLine + commandResult.GetDescription()); if (!commandResult.Succeeded()) { searchLog.WriteLine("LLDB error: " + commandResult.GetError()); return(false); } searchLog.WriteLine("LLDB output: " + commandResult.GetOutput()); searchLog.WriteLine("Symbols loaded successfully."); Trace.WriteLine($"Successfully loaded symbol file '{filepath}'."); return(true); }
public IDebugModule3 GetOrCreate(SbModule lldbModule, IGgpDebugProgram program) { lock (cache) { if (!cache.TryGetValue(lldbModule, out IDebugModule3 module)) { module = moduleCreator(lldbModule, nextLoadOrder++, program); cache.Add(lldbModule, module); // TODO: Simplify inter-thread interactions in the VSI, and as part // of that find a less ad-hoc solution to ModuleAdded/Removed event thread // safety issues mainThreadDispatcher.Post(() => { try { ModuleAdded?.Invoke(Self, new ModuleAddedEventArgs(module)); } catch (Exception e) { Trace.WriteLine( $"Warning: ModuleAdded handler failed with exception: {e}"); } }); } ; return(module); } }
public void GetAndApplyPlaceholderProperties(ulong fileBaseAddress) { long slide = (long)BASE_LOAD_ADDRESS - (long)fileBaseAddress; SbModule placeholderModule = CreatePlaceholderModule(); var headerAddress = Substitute.For <SbAddress>(); headerAddress.GetFileAddress().Returns(fileBaseAddress); var containerSection = Substitute.For <SbSection>(); containerSection.GetSectionType().Returns(SectionType.Container); var otherModule = Substitute.For <SbModule>(); otherModule.GetObjectFileHeaderAddress().Returns(headerAddress); otherModule.SetPlatformFileSpec(Arg.Any <SbFileSpec>()).Returns(true); PlaceholderModuleProperties properties = moduleUtil.GetPlaceholderProperties(placeholderModule, mockTarget); Assert.IsNotNull(properties); Assert.AreEqual(slide + (long)fileBaseAddress, properties.Slide); Assert.AreEqual(mockPlatformFileSpec, properties.PlatformFileSpec); Assert.True( moduleUtil.ApplyPlaceholderProperties(otherModule, properties, mockTarget)); otherModule.Received().SetPlatformFileSpec(mockPlatformFileSpec); mockTarget.Received().SetModuleLoadAddress(otherModule, slide); }
public bool ApplyPlaceholderProperties(SbModule destModule, PlaceholderModuleProperties properties, RemoteTarget lldbTarget) { long slide = properties.Slide; SbAddress headerAddress = destModule.GetObjectFileHeaderAddress(); if (headerAddress != null) { // For libraries this will generally equal 0, for executables it will equal // |placeholderBaseLoadAddress|. ulong fileBaseAddress = headerAddress.GetFileAddress(); slide -= (long)fileBaseAddress; } SbError error = lldbTarget.SetModuleLoadAddress(destModule, slide); if (error.Fail()) { Trace.WriteLine( $"Failed to set load address on destination module: {error.GetCString()}."); return(false); } if (!destModule.SetPlatformFileSpec(properties.PlatformFileSpec)) { Trace.WriteLine("Failed to set file spec on the destination module."); return(false); } return(true); }
public void SetUp() { searchLog = new StringWriter(); mockTarget = Substitute.For <RemoteTarget>(); moduleReplacedHandler = Substitute.For <EventHandler <LldbModuleReplacedEventArgs> >(); mockModuleFileFinder = Substitute.For <IModuleFileFinder>(); mockModuleFileFinder.FindFileAsync(BINARY_FILENAME, UUID, false, searchLog) .Returns(Task.FromResult(PATH_IN_STORE)); placeholderModule = Substitute.For <SbModule>(); placeholderModule.GetPlatformFileSpec().GetFilename().Returns(BINARY_FILENAME); placeholderModule.GetUUIDString().Returns(UUID.ToString()); placeholderProperties = new PlaceholderModuleProperties(MODULE_SLIDE, Substitute.For <SbFileSpec>()); mockModuleUtil = Substitute.For <ILldbModuleUtil>(); mockModuleUtil.IsPlaceholderModule(placeholderModule).Returns(true); mockModuleUtil.GetPlaceholderProperties(Arg.Any <SbModule>(), Arg.Any <RemoteTarget>()) .ReturnsForAnyArgs(placeholderProperties); mockModuleUtil.ApplyPlaceholderProperties( Arg.Any <SbModule>(), Arg.Any <PlaceholderModuleProperties>(), Arg.Any <RemoteTarget>()) .ReturnsForAnyArgs(true); binaryLoader = new BinaryLoader(mockModuleUtil, mockModuleFileFinder, mockTarget); binaryLoader.LldbModuleReplaced += moduleReplacedHandler; }
public virtual async Task <(SbModule, bool)> LoadBinaryAsync( SbModule lldbModule, TextWriter searchLog) { if (lldbModule == null) { throw new ArgumentNullException(nameof(lldbModule)); } searchLog = searchLog ?? TextWriter.Null; if (!moduleUtil.IsPlaceholderModule(lldbModule)) { return(lldbModule, true); } var binaryName = lldbModule.GetPlatformFileSpec()?.GetFilename(); if (string.IsNullOrEmpty(binaryName)) { await searchLog.WriteLineAsync(ErrorStrings.BinaryFileNameUnknown); Trace.WriteLine(ErrorStrings.BinaryFileNameUnknown); return(lldbModule, false); } var binaryPath = await moduleFileFinder.FindFileAsync( binaryName, new BuildId(lldbModule.GetUUIDString()), false, searchLog); if (binaryPath == null) { return(lldbModule, false); } PlaceholderModuleProperties properties = moduleUtil.GetPlaceholderProperties(lldbModule, lldbTarget); if (properties == null) { return(lldbModule, false); } RemoveModule(lldbModule); var newModule = AddModule(binaryPath, lldbModule.GetUUIDString(), searchLog); if (newModule == null) { return(lldbModule, false); } if (!moduleUtil.ApplyPlaceholderProperties(newModule, properties, lldbTarget)) { return(lldbModule, false); } LldbModuleReplaced?.Invoke(Self, new LldbModuleReplacedEventArgs(newModule, lldbModule)); return(newModule, true); }
public virtual IDebugModule3 Create( IModuleFileLoader moduleFileLoader, IModuleSearchLogHolder moduleSearchLogHolder, SbModule lldbModule, uint loadOrder, IDebugEngineHandler debugEngineHandler, IGgpDebugProgram program) => new DebugModule(_cancelableTaskFactory, _actionRecorder, _moduleFileLoadRecorderFactory, _moduleUtil, moduleFileLoader, moduleSearchLogHolder, lldbModule, loadOrder, debugEngineHandler, program, _symbolSettingsProvider);
public override Task <RemoveModuleResponse> RemoveModule(RemoveModuleRequest request, ServerCallContext context) { RemoteTarget target = GrpcLookupUtils.GetTarget(request.Target, _targetStore); SbModule module = _moduleStore.GetObject(request.Module.Id); return(Task.FromResult( new RemoveModuleResponse { Result = target.RemoveModule(module) })); }
public void SetSearchLog(SbModule lldbModule, string log) { SbFileSpec platformFileSpec = lldbModule.GetPlatformFileSpec(); if (platformFileSpec != null) { string key = FileUtil.PathCombineLinux(platformFileSpec.GetDirectory(), platformFileSpec.GetFilename()); _logsByPlatformFileSpec[key] = log; } }
public void GetPlaceholderProperties_GetPlatformFileSpecFails() { SbModule placeholderModule = CreatePlaceholderModule(); placeholderModule.GetPlatformFileSpec().Returns((SbFileSpec)null); Assert.IsNull(moduleUtil.GetPlaceholderProperties(placeholderModule, mockTarget)); var output = logSpy.GetOutput(); Assert.That(output, Does.Contain("Failed to get file spec")); }
public void GetPlaceholderProperties_GetLoadAddressFails() { SbModule placeholderModule = CreatePlaceholderModule(); placeholderModule.FindSection(".module_image") .GetLoadAddress(mockTarget).Returns(DebuggerConstants.INVALID_ADDRESS); Assert.IsNull(moduleUtil.GetPlaceholderProperties(placeholderModule, mockTarget)); var output = logSpy.GetOutput(); Assert.That(output, Does.Contain("Failed to get load address")); }
public void SetUp() { logSpy = new LogSpy(); logSpy.Attach(); var noError = new SbErrorStub(true, null); mockTarget = Substitute.For <RemoteTarget>(); mockTarget.SetModuleLoadAddress(Arg.Any <SbModule>(), Arg.Any <long>()).Returns(noError); mockModule = Substitute.For <SbModule>(); mockModule.HasCompileUnits().Returns(false); mockModule.FindSection(Arg.Any <string>()).Returns((SbSection)null); mockPlatformFileSpec = Substitute.For <SbFileSpec>(); moduleUtil = new LldbModuleUtil(); }
public override Task <SetModuleLoadAddressResponse> SetModuleLoadAddress( SetModuleLoadAddressRequest request, ServerCallContext context) { RemoteTarget target = GrpcLookupUtils.GetTarget(request.Target, _targetStore); SbModule module = _moduleStore.GetObject(request.Module.Id); SbError error = target.SetModuleLoadAddress(module, request.SectionsOffset); var grpcError = new GrpcSbError { Success = error.Success(), Error = error.GetCString() }; return(Task.FromResult(new SetModuleLoadAddressResponse { Error = grpcError })); }
public override Task <AddModuleResponse> AddModule(AddModuleRequest request, ServerCallContext context) { RemoteTarget target = GrpcLookupUtils.GetTarget(request.Target, _targetStore); var response = new AddModuleResponse(); SbModule module = target.AddModule(request.Path, request.Triple, request.Uuid); if (module != null) { response.Module = new GrpcSbModule { Id = _moduleStore.AddObject(module) }; } return(Task.FromResult(response)); }
public override Task <GetModuleResponse> GetModule(GetModuleRequest request, ServerCallContext context) { RemoteFrame frame = frameStore.GetObject(request.Frame.Id); SbModule module = frame.GetModule(); GetModuleResponse response = new GetModuleResponse(); if (module != null) { response.Module = new GrpcSbModule { Id = moduleStore.AddObject(module) }; } return(Task.FromResult(response)); }
public string GetSearchLog(SbModule lldbModule) { SbFileSpec platformFileSpec = lldbModule.GetPlatformFileSpec(); if (platformFileSpec == null) { return(""); } string key = FileUtil.PathCombineLinux(platformFileSpec.GetDirectory(), platformFileSpec.GetFilename()); if (_logsByPlatformFileSpec.TryGetValue(key, out string log)) { return(log); } return(""); }
DebugModule(CancelableTask.Factory cancelableTaskFactory, ActionRecorder actionRecorder, ModuleFileLoadMetricsRecorder.Factory moduleFileLoadRecorderFactory, ILldbModuleUtil moduleUtil, IModuleFileLoader moduleFileLoader, IModuleSearchLogHolder moduleSearchLogHolder, SbModule lldbModule, uint loadOrder, IDebugEngineHandler engineHandler, IGgpDebugProgram program, ISymbolSettingsProvider symbolSettingsProvider) { _cancelableTaskFactory = cancelableTaskFactory; _actionRecorder = actionRecorder; _moduleFileLoadRecorderFactory = moduleFileLoadRecorderFactory; _moduleUtil = moduleUtil; _moduleFileLoader = moduleFileLoader; _moduleSearchLogHolder = moduleSearchLogHolder; _lldbModule = lldbModule; _loadOrder = loadOrder; _engineHandler = engineHandler; _program = program; _symbolSettingsProvider = symbolSettingsProvider; }
public bool RemoveModule(SbModule module) { RemoveModuleResponse response = null; if (connection.InvokeRpc(() => { response = client.RemoveModule(new RemoveModuleRequest { Target = grpcSbTarget, Module = new GrpcSbModule { Id = module.GetId() }, }); })) { return(response.Result); } return(false); }
public override Task <GetModuleAtIndexResponse> GetModuleAtIndex( GetModuleAtIndexRequest request, ServerCallContext context) { if (!_targetStore.TryGetValue(request.Target.Id, out RemoteTarget target)) { ErrorUtils.ThrowError(StatusCode.Internal, "Could not find target in store: " + request.Target.Id); } var response = new GetModuleAtIndexResponse(); SbModule module = target.GetModuleAtIndex(request.Index); if (module != null) { response.Module = new GrpcSbModule { Id = _moduleStore.AddObject(module) }; } return(Task.FromResult(response)); }
public void SetUp() { _mockCancelableTaskFactory = Substitute.For <CancelableTask.Factory>(); _mockModuleUtil = Substitute.For <ILldbModuleUtil>(); _mockModuleUtil.HasSymbolsLoaded(Arg.Any <SbModule>()).Returns(false); _mockModuleFileLoader = Substitute.For <IModuleFileLoader>(); _mockModuleSearchLogHolder = Substitute.For <IModuleSearchLogHolder>(); _mockModule = Substitute.For <SbModule>(); _mockActionRecorder = Substitute.For <ActionRecorder>(null, null); var mockModuleFileLoadRecorderFactory = Substitute.For <ModuleFileLoadMetricsRecorder.Factory>(); _mockEngineHandler = Substitute.For <IDebugEngineHandler>(); _mockDebugProgram = Substitute.For <IGgpDebugProgram>(); _mockSymbolSettingsProvider = Substitute.For <ISymbolSettingsProvider>(); _debugModule = new DebugModule .Factory(_mockCancelableTaskFactory, _mockActionRecorder, mockModuleFileLoadRecorderFactory, _mockModuleUtil, _mockSymbolSettingsProvider) .Create(_mockModuleFileLoader, _mockModuleSearchLogHolder, _mockModule, _testLoadOrder, _mockEngineHandler, _mockDebugProgram); }
public bool Remove(SbModule lldbModule) { lock (cache) { if (cache.TryGetValue(lldbModule, out IDebugModule3 module)) { cache.Remove(lldbModule); mainThreadDispatcher.Post(() => { try { ModuleRemoved?.Invoke(Self, new ModuleRemovedEventArgs(module)); } catch (Exception e) { Trace.WriteLine( $"Warning: ModuleRemoved handler failed with exception: {e}"); } }); return(true); } return(false); } }
public SbError SetModuleLoadAddress(SbModule module, long sectionsOffset) { throw new NotImplementedTestDoubleException(); }
public bool RemoveModule(SbModule module) { throw new NotImplementedTestDoubleException(); }
async Task AssertLoadSymbolsNotReceivedAsync(SbModule module) { await mockSymbolLoader.DidNotReceive().LoadSymbolsAsync( module, Arg.Any <TextWriter>(), Arg.Any <bool>()); }
async Task AssertLoadBinaryNotReceivedAsync(SbModule module) { await mockBinaryLoader.DidNotReceive().LoadBinaryAsync(module, Arg.Any <TextWriter>()); }
public async Task <int> LoadModuleFilesAsync( IList <SbModule> modules, SymbolInclusionSettings symbolSettings, bool useSymbolStores, ICancelable task, IModuleFileLoadMetricsRecorder moduleFileLoadRecorder) { if (modules == null) { throw new ArgumentNullException(nameof(modules)); } if (task == null) { throw new ArgumentNullException(nameof(task)); } if (moduleFileLoadRecorder == null) { throw new ArgumentNullException(nameof(moduleFileLoadRecorder)); } // Add some metrics to the event proto before attempting to load symbols, so that they // are still recorded if the task is aborted or cancelled. moduleFileLoadRecorder.RecordBeforeLoad(modules); int result = VSConstants.S_OK; for (int i = 0; i < modules.Count; ++i) { SbModule module = modules[i]; TextWriter searchLog = new StringWriter(); string name = module.GetPlatformFileSpec()?.GetFilename() ?? "<unknown>"; try { task.ThrowIfCancellationRequested(); if (SkipModule(name, symbolSettings)) { await searchLog.WriteLineAsync( SymbolInclusionSettings.ModuleExcludedMessage); continue; } task.Progress.Report($"Loading binary for {name} ({i}/{modules.Count})"); (SbModule newModule, bool ok) = await _binaryLoader.LoadBinaryAsync(module, searchLog); if (!ok) { result = VSConstants.E_FAIL; continue; } module = newModule; task.ThrowIfCancellationRequested(); task.Progress.Report($"Loading symbols for {name} ({i}/{modules.Count})"); var loaded = await _symbolLoader.LoadSymbolsAsync(module, searchLog, useSymbolStores); if (!loaded) { result = VSConstants.E_FAIL; continue; } } finally { _moduleSearchLogHolder.SetSearchLog(module, searchLog.ToString()); modules[i] = module; } } moduleFileLoadRecorder.RecordAfterLoad(modules); return(result); }