public GetMethods ( ) : Mono.Debugger.Soft.MethodMirror[] | ||
리턴 | Mono.Debugger.Soft.MethodMirror[] |
public ExpandedProperty(TypeMirror typeMirror, StackFrame frame, LocalVariable localVariable) { this.frame = frame; this.localVariable = localVariable; var properties = typeMirror.GetProperties().Cast<Mirror>(); var methods = typeMirror.GetMethods().Cast<Mirror>(); var fields = typeMirror.GetFields().Cast<Mirror>(); var children = properties.Concat(methods).Concat(fields); allProperties = children.ToList(); }
Location GetLocFromType (TypeMirror type, string file, int line) { Location target_loc = null; foreach (MethodMirror m in type.GetMethods ()) { foreach (Location l in m.Locations) { if (PathComparer.Compare (PathToFileName (l.SourceFile), file) == 0 && l.LineNumber == line) { target_loc = l; break; } } if (target_loc != null) break; } return target_loc; }
Location GetLocFromType (TypeMirror type, string file, int line, out bool genericMethod, out bool insideTypeRange) { Location target_loc = null; bool fuzzy = true; insideTypeRange = false; genericMethod = false; //Console.WriteLine ("Trying to resolve {0}:{1} in type {2}", file, line, type.Name); foreach (MethodMirror method in type.GetMethods ()) { int rangeFirstLine = int.MaxValue; int rangeLastLine = -1; foreach (Location location in method.Locations) { string srcFile = location.SourceFile; //Console.WriteLine ("\tExamining {0}:{1}...", srcFile, location.LineNumber); if (srcFile != null && PathComparer.Compare (PathToFileName (NormalizePath (srcFile)), file) == 0) { if (location.LineNumber < rangeFirstLine) rangeFirstLine = location.LineNumber; if (location.LineNumber > rangeLastLine) rangeLastLine = location.LineNumber; if (line >= rangeFirstLine && line <= rangeLastLine) insideTypeRange = true; // If we are inserting a breakpoint in line L, but L+1 has the same IL offset as L, // pick the L+1 location, since that's where the debugger is going to stop. if (location.LineNumber >= line && line >= rangeFirstLine) { if (target_loc != null) { if (location.LineNumber > line) { if (target_loc.LineNumber - line > location.LineNumber - line) { // Grab the location closest to the requested line //Console.WriteLine ("\t\tLocation is closest match"); target_loc = location; } else if (location.ILOffset == target_loc.ILOffset) { // Grab the last location with the same ILOffset //Console.WriteLine ("\t\tLocation has same ILOffset"); target_loc = location; } } else { // Line number matches exactly //Console.WriteLine ("\t\tLocation matches exactly."); target_loc = location; fuzzy = false; } } else { //Console.WriteLine ("\t\tLocation is first possible match"); fuzzy = location.LineNumber != line; target_loc = location; } } } else { rangeFirstLine = int.MaxValue; rangeLastLine = -1; } } if (target_loc != null) { genericMethod = IsGenericMethod (method); // If we got a fuzzy match, then we need to make sure that there isn't a better // match in another method (e.g. code might have been extracted out into another // method by the compiler. if (!fuzzy) return target_loc; } } if (target_loc != null && fuzzy && CheckBetterMatch (type, file, line, target_loc)) { insideTypeRange = false; return null; } return target_loc; }
Location GetLocFromType (TypeMirror type, string file, int line, out bool genericMethod, out bool insideTypeRange) { Location target_loc = null; bool fuzzy = true; insideTypeRange = false; genericMethod = false; //Console.WriteLine ("Trying to resolve {0}:{1} in type {2}", file, line, type.Name); foreach (MethodMirror method in type.GetMethods ()) { int rangeFirstLine = int.MaxValue; int rangeLastLine = -1; foreach (Location location in method.Locations) { string srcFile = location.SourceFile; //Console.WriteLine ("\tExamining {0}:{1}...", srcFile, location.LineNumber); if (srcFile != null && PathsAreEqual (PathToFileName (NormalizePath (srcFile)), file)) { if (location.LineNumber < rangeFirstLine) rangeFirstLine = location.LineNumber; if (location.LineNumber > rangeLastLine) rangeLastLine = location.LineNumber; if (line >= rangeFirstLine && line <= rangeLastLine) insideTypeRange = true; if (location.LineNumber >= line && line >= rangeFirstLine) { if (target_loc != null) { if (location.LineNumber > line) { if (target_loc.LineNumber - line > location.LineNumber - line) { // Grab the location closest to the requested line //Console.WriteLine ("\t\tLocation is closest match. (ILOffset = 0x{0:x5})", location.ILOffset); target_loc = location; } } else if (target_loc.LineNumber != line) { // Previous match was a fuzzy match, but now we've found an exact line match //Console.WriteLine ("\t\tLocation is exact line match. (ILOffset = 0x{0:x5})", location.ILOffset); target_loc = location; fuzzy = false; } else if (location.ILOffset < target_loc.ILOffset) { // Line number matches exactly, but has an earlier ILOffset //Console.WriteLine ("\t\tLocation has an earlier ILOffset. (ILOffset = 0x{0:x5})", location.ILOffset); target_loc = location; fuzzy = false; } } else { //Console.WriteLine ("\t\tLocation is first possible match. (ILOffset = 0x{0:x5})", location.ILOffset); fuzzy = location.LineNumber != line; target_loc = location; } } } else { rangeFirstLine = int.MaxValue; rangeLastLine = -1; } } if (target_loc != null) { genericMethod = IsGenericMethod (method); // If we got a fuzzy match, then we need to make sure that there isn't a better // match in another method (e.g. code might have been extracted out into another // method by the compiler. if (!fuzzy) return target_loc; } } if (target_loc != null && fuzzy && CheckBetterMatch (type, file, line, target_loc)) { insideTypeRange = false; return null; } return target_loc; }
void ResolveBreakpoints (TypeMirror type) { var resolved = new List<BreakInfo> (); string typeName = type.FullName; Location loc; ProcessType (type); // First, resolve FunctionBreakpoints foreach (var bi in pending_bes.Where (b => b.BreakEvent is FunctionBreakpoint)) { var bp = (FunctionBreakpoint) bi.BreakEvent; int dot = bp.FunctionName.LastIndexOf ('.'); string ftypeName = bp.FunctionName.Substring (0, dot); if (ftypeName == typeName) { string methodName = bp.FunctionName.Substring (dot + 1); if (vm.Version.AtLeast (2, 6)) { foreach (var method in type.GetMethodsByNameFlags (methodName, BindingFlags.Default, false)) { if (!CheckMethodParams (method, bp.ParamTypes)) continue; loc = GetLocFromMethod (method); if (loc != null) { string paramList = bp.ParamTypes != null ? "(" + string.Join (",", bp.ParamTypes) + ")" : ""; OnDebuggerOutput (false, string.Format ("Resolved pending breakpoint for '{0}{1}' to {2}:{3} [0x{4:x5}].\n", bp.FunctionName, paramList, loc.SourceFile, loc.LineNumber, loc.ILOffset)); if (bp.ParamTypes == null) bp.ParamTypes = GetParamTypes (method); bp.SetResolvedFileName (loc.SourceFile); ResolvePendingBreakpoint (bi, loc); // Note: if the type or method is generic, there may be more instances so don't assume we are done resolving the breakpoint if (!type.IsGenericType && !IsGenericMethod (method)) resolved.Add (bi); break; } } } else { foreach (var method in type.GetMethods ()) { if (method.Name != methodName || !CheckMethodParams (method, bp.ParamTypes)) continue; loc = GetLocFromMethod (method); if (loc != null) { string paramList = bp.ParamTypes != null ? "(" + string.Join (",", bp.ParamTypes) + ")" : ""; OnDebuggerOutput (false, string.Format ("Resolved pending breakpoint for '{0}{1}' to {2}:{3} [0x{4:x5}].\n", bp.FunctionName, paramList, loc.SourceFile, loc.LineNumber, loc.ILOffset)); if (bp.ParamTypes == null) bp.ParamTypes = GetParamTypes (method); bp.SetResolvedFileName (loc.SourceFile); ResolvePendingBreakpoint (bi, loc); // Note: if the type or method is generic, there may be more instances so don't assume we are done resolving the breakpoint if (!type.IsGenericType /* && !IsGenericMethod (method)*/) resolved.Add (bi); break; } } } } } foreach (var be in resolved) pending_bes.Remove (be); resolved.Clear (); // Now resolve normal Breakpoints foreach (string s in type_to_source [type]) { foreach (var bi in pending_bes.Where (b => b.BreakEvent is Breakpoint)) { var bp = (Breakpoint) bi.BreakEvent; if (PathComparer.Compare (PathToFileName (bp.FileName), s) == 0) { bool insideLoadedRange; bool genericMethod; loc = GetLocFromType (type, s, bp.Line, out genericMethod, out insideLoadedRange); if (loc != null) { OnDebuggerOutput (false, string.Format ("Resolved pending breakpoint at '{0}:{1}' to {2} [0x{3:x5}].\n", s, bp.Line, loc.Method.FullName, loc.ILOffset)); ResolvePendingBreakpoint (bi, loc); // Note: if the type or method is generic, there may be more instances so don't assume we are done resolving the breakpoint if (!genericMethod && !type.IsGenericType) resolved.Add (bi); } else { if (insideLoadedRange) { bi.SetStatus (BreakEventStatus.Invalid, null); } } } } foreach (var be in resolved) pending_bes.Remove (be); resolved.Clear (); } // Thirdly, resolve pending catchpoints foreach (var bi in pending_bes.Where (b => b.BreakEvent is Catchpoint)) { var cp = (Catchpoint) bi.BreakEvent; if (cp.ExceptionName == typeName) { ResolvePendingCatchpoint (bi, type); resolved.Add (bi); } } foreach (var be in resolved) pending_bes.Remove (be); }
Location GetLocFromType (TypeMirror type, string file, int line, out bool insideTypeRange) { Location target_loc = null; insideTypeRange = false; foreach (MethodMirror m in type.GetMethods ()) { int rangeFirstLine = -1; int rangeLastLine = -1; foreach (Location l in m.Locations) { if (PathComparer.Compare (PathToFileName (l.SourceFile), file) == 0) { // If we are inserting a breakpoint in line L, but L+1 has the same IL offset as L, // pick the L+1 location, since that's where the debugger is going to stop. if (l.LineNumber == line) { if (target_loc == null) target_loc = l; } else if (target_loc != null) { if (target_loc.ILOffset == l.ILOffset) target_loc = l; else break; } rangeLastLine = l.LineNumber; if (rangeFirstLine == -1) rangeFirstLine = l.LineNumber; } else { if (rangeFirstLine != -1 && line >= rangeFirstLine && line <= rangeLastLine) { insideTypeRange = true; return null; } rangeFirstLine = -1; } } if (target_loc != null) break; if (rangeFirstLine != -1 && line >= rangeFirstLine && line <= rangeLastLine) { insideTypeRange = true; return null; } } return target_loc; }
Location GetLocFromType (TypeMirror type, string file, int line) { Location target_loc = null; foreach (MethodMirror m in type.GetMethods ()) { foreach (Location l in m.Locations) { if (PathComparer.Compare (PathToFileName (l.SourceFile), file) == 0) { // If we are inserting a breakpoint in line L, but L+1 has the same IL offset as L, // pick the L+1 location, since that's where the debugger is going to stop. if (l.LineNumber == line) { if (target_loc == null) target_loc = l; } else if (target_loc != null) { if (target_loc.ILOffset == l.ILOffset) target_loc = l; else break; } } } if (target_loc != null) break; } return target_loc; }
Location GetLocFromType (TypeMirror type, string file, int line) { Location target_loc = null; foreach (MethodMirror m in type.GetMethods ()) { foreach (Location l in m.Locations) { if (l.SourceFile == file && l.LineNumber == line) { target_loc = l; break; } } if (target_loc != null) break; } return target_loc; }
void MarkType( TypeMirror t ) { MarkAssembly( t.Assembly ); if ( loadedTypes.Contains( t.FullName ) ) return; Log("adding matched type {0}",t.FullName); loadedTypes.Add( t.FullName ); var meths = t.GetMethods (); // make a record for all methods defined by this type foreach (var m in meths) { CodeRecord rec; if (!records.TryGetValue (m.FullName, out rec)) { Log("adding matched method {0}",m.FullName); rec = new CodeRecord () { ClassName = m.DeclaringType.CSharpName, Assembly = m.DeclaringType.Assembly.GetName().FullName, Name = m.Name, FullMethodName = m.FullName, SourceFile = m.SourceFile, }; rec.AddLines( m.LineNumbers.ToArray() ); if (!bps.ContainsKey (m.FullName)) { bps [m.FullName] = new List<BreakPoint> (); // add a break on each line Log("adding {0} breakpoints", m.Locations.Count); foreach (var l in m.Locations) { var bp = VirtualMachine.CreateBreakpointRequest (l); var b = new BreakPoint () { Location = l, Record = rec, Request = bp }; bps [m.FullName].Add (b); rbps [bp] = b; bp.Enabled = true; } } records.Add (m.FullName, rec); DataStore.RegisterMethod (rec); } } }