private IDebugProcess2 GetProcess(IDebugPort2 port) { IDebugProcess2 process; EngineUtils.CheckOk(port.GetProcess(_processId, out process)); return(process); }
public MonoPendingBreakpoint(MonoBreakpointManager breakpointManager, IDebugBreakpointRequest2 request) { this.breakpointManager = breakpointManager; this.request = request; var requestInfo = new BP_REQUEST_INFO[1]; EngineUtils.CheckOk(request.GetRequestInfo(enum_BPREQI_FIELDS.BPREQI_BPLOCATION, requestInfo)); this.requestInfo = requestInfo[0]; }
public AD7PendingBreakpoint(IDebugBreakpointRequest2 pBPRequest, AD7Engine engine, BreakpointManager bpManager) { m_pBPRequest = pBPRequest; BP_REQUEST_INFO[] requestInfo = new BP_REQUEST_INFO[1]; EngineUtils.CheckOk(m_pBPRequest.GetRequestInfo(enum_BPREQI_FIELDS.BPREQI_BPLOCATION, requestInfo)); mBpRequestInfo = requestInfo[0]; EngineUtils.CheckOk(m_pBPRequest.GetRequestInfo(enum_BPREQI_FIELDS.BPREQI_THREAD, requestInfo)); mEngine = engine; mBPMgr = bpManager; }
public string GetLocationInfo(IDebugDocumentPosition2 docPosition, out TEXT_POSITION[] startPosition, out TEXT_POSITION[] endPosition) { string documentName; EngineUtils.CheckOk(docPosition.GetFileName(out documentName)); startPosition = new TEXT_POSITION[1]; endPosition = new TEXT_POSITION[1]; EngineUtils.CheckOk(docPosition.GetRange(startPosition, endPosition)); return(documentName); }
public AD7PendingBreakpoint(IDebugBreakpointRequest2 pBPRequest, AD7Engine engine, BreakpointManager bpManager) { _bpRequest = pBPRequest; BP_REQUEST_INFO[] requestInfo = new BP_REQUEST_INFO[1]; EngineUtils.CheckOk(_bpRequest.GetRequestInfo(enum_BPREQI_FIELDS.BPREQI_BPLOCATION | enum_BPREQI_FIELDS.BPREQI_CONDITION | enum_BPREQI_FIELDS.BPREQI_ALLFIELDS, requestInfo)); _bpRequestInfo = requestInfo[0]; _engine = engine; _bpManager = bpManager; _boundBreakpoints = new System.Collections.Generic.List <AD7BoundBreakpoint>(); _enabled = true; _deleted = false; }
// Get the document context for this pending breakpoint. A document context is a abstract representation of a source file // location. public AD7DocumentContext GetDocumentContext(PythonBreakpoint address) { IDebugDocumentPosition2 docPosition = (IDebugDocumentPosition2)(Marshal.GetObjectForIUnknown(_bpRequestInfo.bpLocation.unionmember2)); EngineUtils.CheckOk(docPosition.GetFileName(out global::System.String documentName)); // Get the location in the document that the breakpoint is in. TEXT_POSITION[] startPosition = new TEXT_POSITION[1]; TEXT_POSITION[] endPosition = new TEXT_POSITION[1]; EngineUtils.CheckOk(docPosition.GetRange(startPosition, endPosition)); AD7MemoryAddress codeContext = new AD7MemoryAddress(_engine, documentName, startPosition[0].dwLine); return(new AD7DocumentContext(documentName, startPosition[0], startPosition[0], codeContext, FrameKind.Python)); }
// Get the document context for this pending breakpoint. A document context is a abstract representation of a source file // location. public AD7DocumentContext GetDocumentContext(uint address) { IDebugDocumentPosition2 docPosition = (IDebugDocumentPosition2)(Marshal.GetObjectForIUnknown(mBpRequestInfo.bpLocation.unionmember2)); string documentName; EngineUtils.CheckOk(docPosition.GetFileName(out documentName)); // Get the location in the document that the breakpoint is in. TEXT_POSITION[] startPosition = new TEXT_POSITION[1]; TEXT_POSITION[] endPosition = new TEXT_POSITION[1]; EngineUtils.CheckOk(docPosition.GetRange(startPosition, endPosition)); AD7MemoryAddress codeContext = new AD7MemoryAddress(mEngine, address); return(new AD7DocumentContext(documentName, startPosition[0], startPosition[0], codeContext)); }
// Get the document context for this pending breakpoint. A document context is a abstract representation of a source file // location. public AD7DocumentContext GetDocumentContext(ulong address, string functionName) { IDebugDocumentPosition2 docPosition = HostMarshal.GetDocumentPositionForIntPtr(_bpRequestInfo.bpLocation.unionmember2); string documentName; EngineUtils.CheckOk(docPosition.GetFileName(out documentName)); // Get the location in the document that the breakpoint is in. TEXT_POSITION[] startPosition = new TEXT_POSITION[1]; TEXT_POSITION[] endPosition = new TEXT_POSITION[1]; EngineUtils.CheckOk(docPosition.GetRange(startPosition, endPosition)); AD7MemoryAddress codeContext = new AD7MemoryAddress(_engine, address, functionName); return(new AD7DocumentContext(new MITextPosition(documentName, startPosition[0], startPosition[0]), codeContext)); }
public int LaunchSuspended(string server, IDebugPort2 port, string exe, string args, string directory, string environment, string options, enum_LAUNCH_FLAGS launchFlags, uint standardInput, uint standardOutput, uint standardError, IDebugEventCallback2 callback, out IDebugProcess2 process) { processId = new AD_PROCESS_ID(); processId.ProcessIdType = (uint)enum_AD_PROCESS_ID.AD_PROCESS_ID_GUID; processId.guidProcessId = Guid.NewGuid(); EngineUtils.CheckOk(port.GetProcess(processId, out process)); this.Callback = callback; Session = new SoftDebuggerSession(); Session.TargetReady += (sender, eventArgs) => { var activeThread = Session.ActiveThread; threadManager.Add(activeThread, new MonoThread(this, activeThread)); /* * Session.Stop(); * var location = activeThread.Location; * var backtrace = activeThread.Backtrace; * var locations = Session.VirtualMachine.RootDomain.GetAssemblies().Select(x => x.Location).ToArray(); * Session.Continue(); */ MonoEngineCreateEvent.Send(this); MonoProgramCreateEvent.Send(this); }; Session.ExceptionHandler = exception => true; Session.TargetExceptionThrown += (sender, x) => Console.WriteLine(x.Type); Session.TargetExited += (sender, x) => Send(new MonoProgramDestroyEvent((uint?)x.ExitCode ?? 0), MonoProgramDestroyEvent.IID, null); Session.TargetUnhandledException += (sender, x) => Console.WriteLine(x.Type); Session.LogWriter = (stderr, text) => Console.WriteLine(text); Session.OutputWriter = (stderr, text) => Console.WriteLine(text); Session.TargetThreadStarted += (sender, x) => threadManager.Add(x.Thread, new MonoThread(this, x.Thread)); Session.TargetThreadStopped += (sender, x) => threadManager.Remove(x.Thread); Session.TargetStopped += (sender, x) => Console.WriteLine(x.Type); Session.TargetStarted += (sender, x) => Console.WriteLine(); Session.TargetSignaled += (sender, x) => Console.WriteLine(x.Type); Session.TargetInterrupted += (sender, x) => Console.WriteLine(x.Type); Session.TargetHitBreakpoint += (sender, x) => { var breakpoint = x.BreakEvent as Breakpoint; var pendingBreakpoint = breakpointManager[breakpoint]; Send(new MonoBreakpointEvent(new MonoBoundBreakpointsEnum(pendingBreakpoint.BoundBreakpoints)), MonoBreakpointEvent.IID, threadManager[x.Thread]); }; return(VSConstants.S_OK); }
public MonoDocumentContext GetDocumentContext(uint address) { var docPosition = (IDebugDocumentPosition2)Marshal.GetObjectForIUnknown(requestInfo.bpLocation.unionmember2); string documentName; EngineUtils.CheckOk(docPosition.GetFileName(out documentName)); // Get the location in the document that the breakpoint is in. var startPosition = new TEXT_POSITION[1]; var endPosition = new TEXT_POSITION[1]; EngineUtils.CheckOk(docPosition.GetRange(startPosition, endPosition)); MonoMemoryAddress codeContext = new MonoMemoryAddress(breakpointManager.Engine, address, null); return(new MonoDocumentContext(documentName, startPosition[0], endPosition[0], codeContext)); }
public AD7PendingBreakpoint(IDebugBreakpointRequest2 pBPRequest, AD7Engine engine, BreakpointManager bpManager) { _pBPRequest = pBPRequest; BP_REQUEST_INFO[] requestInfo = new BP_REQUEST_INFO[1]; EngineUtils.CheckOk(_pBPRequest.GetRequestInfo(enum_BPREQI_FIELDS.BPREQI_BPLOCATION | enum_BPREQI_FIELDS.BPREQI_CONDITION | enum_BPREQI_FIELDS.BPREQI_PASSCOUNT, requestInfo)); _bpRequestInfo = requestInfo[0]; _engine = engine; _bpManager = bpManager; _boundBreakpoints = new List <AD7BoundBreakpoint>(); _enabled = true; _deleted = false; _pendingDelete = false; _bp = null; // no underlying breakpoint created yet _BPError = null; }
// Binds this pending breakpoint to one or more code locations. int IDebugPendingBreakpoint2.Bind() { if (CanBind()) { var docPosition = (IDebugDocumentPosition2)(Marshal.GetObjectForIUnknown(_bpRequestInfo.bpLocation.unionmember2)); // Get the name of the document that the breakpoint was put in string documentName; EngineUtils.CheckOk(docPosition.GetFileName(out documentName)); // Get the location in the document that the breakpoint is in. var startPosition = new TEXT_POSITION[1]; var endPosition = new TEXT_POSITION[1]; EngineUtils.CheckOk(docPosition.GetRange(startPosition, endPosition)); _breakpoint = new NodeBreakpoint(_engine.Process.Debugger, documentName, (int)startPosition[0].dwLine, (int)startPosition[0].dwColumn, _bpRequestInfo.bpCondition.bstrCondition); try { _engine.Process.Debugger.AddBreakpointAsync(_breakpoint).Wait(); } catch (Exception) { return(VSConstants.E_FAIL); } var breakpointResolution = new AD7BreakpointResolution(_engine, _breakpoint, GetDocumentContext(_breakpoint)); var boundBreakpoint = new AD7BoundBreakpoint(_engine, _breakpoint, this, breakpointResolution); _boundBreakpoints.Add(boundBreakpoint); _bpManager.AddBoundBreakpoint(_breakpoint, boundBreakpoint); return(VSConstants.S_OK); } // The breakpoint could not be bound. This may occur for many reasons such as an invalid location, an invalid expression, etc... // The sample engine does not support this, but a real world engine will want to send an instance of IDebugBreakpointErrorEvent2 to the // UI and return a valid instance of IDebugErrorBreakpoint2 from IDebugPendingBreakpoint2::EnumErrorBreakpoints. The debugger will then // display information about why the breakpoint did not bind to the user. return(VSConstants.S_FALSE); }
// Enumerates the code contexts for a given position in a source file. public int EnumCodeContexts(IDebugDocumentPosition2 pDocPos, out IEnumDebugCodeContexts2 ppEnum) { string documentName; EngineUtils.CheckOk(pDocPos.GetFileName(out documentName)); // Get the location in the document TEXT_POSITION[] startPosition = new TEXT_POSITION[1]; TEXT_POSITION[] endPosition = new TEXT_POSITION[1]; EngineUtils.CheckOk(pDocPos.GetRange(startPosition, endPosition)); List <IDebugCodeContext2> codeContexts = new List <IDebugCodeContext2>(); List <ulong> addresses = null; uint line = startPosition[0].dwLine + 1; _debuggedProcess.WorkerThread.RunOperation(async() => { addresses = await DebuggedProcess.StartAddressesForLine(documentName, line); }); if (addresses != null && addresses.Count > 0) { foreach (var a in addresses) { var codeCxt = new AD7MemoryAddress(this, a, null); TEXT_POSITION pos; pos.dwLine = line; pos.dwColumn = 0; MITextPosition textPosition = new MITextPosition(documentName, pos, pos); codeCxt.SetDocumentContext(new AD7DocumentContext(textPosition, codeCxt)); codeContexts.Add(codeCxt); } if (codeContexts.Count > 0) { ppEnum = new AD7CodeContextEnum(codeContexts.ToArray()); return(VSConstants.S_OK); } } ppEnum = null; return(VSConstants.E_FAIL); }
public int Bind() { var docPosition = (IDebugDocumentPosition2)Marshal.GetObjectForIUnknown(requestInfo.bpLocation.unionmember2); string documentName; EngineUtils.CheckOk(docPosition.GetFileName(out documentName)); // Remap document name TODO: Implement this properly const string localRoot = @"C:/dev/TestDebug/TestDebug"; documentName = documentName.Replace('\\', '/'); const string remoteRoot = @"/mnt/c/dev/TestDebug/TestDebug"; documentName = remoteRoot + documentName.Substring(localRoot.Length); var startPosition = new TEXT_POSITION[1]; var endPosition = new TEXT_POSITION[1]; EngineUtils.CheckOk(docPosition.GetRange(startPosition, endPosition)); var engine = breakpointManager.Engine; breakpoint = engine.Session.Breakpoints.Add(documentName, (int)startPosition[0].dwLine + 1, (int)startPosition[0].dwColumn + 1); breakpointManager.Add(breakpoint, this); SetCondition(requestInfo.bpCondition); SetPassCount(requestInfo.bpPassCount); lock (boundBreakpoints) { uint address = 0; var breakpointResolution = new MonoBreakpointResolution(engine, address, GetDocumentContext(address)); var boundBreakpoint = new MonoBoundBreakpoint(engine, address, this, breakpointResolution); boundBreakpoints.Add(boundBreakpoint); engine.Send(new MonoBreakpointBoundEvent(this, boundBreakpoint), MonoBreakpointBoundEvent.IID, null); } return(VSConstants.S_OK); }
public int LaunchSuspended(string server, IDebugPort2 port, string exe, string args, string directory, string environment, string options, enum_LAUNCH_FLAGS launchFlags, uint standardInput, uint standardOutput, uint standardError, IDebugEventCallback2 callback, out IDebugProcess2 process) { waiter = new AutoResetEvent(false); settings = MonoDebuggerSettings.Parse(options); Task.Run(() => { var outputWindow = (IVsOutputWindow)Microsoft.VisualStudio.Shell.Package.GetGlobalService(typeof(SVsOutputWindow)); var generalPaneGuid = VSConstants.GUID_OutWindowDebugPane; outputWindow.GetPane(ref generalPaneGuid, out this.outputWindow); // Upload the contents of the output folder to the target directory if (connection == null) { connection = ConnectionManager.Get(settings); if (!connection.IsConnected) { Log("Connecting SSH and SFTP..."); // Debugger.Launch(); connection.Connect(); Log("Connected"); } } Log("Uploading program..."); // Ensure target directory exists: var targetDirectories = directory.Split('/'); foreach (var part in targetDirectories) { if (!connection.Sftp.Exists(part)) { connection.Sftp.CreateDirectory(part); } connection.Sftp.ChangeDirectory(part); } foreach (var _ in targetDirectories) { connection.Sftp.ChangeDirectory(".."); } var outputDirectory = new DirectoryInfo(Path.GetDirectoryName(exe)); foreach (var file in outputDirectory.EnumerateFiles().Where(x => x.Extension == ".dll" || x.Extension == ".mdb" || x.Extension == ".exe")) { using (var stream = file.OpenRead()) { connection.Sftp.UploadFile(stream, $"{directory}/{file.Name}", true); } Log($"Uploaded {file.FullName}"); } Log("Done"); var targetExe = directory + "/" + Path.GetFileName(exe); connection.Ssh.RunCommand("cd ~"); Log("Launching application"); var commandText = $"mono --debug=mdb-optimizations --debugger-agent=transport=dt_socket,address=0.0.0.0:6438,server=y {targetExe}"; connection.Ssh.RunCommand("kill $(ps auxww | grep '" + commandText + "' | awk '{print $2}')", this.outputWindow, null); runCommand = connection.Ssh.BeginCommand(commandText, this.outputWindow, out runCommandAsyncResult); // Trigger that the app is now running for whomever might be waiting for that signal waiter.Set(); }); Session = new SoftDebuggerSession(); Session.TargetReady += (sender, eventArgs) => { var activeThread = Session.ActiveThread; ThreadManager.Add(activeThread, new MonoThread(this, activeThread)); // Session.Stop(); }; Session.ExceptionHandler = exception => true; Session.TargetExited += (sender, x) => { // runCommand.EndExecute(runCommandAsyncResult); Send(new MonoProgramDestroyEvent((uint?)x.ExitCode ?? 0), MonoProgramDestroyEvent.IID, null); }; Session.TargetUnhandledException += (sender, x) => { Send(new MonoExceptionEvent(x.Backtrace.GetFrame(0)) { IsUnhandled = true }, MonoExceptionEvent.IID, ThreadManager[x.Thread]); }; Session.LogWriter = (stderr, text) => Console.WriteLine(text); Session.OutputWriter = (stderr, text) => Console.WriteLine(text); Session.TargetThreadStarted += (sender, x) => ThreadManager.Add(x.Thread, new MonoThread(this, x.Thread)); Session.TargetThreadStopped += (sender, x) => { ThreadManager.Remove(x.Thread); }; Session.TargetStopped += (sender, x) => Console.WriteLine(x.Type); Session.TargetStarted += (sender, x) => Console.WriteLine(); Session.TargetSignaled += (sender, x) => Console.WriteLine(x.Type); Session.TargetInterrupted += (sender, x) => Console.WriteLine(x.Type); Session.TargetExceptionThrown += (sender, x) => { Send(new MonoExceptionEvent(x.Backtrace.GetFrame(0)), MonoExceptionEvent.IID, ThreadManager[x.Thread]); }; Session.TargetHitBreakpoint += (sender, x) => { var breakpoint = x.BreakEvent as Breakpoint; var pendingBreakpoint = breakpointManager[breakpoint]; Send(new MonoBreakpointEvent(new MonoBoundBreakpointsEnum(pendingBreakpoint.BoundBreakpoints)), MonoBreakpointEvent.IID, ThreadManager[x.Thread]); }; processId = new AD_PROCESS_ID(); processId.ProcessIdType = (uint)enum_AD_PROCESS_ID.AD_PROCESS_ID_GUID; processId.guidProcessId = Guid.NewGuid(); EngineUtils.CheckOk(port.GetProcess(processId, out process)); Callback = callback; return(VSConstants.S_OK); }
internal async Task BindAsync() { if (CanBind()) { string documentName = null; string functionName = null; TEXT_POSITION[] startPosition = new TEXT_POSITION[1]; TEXT_POSITION[] endPosition = new TEXT_POSITION[1]; string condition = null; lock (_boundBreakpoints) { if (_bp != null) // already bound { Debug.Fail("Breakpoint already bound"); return; } if ((_bpRequestInfo.dwFields & enum_BPREQI_FIELDS.BPREQI_BPLOCATION) != 0) { if (_bpRequestInfo.bpLocation.bpLocationType == (uint)enum_BP_LOCATION_TYPE.BPLT_CODE_FUNC_OFFSET) { IDebugFunctionPosition2 functionPosition = HostMarshal.GetDebugFunctionPositionForIntPtr(_bpRequestInfo.bpLocation.unionmember2); EngineUtils.CheckOk(functionPosition.GetFunctionName(out functionName)); } else if (_bpRequestInfo.bpLocation.bpLocationType == (uint)enum_BP_LOCATION_TYPE.BPLT_CODE_FILE_LINE) { IDebugDocumentPosition2 docPosition = HostMarshal.GetDocumentPositionForIntPtr(_bpRequestInfo.bpLocation.unionmember2); // Get the name of the document that the breakpoint was put in EngineUtils.CheckOk(docPosition.GetFileName(out documentName)); // Get the location in the document that the breakpoint is in. EngineUtils.CheckOk(docPosition.GetRange(startPosition, endPosition)); } } if ((_bpRequestInfo.dwFields & enum_BPREQI_FIELDS.BPREQI_CONDITION) != 0 && _bpRequestInfo.bpCondition.styleCondition == enum_BP_COND_STYLE.BP_COND_WHEN_TRUE) { condition = _bpRequestInfo.bpCondition.bstrCondition; } } PendingBreakpoint.BindResult bindResult; // Bind all breakpoints that match this source and line number. if (documentName != null) { bindResult = await PendingBreakpoint.Bind(documentName, startPosition[0].dwLine + 1, startPosition[0].dwColumn, _engine.DebuggedProcess, condition, this); } else { bindResult = await PendingBreakpoint.Bind(functionName, _engine.DebuggedProcess, condition, this); } lock (_boundBreakpoints) { if (bindResult.PendingBreakpoint != null) { _bp = bindResult.PendingBreakpoint; // an MI breakpoint object exists: TODO: lock? } if (bindResult.BoundBreakpoints == null || bindResult.BoundBreakpoints.Count == 0) { _BPError = new AD7ErrorBreakpoint(this, bindResult.ErrorMessage); _engine.Callback.OnBreakpointError(_BPError); } else { Debug.Assert(_bp != null); foreach (BoundBreakpoint bp in bindResult.BoundBreakpoints) { AddBoundBreakpoint(bp); } } } } }
// Binds this pending breakpoint to one or more code locations. int IDebugPendingBreakpoint2.Bind() { try { if (CanBind()) { var xDocPos = (IDebugDocumentPosition2)(Marshal.GetObjectForIUnknown(mBpRequestInfo.bpLocation.unionmember2)); // Get the name of the document that the breakpoint was put in string xDocName; EngineUtils.CheckOk(xDocPos.GetFileName(out xDocName)); xDocName = xDocName.ToLower(); //Bug: Some filenames were returned with the drive letter as lower case but in DocumentGUIDs it was captialised so file-not-found! // Get the location in the document that the breakpoint is in. var xStartPos = new TEXT_POSITION[1]; var xEndPos = new TEXT_POSITION[1]; EngineUtils.CheckOk(xDocPos.GetRange(xStartPos, xEndPos)); uint xAddress = 0; var xDebugInfo = mEngine.mProcess.mDebugInfoDb; // We must check for DocID. This is important because in a solution that contains many projects, // VS will send us BPs from other Cosmos projects (and possibly non Cosmos ones, didnt look that deep) // but we wont have them in our doc list because it contains only ones from the currently project // to run. long xDocID; if (xDebugInfo.DocumentGUIDs.TryGetValue(xDocName, out xDocID)) { // Find which Method the Doc, Line, Col are in. // Must add +1 for both Line and Col. They are 0 based, while SP ones are 1 based. // () around << are VERY important.. + has precedence over << long xPos = (((long)xStartPos[0].dwLine + 1) << 32) + xStartPos[0].dwColumn + 1; try { var xMethod = xDebugInfo.GetMethodByDocumentIDAndLinePosition(xDocID, xPos, xPos); var asm = xDebugInfo.GetAssemblyFileById(xMethod.AssemblyFileID); // We have the method. Now find out what Sequence Point it belongs to. var xSPs = xDebugInfo.GetSequencePoints(asm.Pathname, xMethod.MethodToken); var xSP = xSPs.Single(q => q.LineColStart <= xPos && q.LineColEnd >= xPos); // We have the Sequence Point, find the MethodILOp var xOp = xDebugInfo.GetFirstMethodIlOpByMethodIdAndILOffset(xMethod.ID, xSP.Offset); // Get the address of the Label xAddress = xDebugInfo.GetAddressOfLabel(xOp.LabelName); if (xAddress > 0) { var xBPR = new AD7BreakpointResolution(mEngine, xAddress, GetDocumentContext(xAddress)); var xBBP = new AD7BoundBreakpoint(mEngine, xAddress, this, xBPR); mBoundBPs.Add(xBBP); } // Ask the symbol engine to find all addresses in all modules with symbols that match this source and line number. //uint[] addresses = mEngine.DebuggedProcess.GetAddressesForSourceLocation(null, documentName, startPosition[0].dwLine + 1, startPosition[0].dwColumn); lock (mBoundBPs) { //foreach (uint addr in addresses) { // AD7BreakpointResolution breakpointResolution = new AD7BreakpointResolution(mEngine, addr, GetDocumentContext(addr)); // AD7BoundBreakpoint boundBreakpoint = new AD7BoundBreakpoint(mEngine, addr, this, breakpointResolution); // m_boundBreakpoints.Add(boundBreakpoint); // mEngine.DebuggedProcess.SetBreakpoint(addr, boundBreakpoint); //} } } catch (InvalidOperationException) { //No elements in potXMethods sequence! return(VSConstants.S_FALSE); } } return(VSConstants.S_OK); } else { // The breakpoint could not be bound. This may occur for many reasons such as an invalid location, an invalid expression, etc... // The sample engine does not support this, but a real world engine will want to send an instance of IDebugBreakpointErrorEvent2 to the // UI and return a valid instance of IDebugErrorBreakpoint2 from IDebugPendingBreakpoint2::EnumErrorBreakpoints. The debugger will then // display information about why the breakpoint did not bind to the user. return(VSConstants.S_FALSE); } } //catch (ComponentException e) //{ // return e.HResult; //} catch (Exception e) { return(EngineUtils.UnexpectedException(e)); } }
public int LaunchSuspended(string server, IDebugPort2 port, string exe, string args, string directory, string environment, string options, enum_LAUNCH_FLAGS launchFlags, uint standardInput, uint standardOutput, uint standardError, IDebugEventCallback2 callback, out IDebugProcess2 process) { waiter = new AutoResetEvent(false); settings = MonoDebuggerSettings.Load(options); Task.Run(() => { var outputWindow = (IVsOutputWindow)Microsoft.VisualStudio.Shell.Package.GetGlobalService(typeof(SVsOutputWindow)); var generalPaneGuid = VSConstants.GUID_OutWindowDebugPane; outputWindow.GetPane(ref generalPaneGuid, out this.outputWindow); settings.Launcher.Launch(); // Trigger that the app is now running for whomever might be waiting for that signal waiter.Set(); }); Session = new SoftDebuggerSession(); Session.TargetReady += (sender, eventArgs) => { var activeThread = Session.ActiveThread; ThreadManager.Add(activeThread, new MonoThread(this, activeThread)); // Session.Stop(); }; Session.ExceptionHandler = exception => true; Session.TargetExited += (sender, x) => { // runCommand.EndExecute(runCommandAsyncResult); Send(new MonoProgramDestroyEvent((uint?)x.ExitCode ?? 0), MonoProgramDestroyEvent.IID, null); }; Session.TargetUnhandledException += (sender, x) => { Send(new MonoExceptionEvent(x.Backtrace.GetFrame(0)) { IsUnhandled = true }, MonoExceptionEvent.IID, ThreadManager[x.Thread]); }; Session.LogWriter = (stderr, text) => Console.WriteLine(text); Session.OutputWriter = (stderr, text) => Console.WriteLine(text); Session.TargetThreadStarted += (sender, x) => ThreadManager.Add(x.Thread, new MonoThread(this, x.Thread)); Session.TargetThreadStopped += (sender, x) => { ThreadManager.Remove(x.Thread); }; Session.TargetStopped += (sender, x) => Console.WriteLine(x.Type); Session.TargetStarted += (sender, x) => Console.WriteLine(); Session.TargetSignaled += (sender, x) => Console.WriteLine(x.Type); Session.TargetInterrupted += (sender, x) => Console.WriteLine(x.Type); Session.TargetExceptionThrown += (sender, x) => { Send(new MonoExceptionEvent(x.Backtrace.GetFrame(0)), MonoExceptionEvent.IID, ThreadManager[x.Thread]); }; Session.TargetHitBreakpoint += (sender, x) => { var breakpoint = x.BreakEvent as Breakpoint; var pendingBreakpoint = breakpointManager[breakpoint]; Send(new MonoBreakpointEvent(new MonoBoundBreakpointsEnum(pendingBreakpoint.BoundBreakpoints)), MonoBreakpointEvent.IID, ThreadManager[x.Thread]); }; processId = new AD_PROCESS_ID(); processId.ProcessIdType = (uint)enum_AD_PROCESS_ID.AD_PROCESS_ID_GUID; processId.guidProcessId = Guid.NewGuid(); EngineUtils.CheckOk(port.GetProcess(processId, out process)); Callback = callback; return(VSConstants.S_OK); }
// Binds this pending breakpoint to one or more code locations. int IDebugPendingBreakpoint2.Bind() { if (CanBind()) { IDebugDocumentPosition2 docPosition = (IDebugDocumentPosition2)(Marshal.GetObjectForIUnknown(_bpRequestInfo.bpLocation.unionmember2)); // Get the name of the document that the breakpoint was put in EngineUtils.CheckOk(docPosition.GetFileName(out global::System.String documentName)); // Get the location in the document that the breakpoint is in. TEXT_POSITION[] startPosition = new TEXT_POSITION[1]; TEXT_POSITION[] endPosition = new TEXT_POSITION[1]; EngineUtils.CheckOk(docPosition.GetRange(startPosition, endPosition)); lock (_boundBreakpoints) { if (_bpRequestInfo.guidLanguage == DebuggerConstants.guidLanguagePython) { PythonBreakpoint bp = _engine.Process.AddBreakpoint( documentName, (int)(startPosition[0].dwLine + 1), _bpRequestInfo.bpCondition.styleCondition.ToPython(), _bpRequestInfo.bpCondition.bstrCondition, _bpRequestInfo.bpPassCount.stylePassCount.ToPython(), (int)_bpRequestInfo.bpPassCount.dwPassCount); AD7BreakpointResolution breakpointResolution = new AD7BreakpointResolution(_engine, bp, GetDocumentContext(bp)); AD7BoundBreakpoint boundBreakpoint = new AD7BoundBreakpoint(_engine, bp, this, breakpointResolution, _enabled); _boundBreakpoints.Add(boundBreakpoint); _bpManager.AddBoundBreakpoint(bp, boundBreakpoint); if (_enabled) { TaskHelpers.RunSynchronouslyOnUIThread(ct => bp.AddAsync(ct)); } return(VSConstants.S_OK); } else if (_bpRequestInfo.guidLanguage == DebuggerConstants.guidLanguageDjangoTemplate) { // bind a Django template PythonBreakpoint bp = _engine.Process.AddDjangoBreakpoint( documentName, (int)(startPosition[0].dwLine + 1) ); AD7BreakpointResolution breakpointResolution = new AD7BreakpointResolution(_engine, bp, GetDocumentContext(bp)); AD7BoundBreakpoint boundBreakpoint = new AD7BoundBreakpoint(_engine, bp, this, breakpointResolution, _enabled); _boundBreakpoints.Add(boundBreakpoint); _bpManager.AddBoundBreakpoint(bp, boundBreakpoint); if (_enabled) { TaskHelpers.RunSynchronouslyOnUIThread(ct => bp.AddAsync(ct)); } return(VSConstants.S_OK); } } } // The breakpoint could not be bound. This may occur for many reasons such as an invalid location, an invalid expression, etc... // The Python engine does not support this. // TODO: send an instance of IDebugBreakpointErrorEvent2 to the UI and return a valid instance of IDebugErrorBreakpoint2 from // IDebugPendingBreakpoint2::EnumErrorBreakpoints. The debugger will then display information about why the breakpoint did not // bind to the user. return(VSConstants.S_FALSE); }