1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313
|
using System;
using Mono.Debugging.Backend;
using System.Collections.Generic;
namespace Mono.Debugging.Client
{
[Serializable]
public class StackFrame
{
long address;
string addressSpace;
SourceLocation location;
IBacktrace sourceBacktrace;
string language;
int index;
bool isExternalCode;
bool isDebuggerHidden;
bool hasDebugInfo;
string fullModuleName;
string fullTypeName;
[NonSerialized]
DebuggerSession session;
public StackFrame (long address, string addressSpace, SourceLocation location, string language, bool isExternalCode, bool hasDebugInfo, bool isDebuggerHidden, string fullModuleName, string fullTypeName)
{
this.address = address;
this.addressSpace = addressSpace;
this.location = location;
this.language = language;
this.isExternalCode = isExternalCode;
this.isDebuggerHidden = isDebuggerHidden;
this.hasDebugInfo = hasDebugInfo;
this.fullModuleName = fullModuleName;
this.fullTypeName = fullTypeName;
}
public StackFrame (long address, string addressSpace, SourceLocation location, string language, bool isExternalCode, bool hasDebugInfo, string fullModuleName, string fullTypeName)
: this (address, addressSpace, location, language, isExternalCode, hasDebugInfo, false, fullModuleName, fullTypeName)
{
}
public StackFrame (long address, string addressSpace, SourceLocation location, string language)
: this (address, addressSpace, location, language, string.IsNullOrEmpty (location.FileName), true, "", "")
{
}
public StackFrame (long address, string addressSpace, string module, string method, string filename, int line, string language)
: this (address, addressSpace, new SourceLocation (method, filename, line), language)
{
}
public StackFrame (long address, SourceLocation location, string language, bool isExternalCode, bool hasDebugInfo)
: this (address, "", location, language, string.IsNullOrEmpty (location.FileName), true, "", "")
{
}
public StackFrame (long address, SourceLocation location, string language)
: this (address, "", location, language, string.IsNullOrEmpty (location.FileName), true, "", "")
{
}
internal void Attach (DebuggerSession session)
{
this.session = session;
}
public DebuggerSession DebuggerSession {
get { return session; }
}
public SourceLocation SourceLocation
{
get { return location; }
}
public long Address
{
get { return address; }
}
public string AddressSpace {
get { return addressSpace; }
}
internal IBacktrace SourceBacktrace {
get { return sourceBacktrace; }
set { sourceBacktrace = value; }
}
public int Index {
get { return index; }
internal set { index = value; }
}
public string Language {
get {
return language;
}
}
public bool IsExternalCode {
get { return isExternalCode; }
}
public bool IsDebuggerHidden {
get { return isDebuggerHidden; }
}
public bool HasDebugInfo {
get { return this.hasDebugInfo; }
}
public string FullModuleName {
get { return this.fullModuleName; }
}
public string FullTypeName {
get { return this.fullTypeName; }
}
public ObjectValue[] GetLocalVariables ()
{
return GetLocalVariables (session.EvaluationOptions);
}
public ObjectValue[] GetLocalVariables (EvaluationOptions options)
{
if (!hasDebugInfo)
return new ObjectValue [0];
ObjectValue[] values = sourceBacktrace.GetLocalVariables (index, options);
ObjectValue.ConnectCallbacks (this, values);
return values;
}
public ObjectValue[] GetParameters ()
{
return GetParameters (session.EvaluationOptions);
}
public ObjectValue[] GetParameters (EvaluationOptions options)
{
if (!hasDebugInfo)
return new ObjectValue [0];
ObjectValue[] values = sourceBacktrace.GetParameters (index, options);
ObjectValue.ConnectCallbacks (this, values);
return values;
}
public ObjectValue[] GetAllLocals ()
{
if (!hasDebugInfo)
return new ObjectValue [0];
IExpressionEvaluator evaluator = session.FindExpressionEvaluator (this);
if (evaluator != null)
return evaluator.GetLocals (this);
return GetAllLocals (session.EvaluationOptions);
}
public ObjectValue[] GetAllLocals (EvaluationOptions options)
{
if (!hasDebugInfo)
return new ObjectValue [0];
ObjectValue[] values = sourceBacktrace.GetAllLocals (index, options);
ObjectValue.ConnectCallbacks (this, values);
return values;
}
public ObjectValue GetThisReference ()
{
return GetThisReference (session.EvaluationOptions);
}
public ObjectValue GetThisReference (EvaluationOptions options)
{
if (!hasDebugInfo)
return null;
ObjectValue value = sourceBacktrace.GetThisReference (index, options);
if (value != null)
ObjectValue.ConnectCallbacks (this, value);
return value;
}
public ExceptionInfo GetException ()
{
return GetException (session.EvaluationOptions);
}
public ExceptionInfo GetException (EvaluationOptions options)
{
if (!hasDebugInfo)
return null;
ExceptionInfo value = sourceBacktrace.GetException (index, options);
if (value != null)
value.ConnectCallback (this);
return value;
}
public string ResolveExpression (string exp)
{
return session.ResolveExpression (exp, location);
}
public ObjectValue[] GetExpressionValues (string[] expressions, bool evaluateMethods)
{
EvaluationOptions options = session.EvaluationOptions.Clone ();
options.AllowMethodEvaluation = evaluateMethods;
return GetExpressionValues (expressions, options);
}
public ObjectValue[] GetExpressionValues (string[] expressions, EvaluationOptions options)
{
if (!hasDebugInfo) {
ObjectValue[] vals = new ObjectValue [expressions.Length];
for (int n=0; n<expressions.Length; n++)
vals [n] = ObjectValue.CreateUnknown (expressions [n]);
return vals;
}
if (options.UseExternalTypeResolver) {
string[] resolved = new string [expressions.Length];
for (int n=0; n<expressions.Length; n++)
resolved [n] = ResolveExpression (expressions [n]);
expressions = resolved;
}
ObjectValue[] values = sourceBacktrace.GetExpressionValues (index, expressions, options);
ObjectValue.ConnectCallbacks (this, values);
return values;
}
public ObjectValue GetExpressionValue (string expression, bool evaluateMethods)
{
EvaluationOptions options = session.EvaluationOptions.Clone ();
options.AllowMethodEvaluation = evaluateMethods;
return GetExpressionValue (expression, options);
}
public ObjectValue GetExpressionValue (string expression, EvaluationOptions options)
{
if (!hasDebugInfo)
return ObjectValue.CreateUnknown (expression);
if (options.UseExternalTypeResolver)
expression = ResolveExpression (expression);
ObjectValue[] values = sourceBacktrace.GetExpressionValues (index, new string[] { expression }, options);
ObjectValue.ConnectCallbacks (this, values);
return values [0];
}
/// <summary>
/// Returns True if the expression is valid and can be evaluated for this frame.
/// </summary>
public bool ValidateExpression (string expression)
{
return ValidateExpression (expression, session.EvaluationOptions);
}
/// <summary>
/// Returns True if the expression is valid and can be evaluated for this frame.
/// </summary>
public ValidationResult ValidateExpression (string expression, EvaluationOptions options)
{
if (options.UseExternalTypeResolver)
expression = ResolveExpression (expression);
return sourceBacktrace.ValidateExpression (index, expression, options);
}
public CompletionData GetExpressionCompletionData (string exp)
{
if (!hasDebugInfo)
return null;
return sourceBacktrace.GetExpressionCompletionData (index, exp);
}
// Returns disassembled code for this stack frame.
// firstLine is the relative code line. It can be negative.
public AssemblyLine[] Disassemble (int firstLine, int count)
{
return sourceBacktrace.Disassemble (index, firstLine, count);
}
public override string ToString()
{
string loc;
if (location.Line != -1 && !string.IsNullOrEmpty (location.FileName))
loc = " at " + location.FileName + ":" + location.Line;
else if (!string.IsNullOrEmpty (location.FileName))
loc = " at " + location.FileName;
else
loc = "";
return String.Format("0x{0:X} in {1}{2}", address, location.MethodName, loc);
}
}
[Serializable]
public struct ValidationResult
{
readonly string message;
readonly bool isValid;
public ValidationResult (bool isValid, string message)
{
this.isValid = isValid;
this.message = message;
}
public bool IsValid { get { return isValid; } }
public string Message { get { return message; } }
public static implicit operator bool (ValidationResult result)
{
return result.isValid;
}
}
}
|