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 location = new DC.SourceLocation(methodName, fileName, frame.LineNumber, frame.ColumnNumber, frame.Location.EndLineNumber, frame.Location.EndColumnNumber, frame.Location.SourceFileHash); 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)); }
DC.StackFrame CreateStackFrame(MDB.StackFrame frame) { 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; } // Compiler generated anonymous/lambda methods bool special_method = false; if (methodName [0] == '<' && methodName.Contains(">m__")) { int nidx = methodName.IndexOf(">m__") + 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; } var location = new DC.SourceLocation(methodName, fileName, frame.LineNumber); var external = session.IsExternalCode(frame); return(new SoftDebuggerStackFrame(frame, method.FullName, location, "Managed", external, true, typeFQN, typeFullName)); }