/// <summary> /// Initialize the node with the id and the callback object /// </summary> internal Node ( int nodeId, LoggerDescription[] nodeLoggers, IEngineCallback parentCallback, BuildPropertyGroup parentGlobalProperties, ToolsetDefinitionLocations toolsetSearchLocations, string parentStartupDirectory ) { this.nodeId = nodeId; this.parentCallback = parentCallback; this.exitNodeEvent = new ManualResetEvent(false); this.buildRequests = new Queue <BuildRequest>(); this.requestToLocalIdMapping = new Hashtable(); this.lastRequestIdUsed = 0; this.centralizedLogging = false; this.nodeLoggers = nodeLoggers; this.localEngine = null; this.launchedEngineLoopThread = false; this.nodeShutdown = false; this.parentGlobalProperties = parentGlobalProperties; this.toolsetSearchLocations = toolsetSearchLocations; this.parentStartupDirectory = parentStartupDirectory; }
public static void AsyncErrorImpl(IEngineCallback engineCallback, IVariableInformation var, IDebugProperty2 error) { Task.Run(() => { engineCallback.OnExpressionEvaluationComplete(var, error); }); }
public DebuggedProcess(IPEndPoint endPoint, IEngineCallback engineCallback, IWorkerThread workerThread, AD7Engine engine) { _engineCallback = engineCallback; WorkerThread = workerThread; Engine = engine; ProcessState = ProcessState.NotConnected; _rokuController = new RokuController(endPoint); _rokuController.OnOutput += RokuControllerOnOutput; _rokuController.OnBackTrace += RokuControllerOnOnBackTrace; _rokuController.OnVariables += RokuControllerOnOnVariables; _rokuController.RunModeEvent += RokuControllerOnRunModeEvent; _rokuController.BreakModeEvent += RokuControllerOnBreakModeEvent; _rokuController.ProcessExitEvent += RokuControllerOnProcessExitEvent; CommandFactory = new CommandFactory(_rokuController); ThreadCache = new ThreadCache(engineCallback, Engine, CommandFactory); // we do NOT have real Win32 process IDs, so we use a guid AD_PROCESS_ID pid = new AD_PROCESS_ID(); pid.ProcessIdType = (int)enum_AD_PROCESS_ID.AD_PROCESS_ID_GUID; pid.guidProcessId = Guid.NewGuid(); this.Id = pid; }
/// <summary> /// Initialize the node with the id and the callback object /// </summary> internal Node ( int nodeId, LoggerDescription[] nodeLoggers, IEngineCallback parentCallback, BuildPropertyGroup parentGlobalProperties, ToolsetDefinitionLocations toolsetSearchLocations, string parentStartupDirectory ) { this.nodeId = nodeId; this.parentCallback = parentCallback; this.exitNodeEvent = new ManualResetEvent(false); this.buildRequests = new Queue<BuildRequest>(); this.requestToLocalIdMapping = new Hashtable(); this.lastRequestIdUsed = 0; this.centralizedLogging = false; this.nodeLoggers = nodeLoggers; this.localEngine = null; this.launchedEngineLoopThread = false; this.nodeShutdown = false; this.parentGlobalProperties = parentGlobalProperties; this.toolsetSearchLocations = toolsetSearchLocations; this.parentStartupDirectory = parentStartupDirectory; }
void INodeProvider.Initialize(string configuration, IEngineCallback engineCallback, BuildPropertyGroup parentGlobalProperties, ToolsetDefinitionLocations toolsetSearchLocations, string startDirectory) { this.initConfiguration = configuration; this.initEngineCallback = engineCallback; this.parentGlobalProperties = parentGlobalProperties; this.toolsetSearchLocations = toolsetSearchLocations; this.startDirectory = startDirectory; }
public ThreadCache(IEngineCallback engineCallback, AD7Engine engine, ICommandFactory commandFactory) { _engineCallback = engineCallback; _engine = engine; _commandFactory = commandFactory; _threadList = new List <DebuggedThread>(); _stackFrames = new Dictionary <int, List <ThreadContext> >(); _topContext = new Dictionary <int, ThreadContext>(); }
// Launches a process by means of the debug engine. // Normally, Visual Studio launches a program using the IDebugPortEx2::LaunchSuspended method and then attaches the debugger // to the suspended program. However, there are circumstances in which the debug engine may need to launch a program // (for example, if the debug engine is part of an interpreter and the program being debugged is an interpreted language), // in which case Visual Studio uses the IDebugEngineLaunch2::LaunchSuspended method // The IDebugEngineLaunch2::ResumeProcess method is called to start the process after the process has been successfully launched in a suspended state. int IDebugEngineLaunch2.LaunchSuspended( string pszServer, IDebugPort2 port, string exe, string args, string dir, string env, string options, enum_LAUNCH_FLAGS launchFlags, uint hStdInput, uint hStdOutput, uint hStdError, IDebugEventCallback2 ad7Callback, out IDebugProcess2 process) { Debug.Assert(_pollThread == null); Debug.Assert(_engineCallback == null); Debug.Assert(_debuggedProcess == null); Debug.Assert(_ad7ProgramId == Guid.Empty); process = null; _engineCallback = new EngineCallback(this, ad7Callback); try { // We are being asked to debug a process when we currently aren't debugging anything _pollThread = new WorkerThread(); _pollThread.RunOperation(() => { var endpoint = new IPEndPoint(IPAddress.Parse(args.Split('=')[1]), 8085); _debuggedProcess = new DebuggedProcess(endpoint, _engineCallback, _pollThread, this); _pollThread.PostedOperationErrorEvent += _debuggedProcess.OnPostedOperationError; return(_debuggedProcess.Initialize()); }); EngineUtils.RequireOk(port.GetProcess(_debuggedProcess.Id, out process)); return(VSConstants.S_OK); } catch (Exception e) when(ExceptionHelper.BeforeCatch(e, reportOnlyCorrupting: true)) { // If we just return the exception as an HRESULT, we will loose our message, so we instead send up an error event, and then // return E_ABORT. SendStartDebuggingError(e); } Dispose(); return(VSConstants.E_ABORT); }
// Attach the debug engine to a program. int IDebugEngine2.Attach(IDebugProgram2[] rgpPrograms, IDebugProgramNode2[] rgpProgramNodes, uint celtPrograms, IDebugEventCallback2 ad7Callback, enum_ATTACH_REASON dwReason) { Debug.Assert(_ad7ProgramId == Guid.Empty); if (celtPrograms != 1) { Debug.Fail("SampleEngine only expects to see one program in a process"); throw new ArgumentException(); } try { AD_PROCESS_ID processId = EngineUtils.GetProcessId(rgpPrograms[0]); EngineUtils.RequireOk(rgpPrograms[0].GetProgramId(out _ad7ProgramId)); // Attach can either be called to attach to a new process, or to complete an attach // to a launched process if (_pollThread == null) { // We are being asked to debug a process when we currently aren't debugging anything _pollThread = new WorkerThread(); _engineCallback = new EngineCallback(this, ad7Callback); _pollThread.PostedOperationErrorEvent += _debuggedProcess.OnPostedOperationError; } else { if (!EngineUtils.ProcIdEquals(processId, _debuggedProcess.Id)) { Debug.Fail("Asked to attach to a process while we are debugging"); return(VSConstants.E_FAIL); } } AD7EngineCreateEvent.Send(this); AD7ProgramCreateEvent.Send(this); this.ProgramCreateEventSent = true; return(VSConstants.S_OK); } catch (MIException e) { return(e.HResult); } catch (Exception e) when(ExceptionHelper.BeforeCatch(e, reportOnlyCorrupting: true)) { return(EngineUtils.UnexpectedException(e)); } }
private void Dispose() { IWorkerThread pollThread = _pollThread; IDebuggedProcess debuggedProcess = _debuggedProcess; _engineCallback?.Close(); _engineCallback = null; _debuggedProcess = null; _pollThread = null; _ad7ProgramId = Guid.Empty; debuggedProcess?.Close(); pollThread?.Close(); }
public void Start(IEngineCallback callback) { engineCallback = callback; try { SetupServerSocket(); for (int i = 0; i < 10; i++) serverSocket.BeginAccept(AcceptCallback, serverSocket); engineCallback.StatusMessage("TCP server started"); } catch (Exception e) { engineCallback.StatusMessage(string.Format("Failed. Exception: {0}", e)); } }
internal override void HostAction(IEngineCallback engineCallback, LocalNodeProvider nodeProvider, int nodeId) { exception = engineCallback.PostCacheEntriesToHost(nodeId, this.entries, this.scopeName, this.scopeProperties, this.scopeToolsVersion, this.cacheContentType); }
internal override void HostAction(IEngineCallback engineCallback, LocalNodeProvider nodeProvider, int nodeId) { nodeProvider.SetNodeProcessId(processId, nodeId); }
internal override void HostAction(IEngineCallback engineCallback, LocalNodeProvider nodeProvider, int nodeId) { engineCallback.PostLoggingMessagesToHost(nodeId, buildEvents); }
/// <summary> /// Appropriate action to take if this event is received on the parent process /// </summary> internal virtual void HostAction(IEngineCallback engineCallback, LocalNodeProvider nodeProvider, int nodeId) { ErrorUtilities.VerifyThrow(false, "This description doesn't support this operation"); }
internal override void HostAction(IEngineCallback engineCallback, LocalNodeProvider nodeProvider, int nodeId) { entries = engineCallback.GetCachedEntriesFromHost(nodeId, this.names, this.scopeName, this.scopeProperties, this.scopeToolsVersion, this.cacheContentType); }
internal override void HostAction(IEngineCallback engineCallback, LocalNodeProvider nodeProvider, int nodeId) { engineCallback.PostStatus(nodeId, nodeStatus, false); }
public void Initialize ( string configuration, IEngineCallback parentEngineCallback, BuildPropertyGroup parentGlobalPropertyGroup, ToolsetDefinitionLocations toolSetSearchLocations, string startupDirectory ) { // Get from the environment how long we should wait in seconds for shutdown to complete string shutdownTimeoutFromEnvironment = Environment.GetEnvironmentVariable("MSBUILDNODESHUTDOWNTIMEOUT"); int result; if (int.TryParse(shutdownTimeoutFromEnvironment, out result) && result >= 0) { shutdownTimeout = result; } this.cpuCount = 1; if (configuration != null) { // Split out the parameter sets based on ; string[] parameters; parameters = configuration.Split(parameterDelimiters); // Go through each of the parameter name value pairs and split them appart for (int param = 0; param < parameters.Length; param++) { if (parameters[param].Length > 0) { string[] parameterComponents = parameters[param].Split(valueDelimiters); // If there is a name and value associated with the parameter, apply the paramter to the provider if (parameterComponents.Length == 2) { ApplyParameter(parameterComponents[0], parameterComponents[1]); } else // Only the parameter name is known, this could be for a boolean parameter { ApplyParameter(parameters[param], null); } } } } /* If we dont get a path passed in as a parameter, we can only assume that our path * is in the current appdomain basedirectory, this is the base directory * that the assembly resolver uses to probe for assemblies */ if (string.IsNullOrEmpty(this.locationOfMSBuildExe)) { this.locationOfMSBuildExe = AppDomain.CurrentDomain.BaseDirectory; } if ((cpuCount - 1) <= 0) { return; } this.exitCommunicationThreads = new ManualResetEvent(false); this.activeNodeCount = 0; this.responseCountChangeEvent = new ManualResetEvent(false); this.nodeStateLock = new object(); this.nodesToLaunch = new Queue <int>(); this.nodeLoggers = new List <LoggerDescription>(); nodeData = new LocalNodeInfo[cpuCount - 1]; // Initialize the internal state indicating that no nodes have been launched int lastUsedNodeNumber = 0; for (int i = 0; i < nodeData.Length; i++) { nodeData[i] = new LocalNodeInfo(lastUsedNodeNumber); lastUsedNodeNumber = nodeData[i].NodeNumber + 1; } // Set up the callback this.engineCallback = parentEngineCallback; this.parentGlobalProperties = parentGlobalPropertyGroup; this.toolsetSearchLocations = toolSetSearchLocations; this.startupDirectory = startupDirectory; // Default node settings centralizedLogging = false; onlyLogCriticalEvents = false; useBreadthFirstTraversal = true; shuttingDown = false; // Start the thread that will be processing the calls from the parent engine ThreadStart threadState = new ThreadStart(this.SharedMemoryWriterThread); Thread taskThread = new Thread(threadState); taskThread.Name = "MSBuild Parent->Child Writer"; taskThread.Start(); threadState = new ThreadStart(this.SharedMemoryReaderThread); taskThread = new Thread(threadState); taskThread.Name = "MSBuild Parent<-Child Reader"; taskThread.Start(); }
internal override void HostAction(IEngineCallback engineCallback, LocalNodeProvider nodeProvider, int nodeId) { engineCallback.PostBuildResultToHost(buildResult); }
internal override void HostAction(IEngineCallback engineCallback, LocalNodeProvider nodeProvider, int nodeId) { nodeProvider.RecordNodeResponse(nodeId, shutdownLevel, totalTaskTime); }
/// <summary> /// Appropriate action to take if this event is received on the parent process /// </summary> internal virtual void HostAction( IEngineCallback engineCallback, LocalNodeProvider nodeProvider, int nodeId ) { ErrorUtilities.VerifyThrow(false, "This description doesn't support this operation"); }
public void Initialize ( string configuration, IEngineCallback parentEngineCallback, BuildPropertyGroup parentGlobalPropertyGroup, ToolsetDefinitionLocations toolSetSearchLocations, string startupDirectory ) { // Get from the environment how long we should wait in seconds for shutdown to complete string shutdownTimeoutFromEnvironment = Environment.GetEnvironmentVariable("MSBUILDNODESHUTDOWNTIMEOUT"); int result; if (int.TryParse(shutdownTimeoutFromEnvironment, out result) && result >= 0) { shutdownTimeout = result; } this.cpuCount = 1; if (configuration != null) { // Split out the parameter sets based on ; string[] parameters; parameters = configuration.Split(parameterDelimiters); // Go through each of the parameter name value pairs and split them appart for (int param = 0; param < parameters.Length; param++) { if (parameters[param].Length > 0) { string[] parameterComponents = parameters[param].Split(valueDelimiters); // If there is a name and value associated with the parameter, apply the paramter to the provider if (parameterComponents.Length == 2) { ApplyParameter(parameterComponents[0], parameterComponents[1]); } else // Only the parameter name is known, this could be for a boolean parameter { ApplyParameter(parameters[param], null); } } } } /* If we dont get a path passed in as a parameter, we can only assume that our path is in the current appdomain basedirectory, this is the base directory that the assembly resolver uses to probe for assemblies */ if (string.IsNullOrEmpty(this.locationOfMSBuildExe)) { this.locationOfMSBuildExe = AppDomain.CurrentDomain.BaseDirectory; } if ( (cpuCount - 1) <= 0) { return; } this.exitCommunicationThreads = new ManualResetEvent(false); this.activeNodeCount = 0; this.responseCountChangeEvent = new ManualResetEvent(false); this.nodeStateLock = new object(); this.nodesToLaunch = new Queue<int>(); this.nodeLoggers = new List<LoggerDescription>(); nodeData = new LocalNodeInfo[cpuCount - 1]; // Initialize the internal state indicating that no nodes have been launched int lastUsedNodeNumber = 0; for (int i = 0; i < nodeData.Length; i++) { nodeData[i] = new LocalNodeInfo(lastUsedNodeNumber); lastUsedNodeNumber = nodeData[i].NodeNumber + 1; } // Set up the callback this.engineCallback = parentEngineCallback; this.parentGlobalProperties = parentGlobalPropertyGroup; this.toolsetSearchLocations = toolSetSearchLocations; this.startupDirectory = startupDirectory; // Default node settings centralizedLogging = false; onlyLogCriticalEvents = false; useBreadthFirstTraversal = true; shuttingDown = false; // Start the thread that will be processing the calls from the parent engine ThreadStart threadState = new ThreadStart(this.SharedMemoryWriterThread); Thread taskThread = new Thread(threadState); taskThread.Name = "MSBuild Parent->Child Writer"; taskThread.Start(); threadState = new ThreadStart(this.SharedMemoryReaderThread); taskThread = new Thread(threadState); taskThread.Name = "MSBuild Parent<-Child Reader"; taskThread.Start(); }