You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
158 lines
5.4 KiB
158 lines
5.4 KiB
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) |
|
// This code is distributed under the BSD license (for details please see \src\AddIns\Debugger\Debugger.AddIn\license.txt) |
|
|
|
using Debugger.Interop.CorDebug; |
|
using System; |
|
using System.Collections.Generic; |
|
using Debugger.MetaData; |
|
using ICSharpCode.SharpDevelop.Debugging; |
|
|
|
namespace Debugger.AddIn.TreeModel |
|
{ |
|
public class ICorDebug |
|
{ |
|
public class InfoNode: TreeNode |
|
{ |
|
List<TreeNode> children; |
|
|
|
public InfoNode(TreeNode parent, string name, string text) |
|
: this(parent, name, text, null) |
|
{ |
|
|
|
} |
|
|
|
public InfoNode(TreeNode parent, string name, string text, Func<TreeNode, List<TreeNode>> children) |
|
: base(parent) |
|
{ |
|
this.Name = name; |
|
this.Text = text; |
|
this.children = children(this); |
|
} |
|
|
|
public override IEnumerable<TreeNode> ChildNodes { |
|
get { return children; } |
|
} |
|
|
|
public void AddChild(string name, string text) |
|
{ |
|
if (children == null) { |
|
children = new List<TreeNode>(); |
|
} |
|
children.Add(new InfoNode(this, name, text)); |
|
} |
|
|
|
public void AddChild(string name, string text, Func<TreeNode, List<TreeNode>> subChildren) |
|
{ |
|
if (children == null) { |
|
children = new List<TreeNode>(); |
|
} |
|
children.Add(new InfoNode(this, name, text, p => subChildren(p))); |
|
} |
|
} |
|
|
|
public static InfoNode GetDebugInfoRoot(AppDomain appDomain, ICorDebugValue corValue) |
|
{ |
|
return new InfoNode(null, "ICorDebug", "", p => GetDebugInfo(p, appDomain, corValue)); |
|
} |
|
|
|
public static List<TreeNode> GetDebugInfo(TreeNode parent, AppDomain appDomain, ICorDebugValue corValue) |
|
{ |
|
List<TreeNode> items = new List<TreeNode>(); |
|
|
|
if (corValue is ICorDebugValue) { |
|
InfoNode info = new InfoNode(parent, "ICorDebugValue", ""); |
|
info.AddChild("Address", corValue.GetAddress().ToString("X8")); |
|
info.AddChild("Type", ((CorElementType)corValue.GetTheType()).ToString()); |
|
info.AddChild("Size", corValue.GetSize().ToString()); |
|
items.Add(info); |
|
} |
|
if (corValue is ICorDebugValue2) { |
|
InfoNode info = new InfoNode(parent, "ICorDebugValue2", ""); |
|
ICorDebugValue2 corValue2 = (ICorDebugValue2)corValue; |
|
string fullname; |
|
try { |
|
fullname = DebugType.CreateFromCorType(appDomain, corValue2.GetExactType()).FullName; |
|
} catch (DebuggerException e) { |
|
fullname = e.Message; |
|
} |
|
info.AddChild("ExactType", fullname); |
|
items.Add(info); |
|
} |
|
if (corValue is ICorDebugGenericValue) { |
|
InfoNode info = new InfoNode(parent, "ICorDebugGenericValue", ""); |
|
try { |
|
byte[] bytes = ((ICorDebugGenericValue)corValue).GetRawValue(); |
|
for(int i = 0; i < bytes.Length; i += 8) { |
|
string val = ""; |
|
for(int j = i; j < bytes.Length && j < i + 8; j++) { |
|
val += bytes[j].ToString("X2") + " "; |
|
} |
|
info.AddChild("Value" + i.ToString("X2"), val); |
|
} |
|
} catch (ArgumentException) { |
|
info.AddChild("Value", "N/A"); |
|
} |
|
items.Add(info); |
|
} |
|
if (corValue is ICorDebugReferenceValue) { |
|
InfoNode info = new InfoNode(parent, "ICorDebugReferenceValue", ""); |
|
ICorDebugReferenceValue refValue = (ICorDebugReferenceValue)corValue; |
|
info.AddChild("IsNull", (refValue.IsNull() != 0).ToString()); |
|
if (refValue.IsNull() == 0) { |
|
info.AddChild("Value", refValue.GetValue().ToString("X8")); |
|
if (refValue.Dereference() != null) { |
|
info.AddChild("Dereference", "", p => GetDebugInfo(p, appDomain, refValue.Dereference())); |
|
} else { |
|
info.AddChild("Dereference", "N/A"); |
|
} |
|
} |
|
items.Add(info); |
|
} |
|
if (corValue is ICorDebugHeapValue) { |
|
InfoNode info = new InfoNode(parent, "ICorDebugHeapValue", ""); |
|
items.Add(info); |
|
} |
|
if (corValue is ICorDebugHeapValue2) { |
|
InfoNode info = new InfoNode(parent, "ICorDebugHeapValue2", ""); |
|
items.Add(info); |
|
} |
|
if (corValue is ICorDebugObjectValue) { |
|
InfoNode info = new InfoNode(parent, "ICorDebugObjectValue", ""); |
|
ICorDebugObjectValue objValue = (ICorDebugObjectValue)corValue; |
|
info.AddChild("Class", objValue.GetClass().GetToken().ToString("X8")); |
|
info.AddChild("IsValueClass", (objValue.IsValueClass() != 0).ToString()); |
|
items.Add(info); |
|
} |
|
if (corValue is ICorDebugObjectValue2) { |
|
InfoNode info = new InfoNode(parent, "ICorDebugObjectValue2", ""); |
|
items.Add(info); |
|
} |
|
if (corValue is ICorDebugBoxValue) { |
|
InfoNode info = new InfoNode(parent, "ICorDebugBoxValue", ""); |
|
ICorDebugBoxValue boxValue = (ICorDebugBoxValue)corValue; |
|
info.AddChild("Object", "", p => GetDebugInfo(p, appDomain, boxValue.GetObject())); |
|
items.Add(info); |
|
} |
|
if (corValue is ICorDebugStringValue) { |
|
InfoNode info = new InfoNode(parent, "ICorDebugStringValue", ""); |
|
ICorDebugStringValue stringValue = (ICorDebugStringValue)corValue; |
|
info.AddChild("Length", stringValue.GetLength().ToString()); |
|
info.AddChild("String", stringValue.GetString()); |
|
items.Add(info); |
|
} |
|
if (corValue is ICorDebugArrayValue) { |
|
InfoNode info = new InfoNode(parent, "ICorDebugArrayValue", ""); |
|
info.AddChild("...", "..."); |
|
items.Add(info); |
|
} |
|
if (corValue is ICorDebugHandleValue) { |
|
InfoNode info = new InfoNode(parent, "ICorDebugHandleValue", ""); |
|
ICorDebugHandleValue handleValue = (ICorDebugHandleValue)corValue; |
|
info.AddChild("HandleType", handleValue.GetHandleType().ToString()); |
|
items.Add(info); |
|
} |
|
|
|
return items; |
|
} |
|
} |
|
}
|
|
|