Пример #1
0
        public void LoadBinary_NullModule()
        {
            SbModule module = null;

            Assert.ThrowsAsync <ArgumentNullException>(
                () => binaryLoader.LoadBinaryAsync(module, searchLog));
        }
Пример #2
0
        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);
        }
Пример #4
0
        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));
        }
Пример #5
0
        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);
        }
Пример #6
0
        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);
            }
        }
Пример #7
0
        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);
        }
Пример #8
0
        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);
        }
Пример #9
0
        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;
        }
Пример #10
0
        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);
        }
Пример #11
0
 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)
            }));
        }
Пример #13
0
        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;
            }
        }
Пример #14
0
        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"));
        }
Пример #15
0
        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"));
        }
Пример #16
0
        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));
        }
Пример #19
0
        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));
        }
Пример #20
0
        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("");
        }
Пример #21
0
 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;
 }
Пример #22
0
        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));
        }
Пример #24
0
        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);
        }
Пример #25
0
 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);
     }
 }
Пример #26
0
 public SbError SetModuleLoadAddress(SbModule module, long sectionsOffset)
 {
     throw new NotImplementedTestDoubleException();
 }
Пример #27
0
 public bool RemoveModule(SbModule module)
 {
     throw new NotImplementedTestDoubleException();
 }
Пример #28
0
 async Task AssertLoadSymbolsNotReceivedAsync(SbModule module)
 {
     await mockSymbolLoader.DidNotReceive().LoadSymbolsAsync(
         module, Arg.Any <TextWriter>(), Arg.Any <bool>());
 }
Пример #29
0
 async Task AssertLoadBinaryNotReceivedAsync(SbModule module)
 {
     await mockBinaryLoader.DidNotReceive().LoadBinaryAsync(module, Arg.Any <TextWriter>());
 }
Пример #30
0
        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);
        }