Browse Source

Show argument names and values in callstack (customizable through context menu)

pull/263/head
Ronny Klier 14 years ago
parent
commit
ae42a14476
  1. 2
      Debugger/ILSpy.Debugger/Commands/DebuggerCommands.cs
  2. 107
      Debugger/ILSpy.Debugger/DebuggerSettings.cs
  3. 3
      Debugger/ILSpy.Debugger/Services/Debugger/WindowsDebugger.cs
  4. 2
      Debugger/ILSpy.Debugger/UI/BreakpointPanel.xaml
  5. 22
      Debugger/ILSpy.Debugger/UI/BreakpointPanel.xaml.cs
  6. 22
      Debugger/ILSpy.Debugger/UI/CallStackPanel.xaml
  7. 92
      Debugger/ILSpy.Debugger/UI/CallStackPanel.xaml.cs
  8. 38
      Debugger/ILSpy.Debugger/UI/DebuggerSettingsPanel.xaml.cs

2
Debugger/ILSpy.Debugger/Commands/DebuggerCommands.cs

@ -138,7 +138,7 @@ namespace ICSharpCode.ILSpy.Debugger.Commands @@ -138,7 +138,7 @@ namespace ICSharpCode.ILSpy.Debugger.Commands
foreach (var item in items.First().Items.OfType<MenuItem>()) {
string header = (string)item.Header;
if (header.StartsWith("Remove")) continue;
if (header.StartsWith("Remove") || header.StartsWith("Show")) continue;
if (header.StartsWith("Attach") || header.StartsWith("Debug"))
item.IsEnabled = enable;

107
Debugger/ILSpy.Debugger/DebuggerSettings.cs

@ -3,15 +3,72 @@ @@ -3,15 +3,72 @@
using System;
using System.ComponentModel;
using System.Xml.Linq;
namespace ICSharpCode.ILSpy.Debugger
{
public class DebuggerSettings : INotifyPropertyChanged
{
bool showWarnings = true;
bool askArguments = true;
bool debugWholeTypesOnly = false;
bool showAllBookmarks = false;
#region members
private static readonly string DEBUGGER_SETTINGS = "DebuggerSettings";
private static readonly string SHOW_WARNINGS = "showWarnings";
private static readonly string ASK_ARGUMENTS = "askForArguments";
private static readonly string SHOW_BOOKMARKS = "showAllBookmarks";
private static readonly string SHOW_MODULE = "showModuleName";
private static readonly string SHOW_ARGUMENTS = "showArguments";
private static readonly string SHOW_ARGUMENTVALUE = "showArgumentValues";
private bool showWarnings = true;
private bool askArguments = true;
private bool debugWholeTypesOnly = false;
private bool showAllBookmarks = false;
private bool showModuleName = true;
private bool showArguments = false;
private bool showArgumentValues = false;
private static DebuggerSettings s_instance;
#endregion
public static DebuggerSettings Instance
{
get {
if (null == s_instance)
s_instance = new DebuggerSettings();
return s_instance;
}
}
private DebuggerSettings()
{
}
public void Load(ILSpySettings settings)
{
XElement e = settings[DEBUGGER_SETTINGS];
ShowWarnings = (bool?)e.Attribute(SHOW_WARNINGS) ?? ShowWarnings;
AskForArguments = (bool?)e.Attribute(ASK_ARGUMENTS) ?? AskForArguments;
ShowAllBookmarks = (bool?)e.Attribute(SHOW_BOOKMARKS) ?? ShowAllBookmarks;
ShowModuleName = (bool?)e.Attribute(SHOW_MODULE) ?? ShowModuleName;
ShowArguments = (bool?)e.Attribute(SHOW_ARGUMENTS) ?? ShowArguments;
ShowArgumentValues = (bool?)e.Attribute(SHOW_ARGUMENTVALUE) ?? ShowArgumentValues;
}
public void Save(XElement root)
{
XElement section = new XElement(DEBUGGER_SETTINGS);
section.SetAttributeValue(SHOW_WARNINGS, ShowWarnings);
section.SetAttributeValue(ASK_ARGUMENTS, AskForArguments);
section.SetAttributeValue(SHOW_BOOKMARKS, ShowAllBookmarks);
section.SetAttributeValue(SHOW_MODULE, ShowModuleName);
section.SetAttributeValue(SHOW_ARGUMENTS, ShowArguments);
section.SetAttributeValue(SHOW_ARGUMENTVALUE, ShowArgumentValues);
XElement existingElement = root.Element(DEBUGGER_SETTINGS);
if (existingElement != null)
existingElement.ReplaceWith(section);
else
root.Add(section);
}
/// <summary>
/// Show warnings messages.
@ -71,6 +128,47 @@ namespace ICSharpCode.ILSpy.Debugger @@ -71,6 +128,47 @@ namespace ICSharpCode.ILSpy.Debugger
}
}
/// <summary>
/// Show module name in callstack panel.
/// </summary>
[DefaultValue(true)]
public bool ShowModuleName {
get { return showModuleName; }
set {
if (showModuleName != value) {
showModuleName = value;
OnPropertyChanged("ShowModuleName");
}
}
}
/// <summary>
/// Show module name in callstack panel.
/// </summary>
[DefaultValue(false)]
public bool ShowArguments {
get { return showArguments; }
set {
if (showArguments != value) {
showArguments = value;
OnPropertyChanged("ShowArguments");
}
}
}
/// <summary>
/// Show module name in callstack panel.
/// </summary>
[DefaultValue(false)]
public bool ShowArgumentValues {
get { return showArgumentValues; }
set {
if (showArgumentValues != value) {
showArgumentValues = value;
OnPropertyChanged("ShowArgumentValues");
}
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(string propertyName)
@ -79,5 +177,6 @@ namespace ICSharpCode.ILSpy.Debugger @@ -79,5 +177,6 @@ namespace ICSharpCode.ILSpy.Debugger
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}
}

3
Debugger/ILSpy.Debugger/Services/Debugger/WindowsDebugger.cs

@ -796,7 +796,8 @@ namespace ICSharpCode.ILSpy.Debugger.Services @@ -796,7 +796,8 @@ namespace ICSharpCode.ILSpy.Debugger.Services
int line;
MemberReference memberReference;
if (DebugInformation.CodeMappings.ContainsKey(token) &&
if (null != DebugInformation.CodeMappings &&
DebugInformation.CodeMappings.ContainsKey(token) &&
DebugInformation.CodeMappings[token].GetInstructionByTokenAndOffset(token, ilOffset, out memberReference, out line)) {
DebugInformation.DebugStepInformation = null; // we do not need to step into/out
DebuggerService.RemoveCurrentLineMarker();

2
Debugger/ILSpy.Debugger/UI/BreakpointPanel.xaml

@ -1,6 +1,6 @@ @@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<UserControl
x:Class="ILSpyPlugin.BreakpointPanel" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:bm="clr-namespace:ICSharpCode.ILSpy.Bookmarks">
x:Class="ICSharpCode.ILSpy.Debugger.UI.BreakpointPanel" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:bm="clr-namespace:ICSharpCode.ILSpy.Bookmarks">
<Grid>
<ListView
Name="view"

22
Debugger/ILSpy.Debugger/UI/BreakpointPanel.xaml.cs

@ -17,7 +17,7 @@ using ICSharpCode.ILSpy.Bookmarks; @@ -17,7 +17,7 @@ using ICSharpCode.ILSpy.Bookmarks;
using ICSharpCode.ILSpy.Debugger.Bookmarks;
using ICSharpCode.ILSpy.Options;
namespace ILSpyPlugin
namespace ICSharpCode.ILSpy.Debugger.UI
{
/// <summary>
/// Interaction logic for BreakpointPanel.xaml
@ -41,23 +41,27 @@ namespace ILSpyPlugin @@ -41,23 +41,27 @@ namespace ILSpyPlugin
private BreakpointPanel()
{
InitializeComponent();
SetItemSource();
BookmarkManager.Added += delegate { SetItemSource(); };
BookmarkManager.Removed += delegate { SetItemSource(); };
DebuggerSettingsPanel.CurrentDebuggerSettings.PropertyChanged +=
delegate(object s, PropertyChangedEventArgs e) { if (e.PropertyName == "ShowAllBookmarks") SetItemSource(); };
}
public void Show()
{
if (!IsVisible)
MainWindow.Instance.ShowInBottomPane("Breakpoints", this);
{
SetItemSource();
MainWindow.Instance.ShowInBottomPane("Breakpoints", this);
BookmarkManager.Added += delegate { SetItemSource(); };
BookmarkManager.Removed += delegate { SetItemSource(); };
DebuggerSettings.Instance.PropertyChanged +=
delegate(object s, PropertyChangedEventArgs e) { if (e.PropertyName == "ShowAllBookmarks") SetItemSource(); };
}
}
private void SetItemSource()
{
view.ItemsSource = null;
if (DebuggerSettingsPanel.CurrentDebuggerSettings.ShowAllBookmarks)
if (DebuggerSettings.Instance.ShowAllBookmarks)
view.ItemsSource = BookmarkManager.Bookmarks;
else
view.ItemsSource = BookmarkManager.Bookmarks.Where(b => b is BreakpointBookmark);
@ -67,7 +71,7 @@ namespace ILSpyPlugin @@ -67,7 +71,7 @@ namespace ILSpyPlugin
{
BookmarkManager.Added -= delegate { SetItemSource(); };
BookmarkManager.Removed -= delegate { SetItemSource(); };
DebuggerSettingsPanel.CurrentDebuggerSettings.PropertyChanged -=
DebuggerSettings.Instance.PropertyChanged -=
delegate(object s, PropertyChangedEventArgs e) { if (e.PropertyName == "ShowAllBookmarks") SetItemSource(); };
}

22
Debugger/ILSpy.Debugger/UI/CallStackPanel.xaml

@ -1,7 +1,6 @@ @@ -1,7 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<UserControl
x:Class="ILSpyPlugin.CallStackPanel" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
>
x:Class="ICSharpCode.ILSpy.Debugger.UI.CallStackPanel" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:debugger="clr-namespace:ICSharpCode.ILSpy.Debugger">
<Grid>
<ListView
Name="view"
@ -30,6 +29,25 @@ @@ -30,6 +29,25 @@
</GridViewColumn>
</GridView>
</ListView.View>
<ListView.ContextMenu>
<ContextMenu>
<MenuItem
Header="Show _module names"
IsChecked="{Binding Path=ShowModuleName, Source={x:Static debugger:DebuggerSettings.Instance}, Mode=TwoWay}"
Click="SwitchIsChecked"
/>
<MenuItem
Header="Show _argument names"
IsChecked="{Binding Path=ShowArguments, Source={x:Static debugger:DebuggerSettings.Instance}, Mode=TwoWay}"
Click="SwitchIsChecked"
/>
<MenuItem
Header="Show argument _values"
IsChecked="{Binding Path=ShowArgumentValues, Source={x:Static debugger:DebuggerSettings.Instance}, Mode=TwoWay}"
Click="SwitchIsChecked"
/>
</ContextMenu>
</ListView.ContextMenu>
</ListView>
</Grid>
</UserControl>

92
Debugger/ILSpy.Debugger/UI/CallStackPanel.xaml.cs

@ -2,6 +2,7 @@ @@ -2,6 +2,7 @@
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Windows;
@ -10,6 +11,7 @@ using System.Windows.Data; @@ -10,6 +11,7 @@ using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Xml.Linq;
using Debugger;
using ICSharpCode.ILSpy;
@ -17,17 +19,17 @@ using ICSharpCode.ILSpy.Debugger.Models.TreeModel; @@ -17,17 +19,17 @@ using ICSharpCode.ILSpy.Debugger.Models.TreeModel;
using ICSharpCode.ILSpy.Debugger.Services;
using ICSharpCode.ILSpy.XmlDoc;
using Mono.Cecil;
using Mono.CSharp;
namespace ILSpyPlugin
namespace ICSharpCode.ILSpy.Debugger.UI
{
/// <summary>
/// Interaction logic for CallStackPanel.xaml
/// </summary>
public partial class CallStackPanel : UserControl
public partial class CallStackPanel : UserControl, IPane
{
static CallStackPanel s_instance;
IDebugger m_currentDebugger;
Process debuggedProcess;
public static CallStackPanel Instance
{
@ -44,24 +46,59 @@ namespace ILSpyPlugin @@ -44,24 +46,59 @@ namespace ILSpyPlugin
private CallStackPanel()
{
InitializeComponent();
DebuggerService.DebugStarted += new EventHandler(OnDebugStarted);
DebuggerService.DebugStopped += new EventHandler(OnDebugStopped);
if (DebuggerService.IsDebuggerStarted)
OnDebugStarted(null, EventArgs.Empty);
}
public void Show()
{
if (!IsVisible)
MainWindow.Instance.ShowInBottomPane("Callstack", this);
{
// load debugger settings (to update context menu)
ILSpySettings settings = ILSpySettings.Load();
DebuggerSettings.Instance.Load(settings);
DebuggerSettings.Instance.PropertyChanged += new PropertyChangedEventHandler(OnDebuggerSettingChanged);
SwitchModuleColumn();
MainWindow.Instance.ShowInBottomPane("Callstack", this);
DebuggerService.DebugStarted += new EventHandler(OnDebugStarted);
DebuggerService.DebugStopped += new EventHandler(OnDebugStopped);
if (DebuggerService.IsDebuggerStarted)
OnDebugStarted(null, EventArgs.Empty);
}
}
public void Closed()
{
DebuggerService.DebugStarted -= new EventHandler(OnDebugStarted);
DebuggerService.DebugStopped -= new EventHandler(OnDebugStopped);
if (null != m_currentDebugger)
OnDebugStopped(null, EventArgs.Empty);
// save settings
DebuggerSettings.Instance.PropertyChanged -= new PropertyChangedEventHandler(OnDebuggerSettingChanged);
ILSpySettings.Update(
delegate (XElement root) {
DebuggerSettings.Instance.Save(root);
});
}
void OnDebuggerSettingChanged(object sender, PropertyChangedEventArgs args)
{
if (args.PropertyName == "ShowModuleName") {
SwitchModuleColumn();
}
else if (args.PropertyName == "ShowArguments"
|| args.PropertyName == "ShowArgumentValues") {
RefreshPad();
}
}
void OnDebugStarted(object sender, EventArgs args)
{
m_currentDebugger = DebuggerService.CurrentDebugger;
m_currentDebugger.IsProcessRunningChanged += new EventHandler(OnProcessRunningChanged);
debuggedProcess = ((WindowsDebugger)m_currentDebugger).DebuggedProcess;
OnProcessRunningChanged(null, EventArgs.Empty);
}
@ -69,7 +106,7 @@ namespace ILSpyPlugin @@ -69,7 +106,7 @@ namespace ILSpyPlugin
{
m_currentDebugger.IsProcessRunningChanged -= new EventHandler(OnProcessRunningChanged);
m_currentDebugger = null;
debuggedProcess = null;
view.ItemsSource = null;
}
void OnProcessRunningChanged(object sender, EventArgs args)
@ -79,18 +116,28 @@ namespace ILSpyPlugin @@ -79,18 +116,28 @@ namespace ILSpyPlugin
RefreshPad();
}
void SwitchModuleColumn()
{
foreach (GridViewColumn c in ((GridView)view.View).Columns) {
if ((string)c.Header == "Module") {
c.Width = DebuggerSettings.Instance.ShowModuleName ? double.NaN : 0d;
}
}
}
void RefreshPad()
{
Process debuggedProcess = ((WindowsDebugger)m_currentDebugger).DebuggedProcess;
if (debuggedProcess == null || debuggedProcess.IsRunning || debuggedProcess.SelectedThread == null) {
view.ItemsSource = null;
return;
}
List<CallStackItem> items = null;
IList<CallStackItem> items = null;
StackFrame activeFrame = null;
try {
Utils.DoEvents(debuggedProcess);
items = CreateItems().ToList();
items = CreateItems(debuggedProcess);
activeFrame = debuggedProcess.SelectedThread.SelectedStackFrame;
} catch(AbortedBecauseDebuggeeResumedException) {
} catch(System.Exception) {
@ -104,8 +151,9 @@ namespace ILSpyPlugin @@ -104,8 +151,9 @@ namespace ILSpyPlugin
view.SelectedItem = items != null ? items.FirstOrDefault(item => object.Equals(activeFrame, item.Frame)) : null;
}
IEnumerable<CallStackItem> CreateItems()
IList<CallStackItem> CreateItems(Process debuggedProcess)
{
List<CallStackItem> items = new List<CallStackItem>();
foreach (StackFrame frame in debuggedProcess.SelectedThread.GetCallstack(100)) {
CallStackItem item;
@ -116,16 +164,17 @@ namespace ILSpyPlugin @@ -116,16 +164,17 @@ namespace ILSpyPlugin
Name = GetFullName(frame), ModuleName = moduleName
};
item.Frame = frame;
yield return item;
items.Add(item);
Utils.DoEvents(debuggedProcess);
}
return items;
}
internal static string GetFullName(StackFrame frame)
{
// disabled by default, my be switched if options / context menu is added
bool showArgumentNames = false;
bool showArgumentValues = false;
bool showArgumentNames = DebuggerSettings.Instance.ShowArguments;
bool showArgumentValues = DebuggerSettings.Instance.ShowArgumentValues;
StringBuilder name = new StringBuilder();
name.Append(frame.MethodInfo.DeclaringType.FullName);
@ -179,6 +228,7 @@ namespace ILSpyPlugin @@ -179,6 +228,7 @@ namespace ILSpyPlugin
var selectedItem = view.SelectedItem as CallStackItem;
if (null == selectedItem)
return;
var foundAssembly = MainWindow.Instance.CurrentAssemblyList.OpenAssembly(selectedItem.Frame.MethodInfo.DebugModule.FullPath);
if (null == foundAssembly || null == foundAssembly.AssemblyDefinition)
return;
@ -191,6 +241,14 @@ namespace ILSpyPlugin @@ -191,6 +241,14 @@ namespace ILSpyPlugin
// MainWindow.Instance.TextView.UnfoldAndScroll(selectedItem.LineNumber);
e.Handled = true;
}
void SwitchIsChecked(object sender, EventArgs args)
{
if (sender is MenuItem) {
var mi = (MenuItem)sender;
mi.IsChecked = !mi.IsChecked;
}
}
}
public class CallStackItem

38
Debugger/ILSpy.Debugger/UI/DebuggerSettingsPanel.xaml.cs

@ -19,11 +19,6 @@ namespace ICSharpCode.ILSpy.Options @@ -19,11 +19,6 @@ namespace ICSharpCode.ILSpy.Options
[ExportOptionPage(Title = "Debugger", Order = 2)]
partial class DebuggerSettingsPanel : UserControl, IOptionPage
{
private static readonly string DEBUGGER_SETTINGS = "DebuggerSettings";
private static readonly string SHOW_WARNINGS = "showWarnings";
private static readonly string ASK_ARGUMENTS = "askForArguments";
private static readonly string SHOW_BOOKMARKS = "showAllBookmarks";
public DebuggerSettingsPanel()
{
InitializeComponent();
@ -31,40 +26,15 @@ namespace ICSharpCode.ILSpy.Options @@ -31,40 +26,15 @@ namespace ICSharpCode.ILSpy.Options
public void Load(ILSpySettings settings)
{
this.DataContext = CurrentDebuggerSettings;
}
static DebuggerSettings currentDebuggerSettings;
public static DebuggerSettings CurrentDebuggerSettings {
get {
return currentDebuggerSettings ?? (currentDebuggerSettings = LoadDebuggerSettings(ILSpySettings.Load()));
}
}
public static DebuggerSettings LoadDebuggerSettings(ILSpySettings settings)
{
XElement e = settings[DEBUGGER_SETTINGS];
DebuggerSettings s = new DebuggerSettings();
s.ShowWarnings = (bool?)e.Attribute(SHOW_WARNINGS) ?? s.ShowWarnings;
s.AskForArguments = (bool?)e.Attribute(ASK_ARGUMENTS) ?? s.AskForArguments;
s.ShowAllBookmarks = (bool?)e.Attribute(SHOW_BOOKMARKS) ?? s.ShowAllBookmarks;
return s;
var s = DebuggerSettings.Instance;
s.Load(settings);
this.DataContext = s;
}
public void Save(XElement root)
{
var s = (DebuggerSettings)this.DataContext;
XElement section = new XElement(DEBUGGER_SETTINGS);
section.SetAttributeValue(SHOW_WARNINGS, s.ShowWarnings);
section.SetAttributeValue(ASK_ARGUMENTS, s.AskForArguments);
section.SetAttributeValue(SHOW_BOOKMARKS, s.ShowAllBookmarks);
XElement existingElement = root.Element(DEBUGGER_SETTINGS);
if (existingElement != null)
existingElement.ReplaceWith(section);
else
root.Add(section);
s.Save(root);
}
}
}
Loading…
Cancel
Save