public SoftEvaluationContext(SoftDebuggerSession session, StackFrame frame, DC.EvaluationOptions options) : base(options) { Frame = frame; Thread = frame.Thread; Domain = frame.Domain; string method = frame.Method.Name; if (frame.Method.DeclaringType != null) { method = frame.Method.DeclaringType.FullName + "." + method; } var sourceLink = session.GetSourceLink(frame.Method, frame.FileName); var location = new DC.SourceLocation(method, frame.FileName, frame.LineNumber, frame.ColumnNumber, frame.EndLineNumber, frame.EndColumnNumber, frame.Location.SourceFileHash, sourceLink); string language; if (frame.Method != null) { language = frame.IsNativeTransition ? "Transition" : "Managed"; } else { language = "Native"; } Evaluator = session.GetEvaluator(new DC.StackFrame(frame.ILOffset, location, language, session.IsExternalCode(frame), true)); Adapter = session.Adaptor; this.session = session; stackVersion = session.StackVersion; sourceAvailable = !string.IsNullOrEmpty(frame.FileName) && System.IO.File.Exists(frame.FileName); }
DC.StackFrame CreateStackFrame(MDB.StackFrame frame, int frameIndex) { MDB.MethodMirror method = frame.Method; MDB.TypeMirror type = method.DeclaringType; string fileName = frame.FileName; string typeFullName = null; string typeFQN = null; string methodName; if (fileName != null) { fileName = SoftDebuggerSession.NormalizePath(fileName); } if (method.VirtualMachine.Version.AtLeast(2, 12) && method.IsGenericMethod) { StringBuilder name = new StringBuilder(method.Name); name.Append('<'); if (method.VirtualMachine.Version.AtLeast(2, 15)) { bool first = true; foreach (var argumentType in method.GetGenericArguments()) { if (!first) { name.Append(", "); } name.Append(session.Adaptor.GetDisplayTypeName(argumentType.FullName)); first = false; } } name.Append('>'); methodName = name.ToString(); } else { methodName = method.Name; } if (string.IsNullOrEmpty(methodName)) { methodName = "[Function Without Name]"; } // Compiler generated anonymous/lambda methods bool special_method = false; if (methodName [0] == '<' && methodName.Contains(">m__")) { int nidx = methodName.IndexOf(">m__", StringComparison.Ordinal) + 2; methodName = "AnonymousMethod" + methodName.Substring(nidx, method.Name.Length - nidx); special_method = true; } if (type != null) { string typeDisplayName = session.Adaptor.GetDisplayTypeName(type.FullName); if (SoftDebuggerAdaptor.IsGeneratedType(type)) { // The user-friendly method name is embedded in the generated type name var mn = SoftDebuggerAdaptor.GetNameFromGeneratedType(type); // Strip off the generated type name int dot = typeDisplayName.LastIndexOf('.'); var tname = typeDisplayName.Substring(0, dot); // Keep any type arguments int targs = typeDisplayName.LastIndexOf('<'); if (targs > dot + 1) { mn += typeDisplayName.Substring(targs, typeDisplayName.Length - targs); } typeDisplayName = tname; if (special_method) { typeDisplayName += "." + mn; } else { methodName = mn; } } methodName = typeDisplayName + "." + methodName; typeFQN = type.Module.FullyQualifiedName; typeFullName = type.FullName; } bool external = false; bool hidden = false; if (session.VirtualMachine.Version.AtLeast(2, 21)) { var ctx = GetEvaluationContext(frameIndex, session.EvaluationOptions); var hiddenAttr = session.Adaptor.GetType(ctx, "System.Diagnostics.DebuggerHiddenAttribute") as MDB.TypeMirror; hidden = method.GetCustomAttributes(hiddenAttr, true).Any(); } if (hidden) { external = true; } else { external = session.IsExternalCode(frame); if (!external && session.Options.ProjectAssembliesOnly && session.VirtualMachine.Version.AtLeast(2, 21)) { var ctx = GetEvaluationContext(frameIndex, session.EvaluationOptions); var nonUserCodeAttr = session.Adaptor.GetType(ctx, "System.Diagnostics.DebuggerNonUserCodeAttribute") as MDB.TypeMirror; external = method.GetCustomAttributes(nonUserCodeAttr, true).Any(); } } var sourceLink = session.GetSourceLink(frame.Method, frame.FileName); var location = new DC.SourceLocation(methodName, fileName, frame.LineNumber, frame.ColumnNumber, frame.Location.EndLineNumber, frame.Location.EndColumnNumber, frame.Location.SourceFileHash, sourceLink); string addressSpace = string.Empty; bool hasDebugInfo = false; string language; if (frame.Method != null) { if (frame.IsNativeTransition) { language = "Transition"; } else { addressSpace = method.FullName; language = "Managed"; hasDebugInfo = true; } } else { language = "Native"; } return(new SoftDebuggerStackFrame(frame, addressSpace, location, language, external, hasDebugInfo, hidden, typeFQN, typeFullName)); }