public void SetUp() { _lldbShell = Substitute.For <ILLDBShell>(); _breakpointManager = Substitute.For <IBreakpointManager>(); _moduleFileLoader = Substitute.For <IModuleFileLoader>(); _debugger = Substitute.For <SbDebugger>(); _target = Substitute.For <RemoteTarget>(); _listenerSubscriber = Substitute.For <ILldbListenerSubscriber>(); _process = Substitute.For <SbProcess>(); _debugEngineHandler = Substitute.For <IDebugEngineHandler>(); _taskExecutor = Substitute.For <ITaskExecutor>(); _eventManager = Substitute.For <IEventManager>(); var exceptionManagerFactory = new LldbExceptionManager.Factory(new Dictionary <int, YetiCommon.Signal>()); var exceptionManager = exceptionManagerFactory.Create(_process); _debugModuleCache = Substitute.For <IDebugModuleCache>(); _debugProgram = Substitute.For <IGgpDebugProgram>(); _attachedProgram = new LldbAttachedProgram( _breakpointManager, _eventManager, _lldbShell, _moduleFileLoader, _debugEngineHandler, _taskExecutor, _debugProgram, _debugger, _target, _process, exceptionManager, _debugModuleCache, _listenerSubscriber, _remotePid); }
public void SetUp() { var taskContext = new JoinableTaskContext(); remoteThread = Substitute.For <RemoteThread>(); mockThread = Substitute.For <IDebugThread>(); mockThread.GetRemoteThread().Returns(remoteThread); mockDebugEngineHandler = Substitute.For <IDebugEngineHandler>(); mockDebugThreadCreator = Substitute.For <DebugProgram.ThreadCreator>(); mockDebugDisassemblyStreamFactory = Substitute.For <DebugDisassemblyStream.Factory>(); mockProcess = Substitute.For <IDebugProcess2>(); var guid = new Guid(); mockSbProcess = Substitute.For <SbProcess>(); mockRemoteTarget = Substitute.For <RemoteTarget>(); mockDocumentContextFactory = Substitute.For <DebugDocumentContext.Factory>(); mockCodeContextFactory = Substitute.For <DebugCodeContext.Factory>(); threadEnumFactory = new ThreadEnumFactory(); moduleEnumFactory = new ModuleEnumFactory(); codeContextEnumFactory = new CodeContextEnumFactory(); mockDebugModuleCache = Substitute.For <IDebugModuleCache>(); program = new DebugProgram.Factory(taskContext, mockDebugDisassemblyStreamFactory, mockDocumentContextFactory, mockCodeContextFactory, threadEnumFactory, moduleEnumFactory, codeContextEnumFactory) .Create(mockDebugEngineHandler, mockDebugThreadCreator, mockProcess, guid, mockSbProcess, mockRemoteTarget, mockDebugModuleCache, false); }
DebugProgram( JoinableTaskContext taskContext, ThreadCreator threadCreator, DebugDisassemblyStream.Factory debugDisassemblyStreamFactory, DebugDocumentContext.Factory documentContextFactory, DebugCodeContext.Factory codeContextFactory, ThreadEnumFactory threadEnumFactory, ModuleEnumFactory moduleEnumFactory, CodeContextEnumFactory codeContextEnumFactory, IDebugEngineHandler debugEngineHandler, IDebugProcess2 process, Guid programId, SbProcess lldbProcess, RemoteTarget lldbTarget, IDebugModuleCache debugModuleCache, bool isCoreAttach) { _id = programId; _process = process; _lldbProcess = lldbProcess; _lldbTarget = lldbTarget; _threadCache = new Dictionary <uint, IDebugThread>(); _isCoreAttach = isCoreAttach; _debugEngineHandler = debugEngineHandler; _taskContext = taskContext; _threadCreator = threadCreator; _debugDisassemblyStreamFactory = debugDisassemblyStreamFactory; _documentContextFactory = documentContextFactory; _codeContextFactory = codeContextFactory; _threadEnumFactory = threadEnumFactory; _moduleEnumFactory = moduleEnumFactory; _codeContextEnumFactory = codeContextEnumFactory; _debugModuleCache = debugModuleCache; }
public virtual IEventManager Create(IDebugEngineHandler debugEngineHandler, IBreakpointManager breakpointManager, IGgpDebugProgram program, SbProcess process, LldbListenerSubscriber listenerSubscriber) { return(new LldbEventManager(debugEngineHandler, breakpointManager, _boundBreakpointEnumFactory, program, process, listenerSubscriber, _taskContext)); }
// Get the total number of threads in the thread list. public override Task <GetNumThreadsResponse> GetNumThreads(GetNumThreadsRequest request, ServerCallContext context) { SbProcess sbProcess = GrpcLookupUtils.GetProcess(request.Process, processStore); int numberThreads = sbProcess.GetNumThreads(); return(Task.FromResult(new GetNumThreadsResponse { NumberThreads = numberThreads })); }
public IGgpDebugProgram Create(IDebugEngineHandler debugEngineHandler, ThreadCreator threadCreator, IDebugProcess2 process, Guid programId, SbProcess lldbProcess, RemoteTarget lldbTarget, IDebugModuleCache debugModuleCache, bool isCoreAttach) { return(new DebugProgram(_taskContext, threadCreator, _debugDisassemblyStreamFactory, _documentContextFactory, _codeContextFactory, _threadsEnumFactory, _moduleEnumFactory, _codeContextEnumFactory, debugEngineHandler, process, programId, lldbProcess, lldbTarget, debugModuleCache, isCoreAttach)); }
internal static SbProcess GetProcess(GrpcSbProcess grpcProcess, ConcurrentDictionary <int, SbProcess> processStore) { SbProcess sbProcess = null; if (!processStore.TryGetValue(grpcProcess.Id, out sbProcess)) { ErrorUtils.ThrowError(StatusCode.Internal, "Could not find process in store: " + grpcProcess.Id); } return(sbProcess); }
public override Task <GetTargetResponse> GetTarget(GetTargetRequest request, ServerCallContext context) { SbProcess sbProcess = GrpcLookupUtils.GetProcess(request.Process, processStore); var target = sbProcess.GetTarget(); var grpcSbThread = new GrpcSbTarget { Id = target.GetId() }; return(Task.FromResult(new GetTargetResponse { Target = grpcSbThread })); }
LldbEventManager(IDebugEngineHandler debugEngineHandler, IBreakpointManager breakpointManager, BoundBreakpointEnumFactory boundBreakpointEnumFactory, IGgpDebugProgram program, SbProcess process, LldbListenerSubscriber listenerSubscriber, JoinableTaskContext taskContext) { _debugEngineHandler = debugEngineHandler; _lldbBreakpointManager = breakpointManager; _boundBreakpointEnumFactory = boundBreakpointEnumFactory; _program = program; _lldbProcess = process; _lldbListenerSubscriber = listenerSubscriber; _taskContext = taskContext; }
public void SetUp() { mockTarget = Substitute.For <SbTarget>(); remoteTarget = new RemoteTargetFactory(new RemoteBreakpointFactory()) .Create(mockTarget); mockAddress = Substitute.For <SbAddress>(); mockProcess = Substitute.For <SbProcess>(); mockMemoryRegion = Substitute.For <SbMemoryRegionInfo>(); mockError = Substitute.For <SbError>(); mockBreakpoint = Substitute.For <SbBreakpoint>(); remoteBreakpoint = new RemoteBreakpointFactory().Create(mockBreakpoint); mockFunction = Substitute.For <SbFunction>(); mockTarget.GetProcess().Returns(mockProcess); }
public override Task <LoadCoreResponse> LoadCore(LoadCoreRequest request, ServerCallContext context) { RemoteTarget target = GrpcLookupUtils.GetTarget(request.Target, _targetStore); SbProcess process = target.LoadCore(request.CorePath); var response = new LoadCoreResponse(); if (process != null) { if (!_processStore.TryAdd(process.GetUniqueId(), process)) { ErrorUtils.ThrowError(StatusCode.Internal, "Could not add process to store: " + process.GetUniqueId()); } response.Process = new GrpcSbProcess { Id = process.GetUniqueId() }; } return(Task.FromResult(response)); }
public void SetUp() { _mockSbListener = Substitute.For <SbListener>(); _mockSbProcess = Substitute.For <SbProcess>(); _mockSbEvent = Substitute.For <SbEvent>(); _mockRemoteThread = Substitute.For <RemoteThread>(); _mockBreakpointManager = Substitute.For <IBreakpointManager>(); _mockDebugEngineHandler = Substitute.For <IDebugEngineHandler>(); _mockPendingBreakpoint1 = Substitute.For <IPendingBreakpoint>(); _mockPendingBreakpoint2 = Substitute.For <IPendingBreakpoint>(); _mockBoundBreakpoint1 = Substitute.For <IBoundBreakpoint>(); _mockBoundBreakpoint2 = Substitute.For <IBoundBreakpoint>(); _mockBoundBreakpoint3 = Substitute.For <IBoundBreakpoint>(); _mockWatchpoint = Substitute.For <IWatchpoint>(); _mockProgram = Substitute.For <IGgpDebugProgram>(); MockEvent(EventType.STATE_CHANGED, StateType.STOPPED, false); MockListener(_mockSbEvent, true); MockThread(_mockRemoteThread, StopReason.BREAKPOINT, _breakpointStopData); MockProcess(new List <RemoteThread> { _mockRemoteThread }); MockBreakpointManager(); _mockListenerSubscriber = Substitute.For <LldbListenerSubscriber>(_mockSbListener); var threadContext = new FakeMainThreadContext(); _eventManager = new LldbEventManager .Factory(new BoundBreakpointEnumFactory(), threadContext.JoinableTaskContext) .Create(_mockDebugEngineHandler, _mockBreakpointManager, _mockProgram, _mockSbProcess, _mockListenerSubscriber); var lldbEventManager = _eventManager as LldbEventManager; lldbEventManager?.SubscribeToChanges(); }
public override Task <AttachToProcessWithIDResponse> AttachToProcessWithID( AttachToProcessWithIDRequest 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); } if (!_listenerStore.TryGetValue(request.Listener.Id, out SbListener listener)) { ErrorUtils.ThrowError(StatusCode.Internal, "Could not find listener in store: " + request.Listener.Id); } SbProcess process = target.AttachToProcessWithID(listener, request.Pid, out SbError error); var response = new AttachToProcessWithIDResponse { Error = new GrpcSbError { Success = error.Success(), Error = error.GetCString(), } }; if (process != null) { if (!_processStore.TryAdd(process.GetUniqueId(), process)) { ErrorUtils.ThrowError(StatusCode.Internal, "Could not add process to store: " + process.GetUniqueId()); } response.Process = new GrpcSbProcess { Id = process.GetUniqueId() }; } return(Task.FromResult(response)); }
public LldbAttachedProgram(IBreakpointManager breakpointManager, IEventManager eventManager, ILLDBShell lldbShell, IModuleFileLoader moduleFileLoader, IDebugEngineHandler debugEngineHandler, ITaskExecutor taskExecutor, IGgpDebugProgram debugProgram, SbDebugger debugger, RemoteTarget target, SbProcess process, IExceptionManager exceptionManager, IDebugModuleCache debugModuleCache, ILldbListenerSubscriber listenerSubscriber, uint remotePid) { _debugProgram = debugProgram; _breakpointManager = breakpointManager; _eventManager = eventManager; _lldbShell = lldbShell; _moduleFileLoader = moduleFileLoader; _debugEngineHandler = debugEngineHandler; _taskExecutor = taskExecutor; _debugger = debugger; _target = target; _process = process; _exceptionManager = exceptionManager; _debugModuleCache = debugModuleCache; _listenerSubscriber = listenerSubscriber; RemotePid = remotePid; }
public LldbExceptionManager(SbProcess lldbProcess, IReadOnlyDictionary <int, Signal> defaultSignals) { this.lldbProcess = lldbProcess; this.defaultSignals = defaultSignals; ResetToDefaults(); }
public List <InstructionInfo> ReadInstructionInfos(SbAddress address, uint count, string flavor) { SbProcess process = _sbTarget.GetProcess(); var instructions = new List <InstructionInfo>(); while (instructions.Count < count) { SbMemoryRegionInfo memoryRegion = null; SbError error = process.GetMemoryRegionInfo(address.GetLoadAddress(_sbTarget), out memoryRegion); if (error.Fail()) { Trace.WriteLine("Unable to retrieve memory region info."); return(new List <InstructionInfo>()); } // If the address we are given is not mapped we should not try to disassemble it. if (!memoryRegion.IsMapped()) { uint instructionsLeft = count - (uint)instructions.Count; ulong nextAddress = AddUnmappedInstructions(address, instructionsLeft, memoryRegion, instructions); address = _sbTarget.ResolveLoadAddress(nextAddress); // Continue in case we still need more instructions continue; } List <SbInstruction> sbInstructions = _sbTarget.ReadInstructions(address, count - (uint)instructions.Count, flavor); foreach (SbInstruction sbInstruction in sbInstructions) { SbAddress sbAddress = sbInstruction.GetAddress(); if (sbAddress == null) { // It should never happen that we cannot get an address for an instruction Trace.WriteLine("Unable to retrieve address."); return(new List <InstructionInfo>()); } ulong instructionAddress = sbAddress.GetLoadAddress(_sbTarget); SbSymbol symbol = sbAddress.GetSymbol(); string symbolName = null; // Only set symbolName if it is the start of a function SbAddress startAddress = symbol?.GetStartAddress(); if (startAddress != null && startAddress.GetLoadAddress(_sbTarget) == instructionAddress) { symbolName = symbol.GetName(); } SbLineEntry lineEntry = sbAddress.GetLineEntry(); LineEntryInfo lineEntryInfo = null; if (lineEntry != null) { lineEntryInfo = new LineEntryInfo { FileName = lineEntry.GetFileName(), Directory = lineEntry.GetDirectory(), Line = lineEntry.GetLine(), Column = lineEntry.GetColumn(), }; } // Create a new instruction and fill in the values var instruction = new InstructionInfo { Address = instructionAddress, Operands = sbInstruction.GetOperands(_sbTarget), Comment = sbInstruction.GetComment(_sbTarget), Mnemonic = sbInstruction.GetMnemonic(_sbTarget), SymbolName = symbolName, LineEntry = lineEntryInfo, }; instructions.Add(instruction); } // If we haven't managed to retrieve all the instructions we wanted, add // an invalid instruction and keep going from the next address. if (instructions.Count < count) { ulong nextAddress = AddInvalidInstruction(address, sbInstructions, instructions); // Set the address to the next address after the invalid instruction address = _sbTarget.ResolveLoadAddress(nextAddress); } } return(instructions); }
public ILldbAttachedProgram Create( IDebugProcess2 debugProcess, Guid programId, IDebugEngine2 debugEngine, IDebugEventCallback2 callback, SbDebugger debugger, RemoteTarget target, LldbListenerSubscriber listenerSubscriber, SbProcess process, SbCommandInterpreter commandInterpreter, bool isCoreAttach, IExceptionManager exceptionManager, IModuleSearchLogHolder moduleSearchLogHolder, uint remotePid) { // Required due to an issue triggered by the proxy used to wrap debugProgramFactory. // TODO: Remove assertion once the issue with Castle.DynamicProxy is // fixed. _taskContext.ThrowIfNotOnMainThread(); var debugEngineHandler = _debugEngineHandlerFactory.Create(debugEngine, callback); var binaryLoader = _binaryLoaderFactory.Create(target); var symbolLoader = _symbolLoaderFactory.Create(commandInterpreter); var moduleFileLoader = _moduleFileLoaderFactory.Create(symbolLoader, binaryLoader, moduleSearchLogHolder); var debugModuleCache = _debugModuleCacheFactory.Create( (lldbModule, loadOrder, ggpProgram) => _debugModuleFactory.Create( moduleFileLoader, moduleSearchLogHolder, lldbModule, loadOrder, debugEngineHandler, ggpProgram)); var ad7FrameInfoCreator = new AD7FrameInfoCreator(debugModuleCache); var stackFrameCreator = new StackFramesProvider.StackFrameCreator( (frame, thread, program) => _debugStackFrameCreator( ad7FrameInfoCreator, frame, thread, debugEngineHandler, program)); var threadCreator = new DebugProgram.ThreadCreator( (thread, program) => _debugThreadCreatorDelegate( ad7FrameInfoCreator, stackFrameCreator, thread, program)); var debugProgram = _debugProgramFactory.Create( debugEngineHandler, threadCreator, debugProcess, programId, process, target, debugModuleCache, isCoreAttach); _taskExecutor.StartAsyncTasks( ex => debugEngineHandler.Abort(debugProgram, ExitInfo.Error(ex))); var breakpointManager = _breakpointManagerFactory.Create(debugEngineHandler, debugProgram); var eventManager = _eventManagerFactory.Create(debugEngineHandler, breakpointManager, debugProgram, process, listenerSubscriber); // TODO: Listen for module load/unload events from LLDB binaryLoader.LldbModuleReplaced += (o, args) => { debugModuleCache.GetOrCreate(args.AddedModule, debugProgram); debugModuleCache.Remove(args.RemovedModule); }; debugModuleCache.ModuleAdded += (o, args) => debugEngineHandler.OnModuleLoad(args.Module, debugProgram); debugModuleCache.ModuleRemoved += (o, args) => debugEngineHandler.OnModuleUnload(args.Module, debugProgram); return(new LldbAttachedProgram(breakpointManager, eventManager, _lldbShell, moduleFileLoader, debugEngineHandler, _taskExecutor, debugProgram, debugger, target, process, exceptionManager, debugModuleCache, listenerSubscriber, remotePid)); }
public virtual IExceptionManager Create(SbProcess lldbProcess) { return(new LldbExceptionManager(lldbProcess, defaultSignals)); }
public async Task <ILldbAttachedProgram> LaunchAsync( ICancelable task, IDebugProcess2 process, Guid programId, uint?attachPid, DebuggerOptions.DebuggerOptions debuggerOptions, HashSet <string> libPaths, GrpcConnection grpcConnection, int localDebuggerPort, string targetIpAddress, int targetPort, IDebugEventCallback2 callback) { var launchSucceeded = false; Stopwatch launchTimer = Stopwatch.StartNew(); // This should be the first request to the DebuggerGrpcServer. Providing a retry wait // time allows us to connect to a DebuggerGrpcServer that is slow to start. Note that // we postpone sourcing .lldbinit until we are done with our initialization so that // the users can override our defaults. var lldbDebugger = _lldbDebuggerFactory.Create(grpcConnection, false, TimeSpan.FromSeconds(10)); if (lldbDebugger == null) { throw new AttachException(VSConstants.E_ABORT, ErrorStrings.FailedToCreateDebugger); } if (debuggerOptions[DebuggerOption.CLIENT_LOGGING] == DebuggerOptionState.ENABLED) { lldbDebugger.EnableLog("lldb", new List <string> { "default", "module" }); // TODO: Disable 'dwarf' logs until we can determine why this // causes LLDB to hang. // lldbDebugger.EnableLog("dwarf", new List<string> { "default" }); } if (_fastExpressionEvaluation) { lldbDebugger.EnableFastExpressionEvaluation(); } lldbDebugger.SetDefaultLLDBSettings(); // Apply .lldbinit after we set our settings so that the user can override our // defaults with a custom .lldbinit. LoadLocalLldbInit(lldbDebugger); // Add exec search paths, so that LLDB can find the executable and any dependent // libraries. If LLDB is able to find the files locally, it won't try to download // them from the remote server, saving valuable time on attach. foreach (string path in libPaths) { lldbDebugger.SetLibrarySearchPath(path); } lldbDebugger.SetAsync(true); SbPlatform lldbPlatform; switch (_launchOption) { case LaunchOption.AttachToGame: // Fall through. case LaunchOption.LaunchGame: lldbPlatform = CreateRemotePlatform(grpcConnection, lldbDebugger); if (lldbPlatform == null) { throw new AttachException(VSConstants.E_FAIL, ErrorStrings.FailedToCreateLldbPlatform); } task.ThrowIfCancellationRequested(); Trace.WriteLine("Attempting to connect debugger"); task.Progress.Report("Connecting to debugger"); string connectRemoteUrl = $"{_lldbConnectUrl}:{localDebuggerPort}"; string connectRemoteArgument = CreateConnectRemoteArgument(connectRemoteUrl, targetIpAddress, targetPort); SbPlatformConnectOptions lldbConnectOptions = _lldbPlatformConnectOptionsFactory.Create(connectRemoteArgument); IAction debugerWaitAction = _actionRecorder.CreateToolAction(ActionType.DebugWaitDebugger); bool TryConnectRemote() { if (lldbPlatform.ConnectRemote(lldbConnectOptions).Success()) { return(true); } VerifyGameIsReady(debugerWaitAction); return(false); } try { debugerWaitAction.Record(() => RetryWithTimeout( task, TryConnectRemote, _launchRetryDelay, _launchTimeout, launchTimer)); } catch (TimeoutException e) { throw new AttachException( VSConstants.E_ABORT, ErrorStrings.FailedToConnectDebugger(lldbConnectOptions.GetUrl()), e); } Trace.WriteLine("LLDB successfully connected"); break; case LaunchOption.AttachToCore: lldbPlatform = _lldbPlatformFactory.Create(_localLldbPlatformName, grpcConnection); if (lldbPlatform == null) { throw new AttachException(VSConstants.E_FAIL, ErrorStrings.FailedToCreateLldbPlatform); } break; default: throw new AttachException(VSConstants.E_ABORT, ErrorStrings.InvalidLaunchOption( _launchOption.ToString())); } lldbDebugger.SetSelectedPlatform(lldbPlatform); task.ThrowIfCancellationRequested(); task.Progress.Report("Debugger is attaching (this can take a while)"); RemoteTarget lldbTarget = null; if (_launchOption == LaunchOption.LaunchGame && !string.IsNullOrEmpty(_executableFullPath)) { var createExecutableTargetAction = _actionRecorder.CreateToolAction(ActionType.DebugCreateExecutableTarget); createExecutableTargetAction.Record( () => lldbTarget = CreateTarget(lldbDebugger, _executableFullPath)); } else { lldbTarget = CreateTarget(lldbDebugger, ""); } var lldbListener = CreateListener(grpcConnection); // This is required to catch breakpoint change events. lldbTarget.AddListener(lldbListener, EventType.STATE_CHANGED); var listenerSubscriber = new LldbListenerSubscriber(lldbListener); var eventHandler = new EventHandler <FileUpdateReceivedEventArgs>( (s, e) => ListenerSubscriberOnFileUpdateReceived(task, e)); listenerSubscriber.FileUpdateReceived += eventHandler; listenerSubscriber.Start(); try { if (_launchOption == LaunchOption.AttachToCore) { var loadCoreAction = _actionRecorder.CreateToolAction(ActionType.DebugLoadCore); SbProcess lldbDebuggerProcess = null; loadCoreAction.Record(() => lldbDebuggerProcess = LoadCore(lldbTarget, loadCoreAction)); await _taskContext.Factory.SwitchToMainThreadAsync(); return(_attachedProgramFactory.Create( process, programId, _debugEngine, callback, lldbDebugger, lldbTarget, listenerSubscriber, lldbDebuggerProcess, lldbDebugger.GetCommandInterpreter(), true, new NullExceptionManager(), _moduleSearchLogHolder, remotePid: 0)); } // Get process ID. uint processId = 0; switch (_launchOption) { case LaunchOption.AttachToGame: if (!attachPid.HasValue) { throw new AttachException(VSConstants.E_ABORT, ErrorStrings.FailedToRetrieveProcessId); } processId = attachPid.Value; break; case LaunchOption.LaunchGame: // Since we have no way of knowing when the remote process actually // starts, try a few times to get the pid. IAction debugWaitAction = _actionRecorder.CreateToolAction(ActionType.DebugWaitProcess); bool TryGetRemoteProcessId() { if (GetRemoteProcessId(_executableFileName, lldbPlatform, out processId)) { return(true); } VerifyGameIsReady(debugWaitAction); return(false); } try { debugWaitAction.Record(() => RetryWithTimeout( task, TryGetRemoteProcessId, _launchRetryDelay, _launchTimeout, launchTimer)); } catch (TimeoutException e) { throw new AttachException(VSConstants.E_ABORT, ErrorStrings.FailedToRetrieveProcessId, e); } break; } Trace.WriteLine("Attaching to pid " + processId); var debugAttachAction = _actionRecorder.CreateToolAction(ActionType.DebugAttach); SbProcess debuggerProcess = null; debugAttachAction.Record(() => { var moduleFileLoadRecorder = _moduleFileLoadRecorderFactory.Create(debugAttachAction); moduleFileLoadRecorder.RecordBeforeLoad(Array.Empty <SbModule>()); debuggerProcess = lldbTarget.AttachToProcessWithID(lldbListener, processId, out SbError lldbError); if (lldbError.Fail()) { throw new AttachException( VSConstants.E_ABORT, GetLldbAttachErrorDetails(lldbError, lldbPlatform, processId)); } RecordModules(lldbTarget, moduleFileLoadRecorder); }); var exceptionManager = _exceptionManagerFactory.Create(debuggerProcess); await _taskContext.Factory.SwitchToMainThreadAsync(); ILldbAttachedProgram attachedProgram = _attachedProgramFactory.Create( process, programId, _debugEngine, callback, lldbDebugger, lldbTarget, listenerSubscriber, debuggerProcess, lldbDebugger.GetCommandInterpreter(), false, exceptionManager, _moduleSearchLogHolder, processId); launchSucceeded = true; return(attachedProgram); } finally { // clean up the SBListener subscriber listenerSubscriber.FileUpdateReceived -= eventHandler; // stop the SBListener subscriber completely if the game failed to launch if (!launchSucceeded) { listenerSubscriber.Stop(); } } }
SbProcess LoadCore(RemoteTarget lldbTarget, IAction loadCoreAction) { var moduleFileLoadRecorder = _moduleFileLoadRecorderFactory.Create(loadCoreAction); moduleFileLoadRecorder.RecordBeforeLoad(Array.Empty <SbModule>()); bool isFullDump = _coreFilePath.EndsWith(".core"); if (isFullDump) { string combinedPath = _taskContext.Factory.Run(async() => { await _taskContext.Factory.SwitchToMainThreadAsync(); _symbolSettingsProvider.GetStorePaths(out string paths, out string cache); return(SymbolUtils.GetCombinedLookupPaths(paths, cache)); }); _moduleFileFinder.SetSearchPaths(combinedPath); TextWriter searchLog = new StringWriter(); DumpReadResult dump = _dumpModulesProvider.GetModules(_coreFilePath); DumpModule[] executableModules = dump.Modules.Where(module => module.IsExecutable).ToArray(); DumpModule[] nonExecutableModules = dump.Modules.Where(module => !module.IsExecutable).ToArray(); // We should not pre-load non executable modules if there wasn't any successfully // loaded executable modules. Otherwise lldb will not upgrade image list during the // attachment to the core dump and will try to resolve the executable on the // developer machine. See (internal) if (executableModules.Any() && executableModules.All(module => TryPreloadModule(lldbTarget, searchLog, module))) { foreach (DumpModule module in nonExecutableModules) { TryPreloadModule(lldbTarget, searchLog, module); } } if (dump.Warning == DumpReadWarning.None && !executableModules.Any()) { dump.Warning = DumpReadWarning.ExecutableBuildIdMissing; } if (dump.Warning != DumpReadWarning.None) { var shouldAttach = _taskContext.Factory.Run( async() => await _warningDialog.ShouldAttachToIncosistentCoreFileAsync( dump.Warning)); if (!shouldAttach) { throw new CoreAttachStoppedException(); } } } SbProcess lldbDebuggerProcess = lldbTarget.LoadCore(_coreFilePath); if (lldbDebuggerProcess == null) { throw new AttachException(VSConstants.E_ABORT, ErrorStrings.FailedToLoadCore(_coreFilePath)); } RecordModules(lldbTarget, moduleFileLoadRecorder); return(lldbDebuggerProcess); }