Browse Source

Skip single-line properties during debugging

git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/trunk@3208 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61
shortcuts
David Srbecký 17 years ago
parent
commit
aee0bef040
  1. BIN
      data/resources/StringResources.es-mx.resources
  2. BIN
      data/resources/StringResources.es.resources
  3. BIN
      data/resources/StringResources.nl.resources
  4. 12
      src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Options/DebuggingOptions.cs
  5. 26
      src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Options/DebuggingOptionsPanel.Designer.cs
  6. 4
      src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Options/DebuggingOptionsPanel.cs
  7. 143
      src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Control/Module.cs
  8. 39
      src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Control/NDebugger.Options.cs
  9. 27
      src/AddIns/Misc/Debugger/Debugger.Tests/Project/Src/TestPrograms/DebuggerAttributes.cs
  10. 10
      src/AddIns/Misc/Debugger/Debugger.Tests/Project/Src/TestPrograms/Metadata.cs
  11. BIN
      src/Main/StartUp/Project/Resources/StringResources.resources

BIN
data/resources/StringResources.es-mx.resources

Binary file not shown.

BIN
data/resources/StringResources.es.resources

Binary file not shown.

BIN
data/resources/StringResources.nl.resources

Binary file not shown.

12
src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Options/DebuggingOptions.cs

@ -60,6 +60,16 @@ namespace ICSharpCode.SharpDevelop.Services @@ -60,6 +60,16 @@ namespace ICSharpCode.SharpDevelop.Services
set { DebuggingProperties.Set("SymbolsSearchPaths", value); }
}
public static bool SkipProperties {
get { return DebuggingProperties.Get("SkipProperties", true); }
set { DebuggingProperties.Set("SkipProperties", value); }
}
public static bool SkipOnlySingleLineProperties {
get { return DebuggingProperties.Get("SkipOnlySingleLineProperties", true); }
set { DebuggingProperties.Set("SkipOnlySingleLineProperties", value); }
}
public static void ApplyToCurrentDebugger()
{
WindowsDebugger winDbg = DebuggerService.CurrentDebugger as WindowsDebugger;
@ -69,6 +79,8 @@ namespace ICSharpCode.SharpDevelop.Services @@ -69,6 +79,8 @@ namespace ICSharpCode.SharpDevelop.Services
debugger.JustMyCodeEnabled = JustMyCodeEnabled;
debugger.ObeyDebuggerAttributes = ObeyDebuggerAttributes;
debugger.SymbolsSearchPaths = SymbolsSearchPaths;
debugger.SkipProperties = SkipProperties;
debugger.SkipOnlySingleLineProperties = SkipOnlySingleLineProperties;
}
}
}

26
src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Options/DebuggingOptionsPanel.Designer.cs generated

@ -37,6 +37,8 @@ namespace ICSharpCode.SharpDevelop.Gui.OptionPanels @@ -37,6 +37,8 @@ namespace ICSharpCode.SharpDevelop.Gui.OptionPanels
{
this.jmc = new System.Windows.Forms.CheckBox();
this.obeyDebuggerAttributes = new System.Windows.Forms.CheckBox();
this.skipProperties = new System.Windows.Forms.CheckBox();
this.skipOnlySingleLineProperties = new System.Windows.Forms.CheckBox();
this.SuspendLayout();
//
// jmc
@ -59,10 +61,32 @@ namespace ICSharpCode.SharpDevelop.Gui.OptionPanels @@ -59,10 +61,32 @@ namespace ICSharpCode.SharpDevelop.Gui.OptionPanels
this.obeyDebuggerAttributes.Text = "${res:Dialog.Options.IDEOptions.Debugging.ObeyDebuggerAttributes}";
this.obeyDebuggerAttributes.UseVisualStyleBackColor = true;
//
// skipProperties
//
this.skipProperties.AutoSize = true;
this.skipProperties.Location = new System.Drawing.Point(37, 75);
this.skipProperties.Name = "skipProperties";
this.skipProperties.Size = new System.Drawing.Size(456, 24);
this.skipProperties.TabIndex = 2;
this.skipProperties.Text = "${res:Dialog.Options.IDEOptions.Debugging.SkipProperties}";
this.skipProperties.UseVisualStyleBackColor = true;
//
// skipOnlySingleLineProperties
//
this.skipOnlySingleLineProperties.AutoSize = true;
this.skipOnlySingleLineProperties.Location = new System.Drawing.Point(65, 105);
this.skipOnlySingleLineProperties.Name = "skipOnlySingleLineProperties";
this.skipOnlySingleLineProperties.Size = new System.Drawing.Size(561, 24);
this.skipOnlySingleLineProperties.TabIndex = 3;
this.skipOnlySingleLineProperties.Text = "${res:Dialog.Options.IDEOptions.Debugging.SkipOnlySingleLineProperties}";
this.skipOnlySingleLineProperties.UseVisualStyleBackColor = true;
//
// DebuggingOptionsPanel
//
this.AutoScaleDimensions = new System.Drawing.SizeF(9F, 20F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.Controls.Add(this.skipOnlySingleLineProperties);
this.Controls.Add(this.skipProperties);
this.Controls.Add(this.obeyDebuggerAttributes);
this.Controls.Add(this.jmc);
this.Name = "DebuggingOptionsPanel";
@ -70,6 +94,8 @@ namespace ICSharpCode.SharpDevelop.Gui.OptionPanels @@ -70,6 +94,8 @@ namespace ICSharpCode.SharpDevelop.Gui.OptionPanels
this.ResumeLayout(false);
this.PerformLayout();
}
private System.Windows.Forms.CheckBox skipOnlySingleLineProperties;
private System.Windows.Forms.CheckBox skipProperties;
private System.Windows.Forms.CheckBox obeyDebuggerAttributes;
private System.Windows.Forms.CheckBox jmc;
}

4
src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Options/DebuggingOptionsPanel.cs

@ -32,12 +32,16 @@ namespace ICSharpCode.SharpDevelop.Gui.OptionPanels @@ -32,12 +32,16 @@ namespace ICSharpCode.SharpDevelop.Gui.OptionPanels
{
jmc.Checked = DebuggingOptions.JustMyCodeEnabled;
obeyDebuggerAttributes.Checked = DebuggingOptions.ObeyDebuggerAttributes;
skipProperties.Checked = DebuggingOptions.SkipProperties;
skipOnlySingleLineProperties.Checked = DebuggingOptions.SkipOnlySingleLineProperties;
}
public override bool StorePanelContents()
{
DebuggingOptions.JustMyCodeEnabled = jmc.Checked;
DebuggingOptions.ObeyDebuggerAttributes = obeyDebuggerAttributes.Checked;
DebuggingOptions.SkipProperties = skipProperties.Checked;
DebuggingOptions.SkipOnlySingleLineProperties = skipOnlySingleLineProperties.Checked;
DebuggingOptions.ApplyToCurrentDebugger();

143
src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Control/Module.cs

@ -43,6 +43,12 @@ namespace Debugger @@ -43,6 +43,12 @@ namespace Debugger
}
}
NDebugger Debugger {
get {
return this.Process.Debugger;
}
}
public MetaDataImport MetaData {
get {
return metaData;
@ -170,7 +176,7 @@ namespace Debugger @@ -170,7 +176,7 @@ namespace Debugger
fullPath = pModule.Name;
LoadSymbols(process.Debugger.SymbolsSearchPaths);
SetJustMyCodeStatus(this.HasSymbols, process.Debugger.ObeyDebuggerAttributes);
SetJustMyCodeStatus();
}
public void LoadSymbols(string[] searchPath)
@ -187,66 +193,115 @@ namespace Debugger @@ -187,66 +193,115 @@ namespace Debugger
/// Finds all classes and methods marked with DebuggerNonUserCode attribute
/// and marks them for JMC so that they are not stepped into
/// </summary>
public void SetJustMyCodeStatus(bool isMyCode, bool obeyAttributes)
public void SetJustMyCodeStatus()
{
DateTime start = Util.HighPrecisionTimer.Now;
uint unused = 0;
if (isMyCode) {
corModule.CastTo<ICorDebugModule2>().SetJMCStatus(1, 0, ref unused);
if (obeyAttributes) {
foreach(CustomAttributeProps ca in metaData.EnumCustomAttributeProps(0, 0)) {
MemberRefProps constructorMethod = metaData.GetMemberRefProps(ca.Type);
TypeRefProps attributeType = metaData.GetTypeRefProps(constructorMethod.DeclaringType);
if (attributeType.Name == "System.Diagnostics.DebuggerStepThroughAttribute" ||
attributeType.Name == "System.Diagnostics.DebuggerNonUserCodeAttribute" ||
attributeType.Name == "System.Diagnostics.DebuggerHiddenAttribute")
{
if (ca.Owner >> 24 == 0x02) { // TypeDef
ICorDebugClass2 corClass = corModule.GetClassFromToken(ca.Owner).CastTo<ICorDebugClass2>();
corClass.SetJMCStatus(0 /* false */);
this.Process.TraceMessage("Class {0} marked as non-user code", metaData.GetTypeDefProps(ca.Owner).Name);
}
if (ca.Owner >> 24 == 0x06) { // MethodDef
ICorDebugFunction2 corFunction = corModule.GetFunctionFromToken(ca.Owner).CastTo<ICorDebugFunction2>();
corFunction.SetJMCStatus(0 /* false */);
MethodProps methodProps = metaData.GetMethodProps(ca.Owner);
this.Process.TraceMessage("Function {0}.{1} marked as non-user code", metaData.GetTypeDefProps(methodProps.ClassToken).Name, methodProps.Name);
}
if (!this.HasSymbols) {
corModule.CastTo<ICorDebugModule2>().SetJMCStatus(0, 0, ref unused);
return;
}
// By default the code is my code
corModule.CastTo<ICorDebugModule2>().SetJMCStatus(1, 0, ref unused);
// Apply non-user code attributes
if (this.Debugger.ObeyDebuggerAttributes) {
foreach(CustomAttributeProps ca in metaData.EnumCustomAttributeProps(0, 0)) {
MemberRefProps constructorMethod = metaData.GetMemberRefProps(ca.Type);
TypeRefProps attributeType = metaData.GetTypeRefProps(constructorMethod.DeclaringType);
if (attributeType.Name == "System.Diagnostics.DebuggerStepThroughAttribute" ||
attributeType.Name == "System.Diagnostics.DebuggerNonUserCodeAttribute" ||
attributeType.Name == "System.Diagnostics.DebuggerHiddenAttribute")
{
if (ca.Owner >> 24 == 0x02) { // TypeDef
ICorDebugClass2 corClass = corModule.GetClassFromToken(ca.Owner).CastTo<ICorDebugClass2>();
corClass.SetJMCStatus(0 /* false */);
this.Process.TraceMessage("Class {0} marked as non-user code", metaData.GetTypeDefProps(ca.Owner).Name);
}
if (ca.Owner >> 24 == 0x06) { // MethodDef
DisableJustMyCode(ca.Owner);
}
}
}
}
// Mark generated constructors as non-user code
foreach(uint typeDef in metaData.EnumTypeDefs()) {
foreach(uint methodDef in metaData.EnumMethodsWithName(typeDef, ".ctor")) {
try {
this.SymReader.GetMethod(methodDef);
} catch (COMException) { // Symbols not found
DisableJustMyCode(methodDef);
}
}
foreach(uint methodDef in metaData.EnumMethodsWithName(typeDef, ".cctor")) {
try {
this.SymReader.GetMethod(methodDef);
} catch (COMException) { // Symbols not found
DisableJustMyCode(methodDef);
}
}
// Mark generated constructors as non-user code
if (this.HasSymbols) {
foreach(TypeDefProps typeDef in metaData.EnumTypeDefProps()) {
foreach(MethodProps methodDef in metaData.EnumMethodPropsWithName(typeDef.Token, ".ctor")) {
try {
this.SymReader.GetMethod(methodDef.Token);
} catch (COMException) {
// Symbols not found
ICorDebugFunction2 corFunction = corModule.GetFunctionFromToken(methodDef.Token).CastTo<ICorDebugFunction2>();
corFunction.SetJMCStatus(0 /* false */);
this.Process.TraceMessage("Constructor of {0} marked as non-user code", metaData.GetTypeDefProps(methodDef.ClassToken).Name);
}
// Skip properties
if (this.Debugger.SkipProperties) {
foreach(uint typeDef in metaData.EnumTypeDefs()) {
foreach(PropertyProps prop in metaData.EnumPropertyProps(typeDef)) {
if ((prop.GetterMethod & 0xFFFFFF) != 0) {
if (!Debugger.SkipOnlySingleLineProperties || IsSingleLine(prop.GetterMethod)) {
DisableJustMyCode(prop.GetterMethod);
}
}
foreach(MethodProps methodDef in metaData.EnumMethodPropsWithName(typeDef.Token, ".cctor")) {
try {
this.SymReader.GetMethod(methodDef.Token);
} catch (COMException) {
// Symbols not found
ICorDebugFunction2 corFunction = corModule.GetFunctionFromToken(methodDef.Token).CastTo<ICorDebugFunction2>();
corFunction.SetJMCStatus(0 /* false */);
this.Process.TraceMessage("Static constructor of {0} marked as non-user code", metaData.GetTypeDefProps(methodDef.ClassToken).Name);
if ((prop.SetterMethod & 0xFFFFFF) != 0) {
if (!Debugger.SkipOnlySingleLineProperties || IsSingleLine(prop.SetterMethod)) {
DisableJustMyCode(prop.SetterMethod);
}
}
}
}
} else {
corModule.CastTo<ICorDebugModule2>().SetJMCStatus(0, 0, ref unused);
}
DateTime end = Util.HighPrecisionTimer.Now;
this.Process.TraceMessage("Set Just-My-Code for module \"{0}\" ({1} ms)", this.Filename, (end - start).TotalMilliseconds);
}
void DisableJustMyCode(uint methodDef)
{
MethodProps methodProps = metaData.GetMethodProps(methodDef);
TypeDefProps typeProps = metaData.GetTypeDefProps(methodProps.ClassToken);
ICorDebugFunction2 corFunction = corModule.GetFunctionFromToken(methodProps.Token).CastTo<ICorDebugFunction2>();
corFunction.SetJMCStatus(0 /* false */);
this.Process.TraceMessage("Funciton {0}.{1} marked as non-user code", typeProps.Name, methodProps.Name);
}
bool IsSingleLine(uint methodDef)
{
ISymUnmanagedMethod symMethod = this.SymReader.GetMethod(methodDef);
List<SequencePoint> seqPoints = new List<SequencePoint>(symMethod.SequencePoints);
seqPoints.Sort();
// Remove initial "{"
if (seqPoints.Count > 0 &&
seqPoints[0].Line == seqPoints[0].EndLine &&
seqPoints[0].EndColumn - seqPoints[0].Column <= 1) {
seqPoints.RemoveAt(0);
}
// Remove last "}"
int listIndex = seqPoints.Count - 1;
if (seqPoints.Count > 0 &&
seqPoints[listIndex].Line == seqPoints[listIndex].EndLine &&
seqPoints[listIndex].EndColumn - seqPoints[listIndex].Column <= 1) {
seqPoints.RemoveAt(listIndex);
}
// Is single line
return seqPoints.Count == 0 || seqPoints[0].Line == seqPoints[seqPoints.Count - 1].EndLine;
}
public void ApplyChanges(byte[] metadata, byte[] il)
{
if (corModule.Is<ICorDebugModule2>()) { // Is the debuggee .NET 2.0?

39
src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Control/NDebugger.Options.cs

@ -13,8 +13,19 @@ namespace Debugger @@ -13,8 +13,19 @@ namespace Debugger
{
bool justMyCodeEnabled = true;
bool obeyDebuggerAttributes = true;
bool skipProperties = true;
bool skipOnlySingleLineProperties = true;
string[] symbolsSearchPaths;
void ResetJustMyCodeInModules()
{
foreach(Process process in this.Processes) {
foreach(Module module in process.Modules) {
module.SetJustMyCodeStatus();
}
}
}
public bool JustMyCodeEnabled {
get { return justMyCodeEnabled; }
// Affects steppers during their creation so there is nothing to update
@ -26,16 +37,32 @@ namespace Debugger @@ -26,16 +37,32 @@ namespace Debugger
set {
if (obeyDebuggerAttributes != value) {
obeyDebuggerAttributes = value;
foreach(Process process in this.Processes) {
foreach(Module module in process.Modules) {
// Rechceck the module for attributes
module.SetJustMyCodeStatus(module.HasSymbols, obeyDebuggerAttributes);
}
}
ResetJustMyCodeInModules();
}
}
}
public bool SkipProperties {
get { return skipProperties; }
set {
if (skipProperties != value) {
skipProperties = value;
ResetJustMyCodeInModules();
}
}
}
public bool SkipOnlySingleLineProperties {
get { return skipOnlySingleLineProperties; }
set {
if (skipOnlySingleLineProperties != value) {
skipOnlySingleLineProperties = value;
ResetJustMyCodeInModules();
}
}
}
public string[] SymbolsSearchPaths {
get { return symbolsSearchPaths; }
set {

27
src/AddIns/Misc/Debugger/Debugger.Tests/Project/Src/TestPrograms/DebuggerAttributes.cs

@ -20,6 +20,8 @@ namespace Debugger.Tests.TestPrograms @@ -20,6 +20,8 @@ namespace Debugger.Tests.TestPrograms
StepOut1();
IgnoredClass.Internal_Pass();
new DefaultCtorClass().Target();
int s = ShortProperty;
int l = LongProperty;
}
[DebuggerStepThrough]
@ -64,6 +66,19 @@ namespace Debugger.Tests.TestPrograms @@ -64,6 +66,19 @@ namespace Debugger.Tests.TestPrograms
}
}
public static int ShortProperty {
get {
return 1;
}
}
public static int LongProperty {
get {
return
1;
}
}
}
}
@ -88,19 +103,23 @@ namespace Debugger.Tests { @@ -88,19 +103,23 @@ namespace Debugger.Tests {
process.SelectedStackFrame.StepInto(); // StepOut1
Assert.AreEqual("StepOut2", process.SelectedStackFrame.MethodInfo.Name);
process.SelectedStackFrame.StepOut();
Assert.AreEqual("Main", process.SelectedStackFrame.MethodInfo.Name);
process.SelectedStackFrame.StepOver(); // Finish the step out
Assert.AreEqual("Main", process.SelectedStackFrame.MethodInfo.Name);
process.SelectedStackFrame.StepInto(); // IgnoredClass.Internal_Pass
Assert.AreEqual("Target", process.SelectedStackFrame.MethodInfo.Name);
process.SelectedStackFrame.StepOut();
Assert.AreEqual("Main", process.SelectedStackFrame.MethodInfo.Name);
process.SelectedStackFrame.StepOver(); // Finish the step out
Assert.AreEqual("Main", process.SelectedStackFrame.MethodInfo.Name);
process.SelectedStackFrame.StepInto(); // Generated default constructor
Assert.AreEqual("Target", process.SelectedStackFrame.MethodInfo.Name);
process.SelectedStackFrame.StepOut();
process.SelectedStackFrame.StepOver(); // Finish the step out
Assert.AreEqual("Main", process.SelectedStackFrame.MethodInfo.Name);
process.SelectedStackFrame.StepInto(); // ShortProperty
Assert.AreEqual("Main", process.SelectedStackFrame.MethodInfo.Name);
process.SelectedStackFrame.StepInto(); // LongProperty
Assert.AreEqual("get_LongProperty", process.SelectedStackFrame.MethodInfo.Name);
process.SelectedStackFrame.StepOut();
process.SelectedStackFrame.StepOver(); // Finish the step out
Assert.AreEqual("Main", process.SelectedStackFrame.MethodInfo.Name);
@ -131,6 +150,10 @@ namespace Debugger.Tests { @@ -131,6 +150,10 @@ namespace Debugger.Tests {
<DebuggingPaused>StepComplete</DebuggingPaused>
<DebuggingPaused>StepComplete</DebuggingPaused>
<DebuggingPaused>StepComplete</DebuggingPaused>
<DebuggingPaused>StepComplete</DebuggingPaused>
<DebuggingPaused>StepComplete</DebuggingPaused>
<DebuggingPaused>StepComplete</DebuggingPaused>
<DebuggingPaused>StepComplete</DebuggingPaused>
<ProcessExited />
</Test>
</DebuggerTests>

10
src/AddIns/Misc/Debugger/Debugger.Tests/Project/Src/TestPrograms/Metadata.cs

@ -142,7 +142,7 @@ namespace Debugger.Tests { @@ -142,7 +142,7 @@ namespace Debugger.Tests {
DeclaringType="Debugger.Tests.TestPrograms.Metadata"
FullName="Debugger.Tests.TestPrograms.Metadata.get_privateProperty"
IsInternal="False"
IsMyCode="True"
IsMyCode="False"
IsPrivate="True"
IsProtected="False"
IsPublic="False"
@ -156,7 +156,7 @@ namespace Debugger.Tests { @@ -156,7 +156,7 @@ namespace Debugger.Tests {
DeclaringType="Debugger.Tests.TestPrograms.Metadata"
FullName="Debugger.Tests.TestPrograms.Metadata.get_publicProperty"
IsInternal="False"
IsMyCode="True"
IsMyCode="False"
IsPrivate="False"
IsProtected="False"
IsPublic="True"
@ -170,7 +170,7 @@ namespace Debugger.Tests { @@ -170,7 +170,7 @@ namespace Debugger.Tests {
DeclaringType="Debugger.Tests.TestPrograms.Metadata"
FullName="Debugger.Tests.TestPrograms.Metadata.get_protectedProperty"
IsInternal="False"
IsMyCode="True"
IsMyCode="False"
IsPrivate="False"
IsProtected="True"
IsPublic="False"
@ -184,7 +184,7 @@ namespace Debugger.Tests { @@ -184,7 +184,7 @@ namespace Debugger.Tests {
DeclaringType="Debugger.Tests.TestPrograms.Metadata"
FullName="Debugger.Tests.TestPrograms.Metadata.get_internalProperty"
IsInternal="True"
IsMyCode="True"
IsMyCode="False"
IsPrivate="False"
IsProtected="False"
IsPublic="False"
@ -198,7 +198,7 @@ namespace Debugger.Tests { @@ -198,7 +198,7 @@ namespace Debugger.Tests {
DeclaringType="Debugger.Tests.TestPrograms.Metadata"
FullName="Debugger.Tests.TestPrograms.Metadata.get_staticProperty"
IsInternal="False"
IsMyCode="True"
IsMyCode="False"
IsPrivate="True"
IsProtected="False"
IsPublic="False"

BIN
src/Main/StartUp/Project/Resources/StringResources.resources

Binary file not shown.
Loading…
Cancel
Save