Browse Source

add option "Decompile code without symbols" to SharpDevelop; small improvements in debugger when debugging decompiled code

pull/18/head
Siegfried Pammer 14 years ago
parent
commit
430e6b3954
  1. 71
      src/AddIns/Debugger/Debugger.AddIn/Options/DebuggingOptionsPanel.xaml
  2. 2
      src/AddIns/Debugger/Debugger.AddIn/Pads/CallStackPad.xaml.cs
  3. 10
      src/AddIns/Debugger/Debugger.AddIn/Pads/RunningThreadsPad.cs
  4. 7
      src/AddIns/Debugger/Debugger.AddIn/Service/WindowsDebugger.cs
  5. 1
      src/AddIns/Debugger/Debugger.Core/Debugger.Core.csproj
  6. 152
      src/AddIns/Debugger/Debugger.Core/IDStringProvider.cs
  7. 8
      src/AddIns/Debugger/Debugger.Core/MetaData/DebugMethodInfo.cs
  8. 2
      src/AddIns/Debugger/Debugger.Core/Module.cs
  9. 1
      src/AddIns/Debugger/Debugger.Core/Options.cs
  10. 12
      src/AddIns/DisplayBindings/ILSpyAddIn/NavigateToDecompiledEntityService.cs

71
src/AddIns/Debugger/Debugger.AddIn/Options/DebuggingOptionsPanel.xaml

@ -1,42 +1,43 @@ @@ -1,42 +1,43 @@
<gui:OptionPanel x:Class="Debugger.AddIn.Options.DebuggingOptionsPanel"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:sd="http://icsharpcode.net/sharpdevelop/core"
xmlns:gui="clr-namespace:ICSharpCode.SharpDevelop.Gui;assembly=ICSharpCode.SharpDevelop"
xmlns:debugger="clr-namespace:ICSharpCode.SharpDevelop.Services;assembly=Debugger.AddIn"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:widgets="http://icsharpcode.net/sharpdevelop/widgets">
<StackPanel>
<GroupBox Margin="5" Header="{sd:Localize Dialog.Options.IDEOptions.Debugging.Stepping}">
<widgets:StackPanelWithSpacing SpaceBetweenItems="5">
<CheckBox x:Name="chbEnableJustMyCode"
Content="{sd:Localize Dialog.Options.IDEOptions.Debugging.Stepping.EnableJustMyCode}"
IsChecked="{sd:OptionBinding debugger:DebuggingOptions.EnableJustMyCode}" />
<CheckBox x:Name="chbStepOverNoSymbols"
Content="{sd:Localize Dialog.Options.IDEOptions.Debugging.Stepping.StepOverNoSymbols}"
IsChecked="{sd:OptionBinding debugger:DebuggingOptions.StepOverNoSymbols}" />
<CheckBox x:Name="chbStepOverDebuggerAttributes"
Content="{sd:Localize Dialog.Options.IDEOptions.Debugging.Stepping.StepOverDebuggerAttributes}"
IsChecked="{sd:OptionBinding debugger:DebuggingOptions.StepOverDebuggerAttributes}" />
<CheckBox x:Name="chbStepOverAllProperties"
Checked="ChbStepOverAllProperties_CheckedChanged"
Unchecked="ChbStepOverAllProperties_CheckedChanged"
Content="{sd:Localize Dialog.Options.IDEOptions.Debugging.Stepping.StepOverAllProperties}"
IsChecked="{sd:OptionBinding debugger:DebuggingOptions.StepOverAllProperties}" />
<CheckBox x:Name="chbStepOverSingleLineProperties"
Content="{sd:Localize Dialog.Options.IDEOptions.Debugging.Stepping.StepOverSingleLineProperties}"
IsChecked="{sd:OptionBinding debugger:DebuggingOptions.StepOverSingleLineProperties}" />
<CheckBox x:Name="chbStepOverFieldAccessProperties"
Content="{sd:Localize Dialog.Options.IDEOptions.Debugging.Stepping.StepOverFieldAccessProperties}"
IsChecked="{sd:OptionBinding debugger:DebuggingOptions.StepOverFieldAccessProperties}" />
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:sd="http://icsharpcode.net/sharpdevelop/core"
xmlns:gui="clr-namespace:ICSharpCode.SharpDevelop.Gui;assembly=ICSharpCode.SharpDevelop"
xmlns:debugger="clr-namespace:ICSharpCode.SharpDevelop.Services;assembly=Debugger.AddIn"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:widgets="http://icsharpcode.net/sharpdevelop/widgets">
<StackPanel>
<GroupBox Margin="5" Header="{sd:Localize Dialog.Options.IDEOptions.Debugging.Stepping}">
<widgets:StackPanelWithSpacing SpaceBetweenItems="5">
<CheckBox x:Name="chbEnableJustMyCode"
Content="{sd:Localize Dialog.Options.IDEOptions.Debugging.Stepping.EnableJustMyCode}"
IsChecked="{sd:OptionBinding debugger:DebuggingOptions.EnableJustMyCode}" />
<CheckBox x:Name="chbStepOverNoSymbols"
Content="{sd:Localize Dialog.Options.IDEOptions.Debugging.Stepping.StepOverNoSymbols}"
IsChecked="{sd:OptionBinding debugger:DebuggingOptions.StepOverNoSymbols}" />
<CheckBox x:Name="chbStepOverDebuggerAttributes"
Content="{sd:Localize Dialog.Options.IDEOptions.Debugging.Stepping.StepOverDebuggerAttributes}"
IsChecked="{sd:OptionBinding debugger:DebuggingOptions.StepOverDebuggerAttributes}" />
<CheckBox Content="{sd:Localize Dialog.Options.IDEOptions.Debugging.Stepping.DecompileCodeWithoutSymbols}"
IsChecked="{sd:OptionBinding debugger:DebuggingOptions.DecompileCodeWithoutSymbols}" />
<CheckBox x:Name="chbStepOverAllProperties"
Checked="ChbStepOverAllProperties_CheckedChanged"
Unchecked="ChbStepOverAllProperties_CheckedChanged"
Content="{sd:Localize Dialog.Options.IDEOptions.Debugging.Stepping.StepOverAllProperties}"
IsChecked="{sd:OptionBinding debugger:DebuggingOptions.StepOverAllProperties}" />
<CheckBox x:Name="chbStepOverSingleLineProperties"
Content="{sd:Localize Dialog.Options.IDEOptions.Debugging.Stepping.StepOverSingleLineProperties}"
IsChecked="{sd:OptionBinding debugger:DebuggingOptions.StepOverSingleLineProperties}" />
<CheckBox x:Name="chbStepOverFieldAccessProperties"
Content="{sd:Localize Dialog.Options.IDEOptions.Debugging.Stepping.StepOverFieldAccessProperties}"
IsChecked="{sd:OptionBinding debugger:DebuggingOptions.StepOverFieldAccessProperties}" />
</widgets:StackPanelWithSpacing>
</GroupBox>
</GroupBox>
<GroupBox Margin="5" Header="{sd:Localize Dialog.Options.IDEOptions.Debugging.Exceptions}">
<widgets:StackPanelWithSpacing SpaceBetweenItems="5">
<CheckBox x:Name="chbPauseOnHandledExceptions"
Content="{sd:Localize Dialog.Options.IDEOptions.Debugging.PauseOnHandledExceptions}"
IsChecked="{sd:OptionBinding debugger:DebuggingOptions.PauseOnHandledExceptions}" />
<CheckBox x:Name="chbPauseOnHandledExceptions"
Content="{sd:Localize Dialog.Options.IDEOptions.Debugging.PauseOnHandledExceptions}"
IsChecked="{sd:OptionBinding debugger:DebuggingOptions.PauseOnHandledExceptions}" />
</widgets:StackPanelWithSpacing>
</GroupBox>
</StackPanel>
</StackPanel>
</gui:OptionPanel>

2
src/AddIns/Debugger/Debugger.AddIn/Pads/CallStackPad.xaml.cs

@ -118,7 +118,7 @@ namespace ICSharpCode.SharpDevelop.Gui.Pads @@ -118,7 +118,7 @@ namespace ICSharpCode.SharpDevelop.Gui.Pads
if (item.Frame != null && debuggedProcess.SelectedThread != null) {
// check for options - if these options are enabled, selecting the frame should not continue
if (!item.Frame.HasSymbols && (debuggedProcess.Options.EnableJustMyCode || debuggedProcess.Options.StepOverNoSymbols)) {
if (!item.Frame.HasSymbols && !debuggedProcess.Options.DecompileCodeWithoutSymbols) {
MessageService.ShowMessage("${res:MainWindow.Windows.Debug.CallStack.CannotSwitchWithoutSymbolsOrDecompiledCodeOptions}",
"${res:MainWindow.Windows.Debug.CallStack.FunctionSwitch}");
return;

10
src/AddIns/Debugger/Debugger.AddIn/Pads/RunningThreadsPad.cs

@ -103,14 +103,14 @@ namespace ICSharpCode.SharpDevelop.Gui.Pads @@ -103,14 +103,14 @@ namespace ICSharpCode.SharpDevelop.Gui.Pads
void RunningThreadsListItemActivate(object sender, EventArgs e)
{
if (debuggedProcess.IsPaused) {
if (debuggedProcess != null) {
if (debuggedProcess != null) {
if (debuggedProcess.IsPaused) {
ThreadModel obj = runningThreadsList.SelectedItems[0] as ThreadModel;
Thread thread = obj.Thread;
// check for options - if these options are enabled, selecting the frame should not continue
if ((thread.MostRecentStackFrame == null || !thread.MostRecentStackFrame.HasSymbols) &&
(debuggedProcess.Options.EnableJustMyCode || debuggedProcess.Options.StepOverNoSymbols)) {
!DebuggingOptions.Instance.DecompileCodeWithoutSymbols) {
MessageService.ShowMessage("${res:MainWindow.Windows.Debug.Threads.CannotSwitchWithoutDecompiledCodeOptions}",
"${res:MainWindow.Windows.Debug.Threads.ThreadSwitch}");
return;
@ -124,9 +124,9 @@ namespace ICSharpCode.SharpDevelop.Gui.Pads @@ -124,9 +124,9 @@ namespace ICSharpCode.SharpDevelop.Gui.Pads
} else {
MessageService.ShowMessage("${res:MainWindow.Windows.Debug.Threads.CannotSwitchOnNAFrame}", "${res:MainWindow.Windows.Debug.Threads.ThreadSwitch}");
}
} else {
MessageService.ShowMessage("${res:MainWindow.Windows.Debug.Threads.CannotSwitchWhileRunning}", "${res:MainWindow.Windows.Debug.Threads.ThreadSwitch}");
}
} else {
MessageService.ShowMessage("${res:MainWindow.Windows.Debug.Threads.CannotSwitchWhileRunning}", "${res:MainWindow.Windows.Debug.Threads.ThreadSwitch}");
}
}

7
src/AddIns/Debugger/Debugger.AddIn/Service/WindowsDebugger.cs

@ -942,7 +942,7 @@ namespace ICSharpCode.SharpDevelop.Services @@ -942,7 +942,7 @@ namespace ICSharpCode.SharpDevelop.Services
}
// check for options - if these options are enabled, debugging decompiled code should not continue
if (debuggedProcess.Options.EnableJustMyCode || debuggedProcess.Options.StepOverNoSymbols) {
if (!debuggedProcess.Options.DecompileCodeWithoutSymbols) {
LoggingService.Info("Decompiled code debugging is disabled!");
return;
}
@ -961,13 +961,14 @@ namespace ICSharpCode.SharpDevelop.Services @@ -961,13 +961,14 @@ namespace ICSharpCode.SharpDevelop.Services
// update marker & navigate to line
NavigationService.NavigateTo(debugType.DebugModule.FullPath,
debugType.FullNameWithoutGenericArguments,
string.Empty,
IDStringProvider.GetIDString(frame.MethodInfo),
line);
} else {
// no line => do decompilation
NavigationService.NavigateTo(debugType.DebugModule.FullPath,
debugType.FullNameWithoutGenericArguments,
string.Empty);
IDStringProvider.GetIDString(frame.MethodInfo));
}
}

1
src/AddIns/Debugger/Debugger.Core/Debugger.Core.csproj

@ -56,6 +56,7 @@ @@ -56,6 +56,7 @@
<Reference Include="System.Windows.Forms" />
</ItemGroup>
<ItemGroup>
<Compile Include="IDStringProvider.cs" />
<Compile Include="Interop\MTA2STA.cs" />
<Compile Include="ManagedCallback.cs" />
<Compile Include="ManagedCallbackProxy.cs" />

152
src/AddIns/Debugger/Debugger.Core/IDStringProvider.cs

@ -0,0 +1,152 @@ @@ -0,0 +1,152 @@
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Text;
namespace Debugger
{
/// <summary>
/// Description of IDStringProvider.
/// </summary>
public static class IDStringProvider
{
/// <summary>
/// Gets the ID string (C# 4.0 spec, §A.3.1) for the specified entity.
/// </summary>
public static string GetIDString(MemberInfo member)
{
StringBuilder b = new StringBuilder();
if (member is Type) {
b.Append("T:");
AppendTypeName(b, (Type)member);
} else {
if (member is FieldInfo)
b.Append("F:");
else if (member is PropertyInfo)
b.Append("P:");
else if (member is EventInfo)
b.Append("E:");
else if (member is MethodBase)
b.Append("M:");
AppendTypeName(b, member.DeclaringType);
b.Append('.');
b.Append(member.Name.Replace('.', '#'));
IList<ParameterInfo> parameters;
Type explicitReturnType = null;
if (member is PropertyInfo) {
parameters = ((PropertyInfo)member).GetIndexParameters();
} else if (member is MethodInfo) {
MethodInfo mr = (MethodInfo)member;
if (mr.IsGenericMethod) {
b.Append("``");
b.Append(mr.GetGenericArguments().Length);
}
parameters = mr.GetParameters();
if (mr.Name == "op_Implicit" || mr.Name == "op_Explicit") {
explicitReturnType = mr.ReturnType;
}
} else {
parameters = null;
}
if (parameters != null && parameters.Count > 0) {
b.Append('(');
for (int i = 0; i < parameters.Count; i++) {
if (i > 0) b.Append(',');
AppendTypeName(b, parameters[i].ParameterType);
}
b.Append(')');
}
if (explicitReturnType != null) {
b.Append('~');
AppendTypeName(b, explicitReturnType);
}
}
return b.ToString();
}
static void AppendTypeName(StringBuilder b, Type type)
{
if (type == null) {
return;
}
if (type.IsGenericType) {
AppendTypeNameWithArguments(b, type.GetElementType(), type.GetGenericArguments());
} else if (type.HasElementType) {
AppendTypeName(b, type.GetElementType());
if (type.IsArray) {
b.Append('[');
for (int i = 0; i < type.GetArrayRank(); i++) {
if (i > 0)
b.Append(',');
b.Append("0:");
}
b.Append(']');
}
if (type.IsByRef) {
b.Append('@');
}
if (type.IsPointer) {
b.Append('*');
}
} else {
if (type.IsGenericParameter) {
b.Append('`');
if (type.DeclaringMethod != null) {
b.Append('`');
}
b.Append(type.GenericParameterPosition);
} else if (type.DeclaringType != null) {
AppendTypeName(b, type.DeclaringType);
b.Append('.');
b.Append(type.Name);
} else {
b.Append(type.FullName);
}
}
}
static int AppendTypeNameWithArguments(StringBuilder b, Type type, IList<Type> genericArguments)
{
int outerTypeParameterCount = 0;
if (type.DeclaringType != null) {
Type declType = type.DeclaringType;
outerTypeParameterCount = AppendTypeNameWithArguments(b, declType, genericArguments);
b.Append('.');
} else if (!string.IsNullOrEmpty(type.Namespace)) {
b.Append(type.Namespace);
b.Append('.');
}
int localTypeParameterCount = 0;
b.Append(SplitTypeParameterCountFromReflectionName(type.Name, out localTypeParameterCount));
if (localTypeParameterCount > 0) {
int totalTypeParameterCount = outerTypeParameterCount + localTypeParameterCount;
b.Append('{');
for (int i = outerTypeParameterCount; i < totalTypeParameterCount && i < genericArguments.Count; i++) {
if (i > outerTypeParameterCount) b.Append(',');
AppendTypeName(b, genericArguments[i]);
}
b.Append('}');
}
return outerTypeParameterCount + localTypeParameterCount;
}
static string SplitTypeParameterCountFromReflectionName(string reflectionName, out int typeParameterCount)
{
int pos = reflectionName.LastIndexOf('`');
if (pos < 0) {
typeParameterCount = 0;
return reflectionName;
} else {
string typeCount = reflectionName.Substring(pos + 1);
if (int.TryParse(typeCount, out typeParameterCount))
return reflectionName.Substring(0, pos);
else
return reflectionName;
}
}
}
}

8
src/AddIns/Debugger/Debugger.Core/MetaData/DebugMethodInfo.cs

@ -187,12 +187,12 @@ namespace Debugger.MetaData @@ -187,12 +187,12 @@ namespace Debugger.MetaData
/// <inheritdoc/>
public override bool IsGenericMethod {
get { throw new NotSupportedException(); }
get { return methodDefSig.GenericParameterCount > 0; }
}
/// <inheritdoc/>
public override bool IsGenericMethodDefinition {
get { throw new NotSupportedException(); }
get { return methodDefSig.GenericParameterCount > 0; }
}
/// <inheritdoc/>
@ -294,10 +294,12 @@ namespace Debugger.MetaData @@ -294,10 +294,12 @@ namespace Debugger.MetaData
}
/// <summary> Gets value indicating whether this method should be stepped over
/// accoring to current options </summary>
/// according to current options </summary>
public bool StepOver {
get {
Options opt = this.Process.Options;
if (opt.DecompileCodeWithoutSymbols)
return false;
if (opt.StepOverNoSymbols) {
if (this.SymMethod == null) return true;
}

2
src/AddIns/Debugger/Debugger.Core/Module.cs

@ -336,7 +336,7 @@ namespace Debugger @@ -336,7 +336,7 @@ namespace Debugger
}
/// <summary> Sets all code as being 'my code'. The code will be gradually
/// set to not-user-code as encountered acording to stepping options </summary>
/// set to not-user-code as encountered according to stepping options </summary>
public void ResetJustMyCodeStatus()
{
uint unused = 0;

1
src/AddIns/Debugger/Debugger.Core/Options.cs

@ -31,5 +31,6 @@ namespace Debugger @@ -31,5 +31,6 @@ namespace Debugger
public string[] SymbolsSearchPaths { get; set; }
public bool SuspendOtherThreads { get; set; }
public bool PauseOnHandledExceptions { get; set; }
public bool DecompileCodeWithoutSymbols { get; set; }
}
}

12
src/AddIns/DisplayBindings/ILSpyAddIn/NavigateToDecompiledEntityService.cs

@ -66,13 +66,16 @@ namespace ICSharpCode.ILSpyAddIn @@ -66,13 +66,16 @@ namespace ICSharpCode.ILSpyAddIn
if (string.IsNullOrEmpty(typeName))
throw new ArgumentException("typeName is null or empty");
// jump to line number if the decompiled view content exits - no need for a new decompilation
// jump to line number if the decompiled view content exists - no need for a new decompilation
foreach (var viewContent in WorkbenchSingleton.Workbench.ViewContentCollection.OfType<DecompiledViewContent>()) {
if (string.Equals(viewContent.AssemblyFile, assemblyFile, StringComparison.OrdinalIgnoreCase) && typeName == viewContent.FullTypeName) {
if (updateMarker) {
viewContent.UpdateDebuggingUI();
}
viewContent.JumpToLineNumber(lineNumber);
if (lineNumber > 0)
viewContent.JumpToLineNumber(lineNumber);
else
viewContent.JumpToEntity(entityTag);
viewContent.WorkbenchWindow.SelectWindow();
return true;
}
@ -84,7 +87,10 @@ namespace ICSharpCode.ILSpyAddIn @@ -84,7 +87,10 @@ namespace ICSharpCode.ILSpyAddIn
if (updateMarker) {
decompiledView.UpdateDebuggingUI();
}
decompiledView.JumpToLineNumber(lineNumber);
if (lineNumber > 0)
decompiledView.JumpToLineNumber(lineNumber);
else
decompiledView.JumpToEntity(entityTag);
};
WorkbenchSingleton.Workbench.ShowView(decompiledView);
return true;

Loading…
Cancel
Save