45 changed files with 879 additions and 906 deletions
@ -0,0 +1,7 @@
@@ -0,0 +1,7 @@
|
||||
<UserControl x:Class="Debugger.AddIn.Breakpoints.BreakpointEditor" |
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" |
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> |
||||
<Grid> |
||||
|
||||
</Grid> |
||||
</UserControl> |
@ -0,0 +1,214 @@
@@ -0,0 +1,214 @@
|
||||
// Copyright (c) 2014 AlphaSierraPapa for the SharpDevelop Team
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
|
||||
// software and associated documentation files (the "Software"), to deal in the Software
|
||||
// without restriction, including without limitation the rights to use, copy, modify, merge,
|
||||
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
|
||||
// to whom the Software is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all copies or
|
||||
// substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
|
||||
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
|
||||
// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
using System; |
||||
using System.Diagnostics; |
||||
using ICSharpCode.Core; |
||||
using ICSharpCode.SharpDevelop.Editor; |
||||
using ICSharpCode.SharpDevelop.Gui; |
||||
using ICSharpCode.SharpDevelop.Project; |
||||
|
||||
namespace ICSharpCode.SharpDevelop.Debugging |
||||
{ |
||||
public abstract class BaseDebuggerService : IDebuggerService |
||||
{ |
||||
protected BaseDebuggerService() |
||||
{ |
||||
SD.ProjectService.SolutionOpened += delegate { |
||||
ClearDebugMessages(); |
||||
}; |
||||
SD.ProjectService.SolutionClosing += OnSolutionClosing; |
||||
} |
||||
|
||||
public virtual void Dispose() |
||||
{ |
||||
SD.ProjectService.SolutionClosing -= OnSolutionClosing; |
||||
} |
||||
|
||||
bool debuggerStarted; |
||||
|
||||
/// <summary>
|
||||
/// Gets whether the debugger is currently active.
|
||||
/// </summary>
|
||||
public bool IsDebuggerStarted { |
||||
get { |
||||
return debuggerStarted; |
||||
} |
||||
} |
||||
|
||||
public event EventHandler DebugStarted; |
||||
|
||||
protected virtual void OnDebugStarted(EventArgs e) |
||||
{ |
||||
debuggerStarted = true; |
||||
if (DebugStarted != null) { |
||||
DebugStarted(this, e); |
||||
} |
||||
} |
||||
|
||||
IAnalyticsMonitorTrackedFeature debugFeature; |
||||
|
||||
public event EventHandler IsProcessRunningChanged; |
||||
|
||||
protected virtual void OnIsProcessRunningChanged(EventArgs e) |
||||
{ |
||||
if (IsProcessRunningChanged != null) { |
||||
IsProcessRunningChanged(this, e); |
||||
} |
||||
} |
||||
|
||||
public event EventHandler DebugStopped; |
||||
|
||||
protected virtual void OnDebugStopped(EventArgs e) |
||||
{ |
||||
debuggerStarted = false; |
||||
if (debugFeature != null) |
||||
debugFeature.EndTracking(); |
||||
RemoveCurrentLineMarker(); |
||||
SD.Workbench.CurrentLayoutConfiguration = "Default"; |
||||
if (DebugStopped != null) { |
||||
DebugStopped(this, e); |
||||
} |
||||
} |
||||
|
||||
public event EventHandler DebugStarting; |
||||
|
||||
protected virtual void OnDebugStarting(EventArgs e) |
||||
{ |
||||
SD.Workbench.CurrentLayoutConfiguration = "Debug"; |
||||
debugFeature = SD.AnalyticsMonitor.TrackFeature("Debugger"); |
||||
ClearDebugMessages(); |
||||
if (DebugStarting != null) |
||||
DebugStarting(null, e); |
||||
} |
||||
|
||||
void OnSolutionClosing(object sender, SolutionClosingEventArgs e) |
||||
{ |
||||
if (IsDebugging) { |
||||
if (!e.AllowCancel) { |
||||
Stop(); |
||||
return; |
||||
} |
||||
string caption = StringParser.Parse("${res:XML.MainMenu.DebugMenu.Stop}"); |
||||
string message = StringParser.Parse("${res:MainWindow.Windows.Debug.StopDebugging.Message}"); |
||||
string[] buttonLabels = new string[] { |
||||
StringParser.Parse("${res:Global.Yes}"), |
||||
StringParser.Parse("${res:Global.No}") |
||||
}; |
||||
int result = MessageService.ShowCustomDialog(caption, message, 0, // yes
|
||||
1, // no
|
||||
buttonLabels); |
||||
if (result == 0) { |
||||
Stop(); |
||||
} else { |
||||
e.Cancel = true; |
||||
} |
||||
} |
||||
} |
||||
|
||||
public abstract bool CanDebug(IProject project); |
||||
|
||||
public abstract bool Supports(DebuggerFeatures feature); |
||||
|
||||
public abstract void Start(ProcessStartInfo processStartInfo); |
||||
|
||||
public abstract void StartWithoutDebugging(ProcessStartInfo processStartInfo); |
||||
|
||||
public abstract void Stop(); |
||||
|
||||
public abstract void Break(); |
||||
|
||||
public abstract void Continue(); |
||||
|
||||
public abstract void StepInto(); |
||||
|
||||
public abstract void StepOver(); |
||||
|
||||
public abstract void StepOut(); |
||||
|
||||
public abstract void ShowAttachDialog(); |
||||
|
||||
public abstract void Attach(Process process); |
||||
|
||||
public abstract void Detach(); |
||||
|
||||
public abstract bool SetInstructionPointer(string filename, int line, int column, bool dryRun); |
||||
|
||||
public virtual bool IsDebuggerLoaded { |
||||
get { |
||||
return true; |
||||
} |
||||
} |
||||
|
||||
public abstract bool IsDebugging { |
||||
get; |
||||
} |
||||
|
||||
public abstract bool IsProcessRunning { |
||||
get; |
||||
} |
||||
|
||||
public abstract bool BreakAtBeginning { |
||||
get; |
||||
set; |
||||
} |
||||
|
||||
public abstract bool IsAttached { |
||||
get; |
||||
} |
||||
|
||||
public abstract void HandleToolTipRequest(ToolTipRequestEventArgs e); |
||||
|
||||
static MessageViewCategory debugCategory = null; |
||||
|
||||
static void EnsureDebugCategory() |
||||
{ |
||||
if (debugCategory == null) { |
||||
MessageViewCategory.Create(ref debugCategory, "Debug", "${res:MainWindow.Windows.OutputWindow.DebugCategory}"); |
||||
} |
||||
} |
||||
|
||||
public static void ClearDebugMessages() |
||||
{ |
||||
EnsureDebugCategory(); |
||||
debugCategory.ClearText(); |
||||
} |
||||
|
||||
public static void PrintDebugMessage(string msg) |
||||
{ |
||||
EnsureDebugCategory(); |
||||
debugCategory.AppendText(msg); |
||||
} |
||||
|
||||
public abstract void ToggleBreakpointAt(ITextEditor editor, int lineNumber); |
||||
|
||||
public abstract void RemoveCurrentLineMarker(); |
||||
|
||||
public virtual void JumpToCurrentLine(string sourceFullFilename, int startLine, int startColumn, int endLine, int endColumn) |
||||
{ |
||||
IViewContent viewContent = FileService.OpenFile(sourceFullFilename); |
||||
if (viewContent != null) { |
||||
IPositionable positionable = viewContent.GetService<IPositionable>(); |
||||
if (positionable != null) { |
||||
positionable.JumpTo(startLine, startColumn); |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
||||
|
@ -0,0 +1,326 @@
@@ -0,0 +1,326 @@
|
||||
// Copyright (c) 2014 AlphaSierraPapa for the SharpDevelop Team
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
|
||||
// software and associated documentation files (the "Software"), to deal in the Software
|
||||
// without restriction, including without limitation the rights to use, copy, modify, merge,
|
||||
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
|
||||
// to whom the Software is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all copies or
|
||||
// substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
|
||||
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
|
||||
// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
using System; |
||||
using System.Diagnostics; |
||||
using ICSharpCode.Core; |
||||
using ICSharpCode.SharpDevelop.Editor; |
||||
using ICSharpCode.SharpDevelop.Gui; |
||||
using ICSharpCode.SharpDevelop.Project; |
||||
|
||||
namespace ICSharpCode.SharpDevelop.Debugging |
||||
{ |
||||
[SDService("SD.Debugger", FallbackImplementation = typeof(DebuggerServiceFallback))] |
||||
public interface IDebuggerService : IDisposable, ITextAreaToolTipProvider |
||||
{ |
||||
/// <summary>
|
||||
/// Returns true if debugger is loaded.
|
||||
/// </summary>
|
||||
bool IsDebuggerLoaded { |
||||
get; |
||||
} |
||||
|
||||
bool IsDebuggerStarted { |
||||
get; |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Returns true if debugger is attached to a process
|
||||
/// </summary>
|
||||
bool IsDebugging { |
||||
get; |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Returns true if process is running
|
||||
/// Returns false if breakpoint is hit, program is breaked, program is stepped, etc...
|
||||
/// </summary>
|
||||
bool IsProcessRunning { |
||||
get; |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Gets or sets whether the debugger should break at the first line of execution.
|
||||
/// </summary>
|
||||
bool BreakAtBeginning { |
||||
get; set; |
||||
} |
||||
|
||||
bool IsAttached { |
||||
get; |
||||
} |
||||
|
||||
bool CanDebug(IProject project); |
||||
|
||||
bool Supports(DebuggerFeatures feature); |
||||
|
||||
/// <summary>
|
||||
/// Starts process and attaches debugger
|
||||
/// </summary>
|
||||
void Start(ProcessStartInfo processStartInfo); |
||||
|
||||
void StartWithoutDebugging(ProcessStartInfo processStartInfo); |
||||
|
||||
/// <summary>
|
||||
/// Stops/terminates attached process
|
||||
/// </summary>
|
||||
void Stop(); |
||||
|
||||
// ExecutionControl:
|
||||
|
||||
void Break(); |
||||
|
||||
void Continue(); |
||||
|
||||
// Stepping:
|
||||
|
||||
void StepInto(); |
||||
|
||||
void StepOver(); |
||||
|
||||
void StepOut(); |
||||
|
||||
/// <summary>
|
||||
/// Shows a dialog so the user can attach to a process.
|
||||
/// </summary>
|
||||
void ShowAttachDialog(); |
||||
|
||||
/// <summary>
|
||||
/// Used to attach to an existing process.
|
||||
/// </summary>
|
||||
void Attach(Process process); |
||||
|
||||
void Detach(); |
||||
|
||||
/// <summary>
|
||||
/// Set the instruction pointer to a given position.
|
||||
/// </summary>
|
||||
/// <returns>True if successful. False otherwise</returns>
|
||||
bool SetInstructionPointer(string filename, int line, int column, bool dryRun); |
||||
|
||||
void ToggleBreakpointAt(ITextEditor editor, int lineNumber); |
||||
|
||||
void RemoveCurrentLineMarker(); |
||||
|
||||
void JumpToCurrentLine(string sourceFullFilename, int startLine, int startColumn, int endLine, int endColumn); |
||||
|
||||
/// <summary>
|
||||
/// Ocurrs when the debugger is starting.
|
||||
/// </summary>
|
||||
event EventHandler DebugStarting; |
||||
|
||||
/// <summary>
|
||||
/// Ocurrs after the debugger has started.
|
||||
/// </summary>
|
||||
event EventHandler DebugStarted; |
||||
|
||||
/// <summary>
|
||||
/// Ocurrs when the value of IsProcessRunning changes.
|
||||
/// </summary>
|
||||
event EventHandler IsProcessRunningChanged; |
||||
|
||||
/// <summary>
|
||||
/// Ocurrs after the debugging of program is finished.
|
||||
/// </summary>
|
||||
event EventHandler DebugStopped; |
||||
} |
||||
|
||||
public enum DebuggerFeatures |
||||
{ |
||||
Start, |
||||
StartWithoutDebugging, |
||||
Stop, |
||||
ExecutionControl, |
||||
Stepping, |
||||
Attaching, |
||||
Detaching |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Provides the default debugger tooltips on the text area.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This class must be public because it is accessed via the AddInTree.
|
||||
/// </remarks>
|
||||
public class DebuggerTextAreaToolTipProvider : ITextAreaToolTipProvider |
||||
{ |
||||
public void HandleToolTipRequest(ToolTipRequestEventArgs e) |
||||
{ |
||||
if (SD.Debugger.IsDebuggerLoaded) |
||||
SD.Debugger.HandleToolTipRequest(e); |
||||
} |
||||
} |
||||
|
||||
|
||||
|
||||
class DebuggerServiceFallback : BaseDebuggerService |
||||
{ |
||||
Process attachedProcess = null; |
||||
|
||||
public override bool IsDebugging { |
||||
get { |
||||
return attachedProcess != null; |
||||
} |
||||
} |
||||
|
||||
public override bool IsProcessRunning { |
||||
get { |
||||
return IsDebugging; |
||||
} |
||||
} |
||||
|
||||
/// <inheritdoc/>
|
||||
public override bool BreakAtBeginning { |
||||
get; set; |
||||
} |
||||
|
||||
public override bool CanDebug(IProject project) |
||||
{ |
||||
return true; |
||||
} |
||||
|
||||
public override bool Supports(DebuggerFeatures feature) |
||||
{ |
||||
switch (feature) { |
||||
case DebuggerFeatures.Start: |
||||
case DebuggerFeatures.StartWithoutDebugging: |
||||
case DebuggerFeatures.Stop: |
||||
return true; |
||||
case DebuggerFeatures.ExecutionControl: |
||||
case DebuggerFeatures.Stepping: |
||||
case DebuggerFeatures.Attaching: |
||||
case DebuggerFeatures.Detaching: |
||||
return false; |
||||
default: |
||||
throw new ArgumentOutOfRangeException(); |
||||
} |
||||
} |
||||
|
||||
public override void Start(ProcessStartInfo processStartInfo) |
||||
{ |
||||
if (attachedProcess != null) { |
||||
return; |
||||
} |
||||
|
||||
OnDebugStarting(EventArgs.Empty); |
||||
try { |
||||
attachedProcess = new Process(); |
||||
attachedProcess.StartInfo = processStartInfo; |
||||
attachedProcess.Exited += new EventHandler(AttachedProcessExited); |
||||
attachedProcess.EnableRaisingEvents = true; |
||||
attachedProcess.Start(); |
||||
OnDebugStarted(EventArgs.Empty); |
||||
} catch (Exception) { |
||||
OnDebugStopped(EventArgs.Empty); |
||||
throw new ApplicationException("Can't execute \"" + processStartInfo.FileName + "\"\n"); |
||||
} |
||||
} |
||||
|
||||
public override void ShowAttachDialog() |
||||
{ |
||||
} |
||||
|
||||
public override void Attach(Process process) |
||||
{ |
||||
} |
||||
|
||||
public override void Detach() |
||||
{ |
||||
} |
||||
|
||||
void AttachedProcessExited(object sender, EventArgs e) |
||||
{ |
||||
attachedProcess.Exited -= AttachedProcessExited; |
||||
attachedProcess.Dispose(); |
||||
attachedProcess = null; |
||||
SD.MainThread.InvokeAsyncAndForget(() => new Action<EventArgs>(OnDebugStopped)(EventArgs.Empty)); |
||||
} |
||||
|
||||
public override void StartWithoutDebugging(ProcessStartInfo processStartInfo) |
||||
{ |
||||
Process.Start(processStartInfo); |
||||
} |
||||
|
||||
public override void Stop() |
||||
{ |
||||
if (attachedProcess != null) { |
||||
attachedProcess.Exited -= AttachedProcessExited; |
||||
attachedProcess.Kill(); |
||||
attachedProcess.Close(); |
||||
attachedProcess.Dispose(); |
||||
attachedProcess = null; |
||||
} |
||||
} |
||||
|
||||
// ExecutionControl:
|
||||
|
||||
public override void Break() |
||||
{ |
||||
throw new NotSupportedException(); |
||||
} |
||||
|
||||
public override void Continue() |
||||
{ |
||||
throw new NotSupportedException(); |
||||
} |
||||
// Stepping:
|
||||
|
||||
public override void StepInto() |
||||
{ |
||||
throw new NotSupportedException(); |
||||
} |
||||
|
||||
public override void StepOver() |
||||
{ |
||||
throw new NotSupportedException(); |
||||
} |
||||
|
||||
public override void StepOut() |
||||
{ |
||||
throw new NotSupportedException(); |
||||
} |
||||
|
||||
public override void HandleToolTipRequest(ToolTipRequestEventArgs e) |
||||
{ |
||||
} |
||||
|
||||
public override bool SetInstructionPointer(string filename, int line, int column, bool dryRun) |
||||
{ |
||||
return false; |
||||
} |
||||
|
||||
public override void Dispose() |
||||
{ |
||||
Stop(); |
||||
base.Dispose(); |
||||
} |
||||
|
||||
public override bool IsAttached { |
||||
get { |
||||
return false; |
||||
} |
||||
} |
||||
|
||||
public override void RemoveCurrentLineMarker() |
||||
{ |
||||
} |
||||
|
||||
public override void ToggleBreakpointAt(ITextEditor editor, int lineNumber) |
||||
{ |
||||
} |
||||
} |
||||
} |
@ -1,129 +0,0 @@
@@ -1,129 +0,0 @@
|
||||
// Copyright (c) 2014 AlphaSierraPapa for the SharpDevelop Team
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
|
||||
// software and associated documentation files (the "Software"), to deal in the Software
|
||||
// without restriction, including without limitation the rights to use, copy, modify, merge,
|
||||
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
|
||||
// to whom the Software is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all copies or
|
||||
// substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
|
||||
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
|
||||
// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
|
||||
using System; |
||||
using System.Collections; |
||||
using ICSharpCode.Core; |
||||
|
||||
namespace ICSharpCode.SharpDevelop.Debugging |
||||
{ |
||||
/// <summary>
|
||||
/// Creates debuggers.
|
||||
/// </summary>
|
||||
/// <attribute name="class" use="required">
|
||||
/// Name of the IDebugger class.
|
||||
/// </attribute>
|
||||
/// <attribute name="supportsStart" use="optional">
|
||||
/// Specifies if the debugger supports the 'Start' command. Default: true
|
||||
/// </attribute>
|
||||
/// <attribute name="supportsStartWithoutDebugger" use="optional">
|
||||
/// Specifies if the debugger supports the 'StartWithoutDebugger' command. Default: true
|
||||
/// </attribute>
|
||||
/// <attribute name="supportsStop" use="optional">
|
||||
/// Specifies if the debugger supports the 'Stop' (kill running process) command. Default: true
|
||||
/// </attribute>
|
||||
/// <attribute name="supportsStepping" use="optional">
|
||||
/// Specifies if the debugger supports stepping. Default: false
|
||||
/// </attribute>
|
||||
/// <attribute name="supportsExecutionControl" use="optional">
|
||||
/// Specifies if the debugger supports execution control (break, resume). Default: false
|
||||
/// </attribute>
|
||||
/// <usage>Only in /SharpDevelop/Services/DebuggerService/Debugger</usage>
|
||||
/// <returns>
|
||||
/// An DebuggerDescriptor object that exposes the attributes and the IDebugger object (lazy-loading).
|
||||
/// </returns>
|
||||
public class DebuggerDoozer : IDoozer |
||||
{ |
||||
/// <summary>
|
||||
/// Gets if the doozer handles codon conditions on its own.
|
||||
/// If this property return false, the item is excluded when the condition is not met.
|
||||
/// </summary>
|
||||
public bool HandleConditions { |
||||
get { |
||||
return false; |
||||
} |
||||
} |
||||
|
||||
public object BuildItem(BuildItemArgs args) |
||||
{ |
||||
return new DebuggerDescriptor(args.Codon); |
||||
} |
||||
} |
||||
|
||||
public class DebuggerDescriptor |
||||
{ |
||||
Codon codon; |
||||
|
||||
public DebuggerDescriptor(Codon codon) |
||||
{ |
||||
this.codon = codon; |
||||
} |
||||
|
||||
IDebugger debugger; |
||||
|
||||
public IDebugger Debugger { |
||||
get { |
||||
if (debugger == null) |
||||
debugger = (IDebugger)codon.AddIn.CreateObject(codon.Properties["class"]); |
||||
return debugger; |
||||
} |
||||
} |
||||
|
||||
public bool SupportsStart { |
||||
get { |
||||
return codon.Properties["supportsStart"] != "false"; |
||||
} |
||||
} |
||||
|
||||
public bool SupportsStartWithoutDebugging { |
||||
get { |
||||
return codon.Properties["supportsStartWithoutDebugger"] != "false"; |
||||
} |
||||
} |
||||
|
||||
public bool SupportsStop { |
||||
get { |
||||
return codon.Properties["supportsStop"] != "false"; |
||||
} |
||||
} |
||||
|
||||
public bool SupportsStepping { |
||||
get { |
||||
return codon.Properties["supportsStepping"] == "true"; |
||||
} |
||||
} |
||||
|
||||
public bool SupportsExecutionControl { |
||||
get { |
||||
return codon.Properties["supportsExecutionControl"] == "true"; |
||||
} |
||||
} |
||||
|
||||
public bool SupportsAttaching { |
||||
get { |
||||
return codon.Properties["supportsAttaching"] == "true"; |
||||
} |
||||
} |
||||
|
||||
public bool SupportsDetaching { |
||||
get { |
||||
return codon.Properties["supportsDetaching"] == "true"; |
||||
} |
||||
} |
||||
} |
||||
} |
@ -1,253 +0,0 @@
@@ -1,253 +0,0 @@
|
||||
// Copyright (c) 2014 AlphaSierraPapa for the SharpDevelop Team
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
|
||||
// software and associated documentation files (the "Software"), to deal in the Software
|
||||
// without restriction, including without limitation the rights to use, copy, modify, merge,
|
||||
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
|
||||
// to whom the Software is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all copies or
|
||||
// substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
|
||||
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
|
||||
// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
using System.Linq; |
||||
|
||||
using ICSharpCode.Core; |
||||
using ICSharpCode.SharpDevelop.Editor; |
||||
using ICSharpCode.SharpDevelop.Editor.Bookmarks; |
||||
using ICSharpCode.SharpDevelop.Gui; |
||||
using ICSharpCode.SharpDevelop.Project; |
||||
|
||||
namespace ICSharpCode.SharpDevelop.Debugging |
||||
{ |
||||
public static class DebuggerService |
||||
{ |
||||
static IDebugger currentDebugger; |
||||
static DebuggerDescriptor[] debuggers; |
||||
|
||||
static DebuggerService() |
||||
{ |
||||
SD.ProjectService.SolutionOpened += delegate { |
||||
ClearDebugMessages(); |
||||
}; |
||||
|
||||
SD.ProjectService.SolutionClosing += OnSolutionClosing; |
||||
} |
||||
|
||||
static void GetDescriptors() |
||||
{ |
||||
if (debuggers == null) { |
||||
debuggers = AddInTree.BuildItems<DebuggerDescriptor>("/SharpDevelop/Services/DebuggerService/Debugger", null, false).ToArray(); |
||||
} |
||||
} |
||||
|
||||
static IDebugger GetCompatibleDebugger() |
||||
{ |
||||
GetDescriptors(); |
||||
// IProject project = null;
|
||||
// if (ProjectService.OpenSolution != null) {
|
||||
// project = ProjectService.OpenSolution.StartupProject;
|
||||
// }
|
||||
foreach (DebuggerDescriptor d in debuggers) { |
||||
if (d.Debugger != null /*&& d.Debugger.CanDebug(project)*/) { |
||||
return d.Debugger; |
||||
} |
||||
} |
||||
return new DefaultDebugger(); |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Gets the current debugger. The debugger addin is loaded on demand; so if you
|
||||
/// just want to check a property like IsDebugging, check <see cref="IsDebuggerLoaded"/>
|
||||
/// before using this property.
|
||||
/// </summary>
|
||||
public static IDebugger CurrentDebugger { |
||||
get { |
||||
if (currentDebugger == null) { |
||||
currentDebugger = GetCompatibleDebugger(); |
||||
currentDebugger.DebugStarting += new EventHandler(OnDebugStarting); |
||||
currentDebugger.DebugStarted += new EventHandler(OnDebugStarted); |
||||
currentDebugger.DebugStopped += new EventHandler(OnDebugStopped); |
||||
} |
||||
return currentDebugger; |
||||
} |
||||
} |
||||
|
||||
public static DebuggerDescriptor Descriptor { |
||||
get { |
||||
GetDescriptors(); |
||||
if (debuggers.Length > 0) |
||||
return debuggers[0]; |
||||
return null; |
||||
} |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Returns true if debugger is already loaded.
|
||||
/// </summary>
|
||||
public static bool IsDebuggerLoaded { |
||||
get { |
||||
return currentDebugger != null; |
||||
} |
||||
} |
||||
|
||||
static bool debuggerStarted; |
||||
|
||||
/// <summary>
|
||||
/// Gets whether the debugger is currently active.
|
||||
/// </summary>
|
||||
public static bool IsDebuggerStarted { |
||||
get { return debuggerStarted; } |
||||
} |
||||
|
||||
public static event EventHandler DebugStarting; |
||||
public static event EventHandler DebugStarted; |
||||
public static event EventHandler DebugStopped; |
||||
|
||||
static IAnalyticsMonitorTrackedFeature debugFeature; |
||||
|
||||
static void OnDebugStarting(object sender, EventArgs e) |
||||
{ |
||||
SD.Workbench.CurrentLayoutConfiguration = "Debug"; |
||||
|
||||
debugFeature = SD.AnalyticsMonitor.TrackFeature("Debugger"); |
||||
|
||||
ClearDebugMessages(); |
||||
|
||||
if (DebugStarting != null) |
||||
DebugStarting(null, e); |
||||
} |
||||
|
||||
static void OnDebugStarted(object sender, EventArgs e) |
||||
{ |
||||
debuggerStarted = true; |
||||
if (DebugStarted != null) |
||||
DebugStarted(null, e); |
||||
} |
||||
|
||||
static void OnDebugStopped(object sender, EventArgs e) |
||||
{ |
||||
debuggerStarted = false; |
||||
if (debugFeature != null) |
||||
debugFeature.EndTracking(); |
||||
|
||||
RemoveCurrentLineMarker(); |
||||
SD.Workbench.CurrentLayoutConfiguration = "Default"; |
||||
if (DebugStopped != null) |
||||
DebugStopped(null, e); |
||||
} |
||||
|
||||
static MessageViewCategory debugCategory = null; |
||||
|
||||
static void EnsureDebugCategory() |
||||
{ |
||||
if (debugCategory == null) { |
||||
MessageViewCategory.Create(ref debugCategory, "Debug", "${res:MainWindow.Windows.OutputWindow.DebugCategory}"); |
||||
} |
||||
} |
||||
|
||||
public static void ClearDebugMessages() |
||||
{ |
||||
EnsureDebugCategory(); |
||||
debugCategory.ClearText(); |
||||
} |
||||
|
||||
public static void PrintDebugMessage(string msg) |
||||
{ |
||||
EnsureDebugCategory(); |
||||
debugCategory.AppendText(msg); |
||||
} |
||||
|
||||
static void OnSolutionClosing(object sender, SolutionClosingEventArgs e) |
||||
{ |
||||
if (currentDebugger == null) |
||||
return; |
||||
|
||||
if (currentDebugger.IsDebugging) { |
||||
if (!e.AllowCancel) { |
||||
currentDebugger.Stop(); |
||||
return; |
||||
} |
||||
string caption = StringParser.Parse("${res:XML.MainMenu.DebugMenu.Stop}"); |
||||
string message = StringParser.Parse("${res:MainWindow.Windows.Debug.StopDebugging.Message}"); |
||||
string[] buttonLabels = new string[] { StringParser.Parse("${res:Global.Yes}"), StringParser.Parse("${res:Global.No}") }; |
||||
int result = MessageService.ShowCustomDialog(caption, |
||||
message, |
||||
0, // yes
|
||||
1, // no
|
||||
buttonLabels); |
||||
|
||||
if (result == 0) { |
||||
currentDebugger.Stop(); |
||||
} else { |
||||
e.Cancel = true; |
||||
} |
||||
} |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Toggles a breakpoint bookmark.
|
||||
/// </summary>
|
||||
/// <param name="editor">Text editor where the bookmark is toggled.</param>
|
||||
/// <param name="lineNumber">Line number.</param>
|
||||
/// <param name="breakpointType">Type of breakpoint bookmark.</param>
|
||||
/// <param name="parameters">Optional constructor parameters.</param>
|
||||
public static void ToggleBreakpointAt(ITextEditor editor, int lineNumber) |
||||
{ |
||||
if (editor == null) |
||||
throw new ArgumentNullException("editor"); |
||||
|
||||
if (!SD.BookmarkManager.RemoveBookmarkAt(editor.FileName, lineNumber, b => b is BreakpointBookmark)) { |
||||
SD.BookmarkManager.AddMark(new BreakpointBookmark(), editor.Document, lineNumber); |
||||
} |
||||
} |
||||
|
||||
/* TODO: reimplement this stuff |
||||
static void ViewContentOpened(object sender, ViewContentEventArgs e) |
||||
{ |
||||
textArea.IconBarMargin.MouseDown += IconBarMouseDown; |
||||
textArea.ToolTipRequest += TextAreaToolTipRequest; |
||||
textArea.MouseLeave += TextAreaMouseLeave; |
||||
}*/ |
||||
|
||||
public static void RemoveCurrentLineMarker() |
||||
{ |
||||
CurrentLineBookmark.Remove(); |
||||
} |
||||
|
||||
public static void JumpToCurrentLine(string sourceFullFilename, int startLine, int startColumn, int endLine, int endColumn) |
||||
{ |
||||
IViewContent viewContent = FileService.OpenFile(sourceFullFilename); |
||||
if (viewContent != null) { |
||||
IPositionable positionable = viewContent.GetService<IPositionable>(); |
||||
if (positionable != null) { |
||||
positionable.JumpTo(startLine, startColumn); |
||||
} |
||||
} |
||||
CurrentLineBookmark.SetPosition(viewContent, startLine, startColumn, endLine, endColumn); |
||||
} |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Provides the default debugger tooltips on the text area.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This class must be public because it is accessed via the AddInTree.
|
||||
/// </remarks>
|
||||
public class DebuggerTextAreaToolTipProvider : ITextAreaToolTipProvider |
||||
{ |
||||
public void HandleToolTipRequest(ToolTipRequestEventArgs e) |
||||
{ |
||||
if (DebuggerService.IsDebuggerLoaded) |
||||
DebuggerService.CurrentDebugger.HandleToolTipRequest(e); |
||||
} |
||||
} |
||||
} |
@ -1,197 +0,0 @@
@@ -1,197 +0,0 @@
|
||||
// Copyright (c) 2014 AlphaSierraPapa for the SharpDevelop Team
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
|
||||
// software and associated documentation files (the "Software"), to deal in the Software
|
||||
// without restriction, including without limitation the rights to use, copy, modify, merge,
|
||||
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
|
||||
// to whom the Software is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all copies or
|
||||
// substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
|
||||
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
|
||||
// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
|
||||
using System; |
||||
using System.Diagnostics; |
||||
using ICSharpCode.NRefactory.Semantics; |
||||
using ICSharpCode.SharpDevelop.Editor; |
||||
using ICSharpCode.SharpDevelop.Gui; |
||||
using ICSharpCode.SharpDevelop.Project; |
||||
|
||||
namespace ICSharpCode.SharpDevelop.Debugging |
||||
{ |
||||
public class DefaultDebugger : IDebugger |
||||
{ |
||||
Process attachedProcess = null; |
||||
|
||||
public bool IsDebugging { |
||||
get { |
||||
return attachedProcess != null; |
||||
} |
||||
} |
||||
|
||||
public bool IsProcessRunning { |
||||
get { |
||||
return IsDebugging; |
||||
} |
||||
} |
||||
|
||||
/// <inheritdoc/>
|
||||
public bool BreakAtBeginning { |
||||
get; set; |
||||
} |
||||
|
||||
public bool CanDebug(IProject project) |
||||
{ |
||||
return true; |
||||
} |
||||
|
||||
public void Start(ProcessStartInfo processStartInfo) |
||||
{ |
||||
if (attachedProcess != null) { |
||||
return; |
||||
} |
||||
|
||||
OnDebugStarting(EventArgs.Empty); |
||||
try { |
||||
attachedProcess = new Process(); |
||||
attachedProcess.StartInfo = processStartInfo; |
||||
attachedProcess.Exited += new EventHandler(AttachedProcessExited); |
||||
attachedProcess.EnableRaisingEvents = true; |
||||
attachedProcess.Start(); |
||||
OnDebugStarted(EventArgs.Empty); |
||||
} catch (Exception) { |
||||
OnDebugStopped(EventArgs.Empty); |
||||
throw new ApplicationException("Can't execute \"" + processStartInfo.FileName + "\"\n"); |
||||
} |
||||
} |
||||
|
||||
public void ShowAttachDialog() |
||||
{ |
||||
} |
||||
|
||||
public void Attach(Process process) |
||||
{ |
||||
} |
||||
|
||||
public void Detach() |
||||
{ |
||||
} |
||||
|
||||
void AttachedProcessExited(object sender, EventArgs e) |
||||
{ |
||||
attachedProcess.Exited -= new EventHandler(AttachedProcessExited); |
||||
attachedProcess.Dispose(); |
||||
attachedProcess = null; |
||||
SD.MainThread.InvokeAsyncAndForget(() => new Action<EventArgs>(OnDebugStopped)(EventArgs.Empty)); |
||||
} |
||||
|
||||
public void StartWithoutDebugging(ProcessStartInfo processStartInfo) |
||||
{ |
||||
Process.Start(processStartInfo); |
||||
} |
||||
|
||||
public void Stop() |
||||
{ |
||||
if (attachedProcess != null) { |
||||
attachedProcess.Exited -= new EventHandler(AttachedProcessExited); |
||||
attachedProcess.Kill(); |
||||
attachedProcess.Close(); |
||||
attachedProcess.Dispose(); |
||||
attachedProcess = null; |
||||
} |
||||
} |
||||
|
||||
// ExecutionControl:
|
||||
|
||||
public void Break() |
||||
{ |
||||
throw new NotSupportedException(); |
||||
} |
||||
|
||||
public void Continue() |
||||
{ |
||||
throw new NotSupportedException(); |
||||
} |
||||
// Stepping:
|
||||
|
||||
public void StepInto() |
||||
{ |
||||
throw new NotSupportedException(); |
||||
} |
||||
|
||||
public void StepOver() |
||||
{ |
||||
throw new NotSupportedException(); |
||||
} |
||||
|
||||
public void StepOut() |
||||
{ |
||||
throw new NotSupportedException(); |
||||
} |
||||
|
||||
public void HandleToolTipRequest(ToolTipRequestEventArgs e) |
||||
{ |
||||
} |
||||
|
||||
public bool SetInstructionPointer(string filename, int line, int column, bool dryRun) |
||||
{ |
||||
return false; |
||||
} |
||||
|
||||
|
||||
public event EventHandler DebugStarted; |
||||
|
||||
protected virtual void OnDebugStarted(EventArgs e) |
||||
{ |
||||
if (DebugStarted != null) { |
||||
DebugStarted(this, e); |
||||
} |
||||
} |
||||
|
||||
|
||||
public event EventHandler IsProcessRunningChanged; |
||||
|
||||
protected virtual void OnIsProcessRunningChanged(EventArgs e) |
||||
{ |
||||
if (IsProcessRunningChanged != null) { |
||||
IsProcessRunningChanged(this, e); |
||||
} |
||||
} |
||||
|
||||
|
||||
public event EventHandler DebugStopped; |
||||
|
||||
protected virtual void OnDebugStopped(EventArgs e) |
||||
{ |
||||
if (DebugStopped != null) { |
||||
DebugStopped(this, e); |
||||
} |
||||
} |
||||
|
||||
public event EventHandler DebugStarting; |
||||
|
||||
protected virtual void OnDebugStarting(EventArgs e) |
||||
{ |
||||
if (DebugStarting != null) { |
||||
DebugStarting(this, e); |
||||
} |
||||
} |
||||
|
||||
public void Dispose() |
||||
{ |
||||
Stop(); |
||||
} |
||||
|
||||
public bool IsAttached { |
||||
get { |
||||
return false; |
||||
} |
||||
} |
||||
} |
||||
} |
@ -1,122 +0,0 @@
@@ -1,122 +0,0 @@
|
||||
// Copyright (c) 2014 AlphaSierraPapa for the SharpDevelop Team
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
|
||||
// software and associated documentation files (the "Software"), to deal in the Software
|
||||
// without restriction, including without limitation the rights to use, copy, modify, merge,
|
||||
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
|
||||
// to whom the Software is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all copies or
|
||||
// substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
|
||||
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
|
||||
// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
|
||||
using System; |
||||
using System.Diagnostics; |
||||
using ICSharpCode.NRefactory; |
||||
using ICSharpCode.NRefactory.Semantics; |
||||
using ICSharpCode.SharpDevelop.Editor; |
||||
using ICSharpCode.SharpDevelop.Project; |
||||
|
||||
namespace ICSharpCode.SharpDevelop.Debugging |
||||
{ |
||||
public interface IDebugger : IDisposable, ITextAreaToolTipProvider |
||||
{ |
||||
/// <summary>
|
||||
/// Returns true if debuger is attached to a process
|
||||
/// </summary>
|
||||
bool IsDebugging { |
||||
get; |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Returns true if process is running
|
||||
/// Returns false if breakpoint is hit, program is breaked, program is stepped, etc...
|
||||
/// </summary>
|
||||
bool IsProcessRunning { |
||||
get; |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Gets or sets whether the debugger should break at the first line of execution.
|
||||
/// </summary>
|
||||
bool BreakAtBeginning { |
||||
get; set; |
||||
} |
||||
|
||||
bool IsAttached { |
||||
get; |
||||
} |
||||
|
||||
bool CanDebug(IProject project); |
||||
|
||||
/// <summary>
|
||||
/// Starts process and attaches debugger
|
||||
/// </summary>
|
||||
void Start(ProcessStartInfo processStartInfo); |
||||
|
||||
void StartWithoutDebugging(ProcessStartInfo processStartInfo); |
||||
|
||||
/// <summary>
|
||||
/// Stops/terminates attached process
|
||||
/// </summary>
|
||||
void Stop(); |
||||
|
||||
// ExecutionControl:
|
||||
|
||||
void Break(); |
||||
|
||||
void Continue(); |
||||
|
||||
// Stepping:
|
||||
|
||||
void StepInto(); |
||||
|
||||
void StepOver(); |
||||
|
||||
void StepOut(); |
||||
|
||||
/// <summary>
|
||||
/// Shows a dialog so the user can attach to a process.
|
||||
/// </summary>
|
||||
void ShowAttachDialog(); |
||||
|
||||
/// <summary>
|
||||
/// Used to attach to an existing process.
|
||||
/// </summary>
|
||||
void Attach(Process process); |
||||
|
||||
void Detach(); |
||||
|
||||
/// <summary>
|
||||
/// Set the instruction pointer to a given position.
|
||||
/// </summary>
|
||||
/// <returns>True if successful. False otherwise</returns>
|
||||
bool SetInstructionPointer(string filename, int line, int column, bool dryRun); |
||||
|
||||
/// <summary>
|
||||
/// Ocurrs when the debugger is starting.
|
||||
/// </summary>
|
||||
event EventHandler DebugStarting; |
||||
|
||||
/// <summary>
|
||||
/// Ocurrs after the debugger has started.
|
||||
/// </summary>
|
||||
event EventHandler DebugStarted; |
||||
|
||||
/// <summary>
|
||||
/// Ocurrs when the value of IsProcessRunning changes.
|
||||
/// </summary>
|
||||
event EventHandler IsProcessRunningChanged; |
||||
|
||||
/// <summary>
|
||||
/// Ocurrs after the debugging of program is finished.
|
||||
/// </summary>
|
||||
event EventHandler DebugStopped; |
||||
} |
||||
} |
Loading…
Reference in new issue