IEnumerator IEnumerable.GetEnumerator() { MDbgModule[] ret = new MDbgModule[m_items.Count]; m_items.Values.CopyTo(ret, 0); Array.Sort(ret); return(ret.GetEnumerator()); }
internal void BindBreakpoints(MDbgModule loadedModule) { foreach (MDbgBreakpoint b in m_items) { b.BindToModule(loadedModule); } }
internal void OnModuleUnloaded(MDbgModule unloadedModule) { foreach (MDbgBreakpoint b in m_items) { b.OnModuleUnloaded(unloadedModule); } }
IEnumerator IEnumerable.GetEnumerator() { MDbgModule[] ret = new MDbgModule[m_items.Count]; m_items.Values.CopyTo(ret, 0); Array.Sort(ret); return ret.GetEnumerator(); }
/// <summary> /// Event handler for a module unload /// </summary> /// <param name="module">Module that is being unloaded</param> public override void OnModuleUnloaded(MDbgModule module) { if (m_breakpoints != null) { m_breakpoints.Remove(module); } }
/// <summary> /// Function tries to bind a breakpoint to the specified module. /// </summary> /// <param name="managedModule">A module the breakpoint should be bound to.</param> /// <returns>true if breakpoint was successfully bound or false if it failed or was already bound.</returns> /// <remarks> /// This function is called by breakpoint manager for every brekapoint whenever a new module /// gets loaded into the debugged process or whenever a dynamic module loads a new class /// or new symbols. This adds any missing bindings, but will not duplicate any that already exist. /// </remarks> public sealed override bool BindToModule(MDbgModule managedModule) { List <MDbgFunction> funcs; int ILoffset; // If we already bound a breakpoint in this module then nothing to do if (m_breakpoints != null && m_breakpoints.ContainsKey(managedModule)) { return(false); } // If we can't resolve the location in this module then there is nothing to do if (!m_location.ResolveLocation(this, managedModule, out funcs, out ILoffset)) { return(false); } // Use the resolved information to get a raw CorBreakpoint object. CorFunctionBreakpoint breakpoint = null; try { if (ILoffset == 0) { foreach (var func in funcs) { breakpoint = func.CorFunction.CreateBreakpoint(); SetupBreakpoint(breakpoint, managedModule); } } else { foreach (var func in funcs) { // we need to set a breakpoint on code rather than directly on function CorCode code = func.CorFunction.ILCode; if (code == null) { throw new MDbgException(String.Format(CultureInfo.InvariantCulture, "IL Code for function {0} is null", new Object[] { func.FullName })); } breakpoint = code.CreateBreakpoint(ILoffset); SetupBreakpoint(breakpoint, managedModule); } } } catch (NotImplementedException) { return(false); } catch (COMException) { return(false); } return(true); }
internal MDbgFunction(MDbgModule managedModule, CorFunction managedFunction) { Debug.Assert(managedModule != null); Debug.Assert(managedFunction != null); Debug.Assert(managedFunction.Version >= 0 && managedFunction.Version - 1 <= managedModule.EditsCounter); // version numbers starts with 1 m_module = managedModule; m_function = managedFunction; EnsureIsUpToDate(); }
internal MDbgFunction(MDbgModule managedModule, CorFunction managedFunction) { Debug.Assert(managedModule != null); Debug.Assert(managedFunction != null); Debug.Assert(managedFunction.Version >= 0 && managedFunction.Version - 1 <= managedModule.EditsCounter); // version numbers starts with 1 m_module = managedModule; m_function = managedFunction; EnsureIsUpToDate(); }
bool IsNullableType(CorType ct) { if (ct.Type != CorElementType.ELEMENT_TYPE_VALUETYPE) { return(false); } MDbgModule m = m_process.Modules.Lookup(ct.Class.Module); String name = m.Importer.GetType(ct.Class.Token).FullName; return(name.Equals("System.Nullable`1")); }
/// <summary> /// Function tries to resolve the breakpoint from breakpoint description. /// </summary> /// <param name="functionBreakpoint">A breakpoint object.</param> /// <param name="managedModule">A module that the breakpoint should be resolved at.</param> /// <param name="managedFunction">A function that is resolved from the breakpoint description.</param> /// <param name="ILoffset">An il offset within a function resolved from the breakpoint description.</param> /// <returns>true if breakpoint was successfully resolved</returns> /// <remarks> /// Resolved is usually called for every loaded module. /// </remarks> public bool ResolveLocation(MDbgFunctionBreakpoint functionBreakpoint, MDbgModule managedModule, out List <MDbgFunction> managedFunction, out int ILoffset) { Debug.Assert(m_lineNo > 0 && m_file.Length > 0); managedFunction = null; ILoffset = 0; if (managedModule.SymReader == null) { // no symbols for current module, skip it. return(false); } foreach (ISymbolDocument doc in managedModule.SymReader.GetDocuments()) { if (String.Compare(doc.URL, m_file, true, CultureInfo.InvariantCulture) == 0 || String.Compare(System.IO.Path.GetFileName(doc.URL), m_file, true, CultureInfo.InvariantCulture) == 0) { int lineNo = 0; try { lineNo = doc.FindClosestLine(m_lineNo); } catch (System.Runtime.InteropServices.COMException e) { if (e.ErrorCode == (int)HResult.E_FAIL) { // we continue, because this location is not in this file, let's // keep trying to search for next file. continue; } } ISymbolMethod symMethod = managedModule.SymReader.GetMethodFromDocumentPosition(doc, lineNo, 0); managedFunction = new List <MDbgFunction>(); var func = managedModule.GetFunction(symMethod.Token.GetToken()); managedFunction.Add(func); ILoffset = func.GetIPFromPosition(doc, lineNo); // If this IL if (ILoffset == -1) { return(false); } Debug.Assert(ILoffset != -1); return(true); } } managedFunction = null; ILoffset = -1; return(false); }
internal MDbgModule Register(CorModule managedModule) { MDbgModule mdbgModule; if (m_items.ContainsKey(managedModule)) { mdbgModule = (MDbgModule)m_items[managedModule]; return(mdbgModule); } mdbgModule = new MDbgModule(m_process, managedModule, m_freeModuleNumber++); m_items.Add(managedModule, mdbgModule); return(mdbgModule); }
/// <summary> /// Function tries to resolve the breakpoint from breakpoint description. /// </summary> /// <param name="functionBreakpoint">A breakpoint object.</param> /// <param name="managedModule">A module that the breakpoint should be resolved at.</param> /// <param name="managedFunction">A function that is resolved from the breakpoint description.</param> /// <param name="ilOffset">An il offset within a function resolved from the breakpoint description.</param> /// <returns>true if breakpoint was successfully resolved</returns> /// <remarks> /// Resolved is usually called for every loaded module. /// </remarks> public bool ResolveLocation(MDbgFunctionBreakpoint functionBreakpoint, MDbgModule managedModule, out MDbgFunction managedFunction, out int ilOffset) { managedFunction = null; ilOffset = -1; // check if the function is from the module we specified. if (m_function.Module != managedModule) { return(false); } managedFunction = m_function; ilOffset = m_ILoffset; return(true); }
/// <summary> /// Function tries to resolve the breakpoint from breakpoint description. /// </summary> /// <param name="functionBreakpoint">A breakpoint object.</param> /// <param name="managedModule">A module that the breakpoint should be resolved at.</param> /// <param name="managedFunction">A function that is resolved from the breakpoint description.</param> /// <param name="ilOffset">An il offset within a function resolved from the breakpoint description.</param> /// <returns>true if breakpoint was successfully resolved</returns> /// <remarks> /// Resolved is usually called for every loaded module. /// </remarks> public bool ResolveLocation(MDbgFunctionBreakpoint functionBreakpoint, MDbgModule managedModule, out MDbgFunction managedFunction, out int ilOffset) { managedFunction = null; ilOffset = m_ILoffset; if (m_moduleName != null && m_moduleName.Length > 0) { if (!managedModule.MatchesModuleName(m_moduleName)) { return(false); } } managedFunction = functionBreakpoint.m_breakpointCollection.m_process.ResolveFunctionName(managedModule, m_className, m_methodName); return(managedFunction != null); }
/// <summary> /// Looks up a Module Name. /// </summary> /// <param name="moduleName">Which Module Name to lookup.</param> /// <returns>The coresponding MDbgModule with the given name.</returns> public MDbgModule Lookup(string moduleName) { MDbgModule matchedModule = null; foreach (MDbgModule module in m_items.Values) { if (module.MatchesModuleName(moduleName)) { if (matchedModule == null) { matchedModule = module; } else { throw new MDbgAmbiguousModuleNameException(); } } } return(matchedModule); }
private void SetupBreakpoint(CorFunctionBreakpoint breakpoint, MDbgModule managedModule) { // Add the new CorBreakpoint object to our internal list and register a handler for it. Debug.Assert(breakpoint != null); breakpoint.Activate(true); if (m_breakpoints == null) { m_breakpoints = new Dictionary <MDbgModule, List <CorFunctionBreakpoint> >(); } else if (m_breakpoints.ContainsKey(managedModule)) { m_breakpoints[managedModule].Add(breakpoint); } else { m_breakpoints[managedModule] = new List <CorFunctionBreakpoint>(); m_breakpoints[managedModule].Add(breakpoint); } MDbgProcess p = managedModule.Process; CustomBreakpointEventHandler handler = new CustomBreakpointEventHandler(this.InternalOnHitHandler); p.RegisterCustomBreakpoint(breakpoint, handler); }
/// <summary> /// Function tries to bind a breakpoint to the specified module. /// </summary> /// <param name="managedModule">A module the breakpoint should be bound to.</param> /// <returns>true if breakpoint was successfully bound or false if it failed or was already bound.</returns> /// <remarks> /// This function is called by breakpoint manager for every brekapoint whenever a new module /// gets loaded into the debugged process or whenever a dynamic module loads a new class /// or new symbols. This adds any missing bindings, but will not duplicate any that already exist. /// </remarks> public sealed override bool BindToModule(MDbgModule managedModule) { MDbgFunction func; int ILoffset; // Note that in some cases (eg. source/line breakpoints) we may actually // want to bind to multiple locations in this module instead of just one. if (!m_location.ResolveLocation(this, managedModule, out func, out ILoffset)) { return(false); } if (m_breakpoints != null) { // Assume all breakpoints are CorFunctionBreakpoints. // If this ever becomes invalid, we'll need a new check here to avoid // duplicating that type of breakpoint. foreach (CorFunctionBreakpoint cb in m_breakpoints) { // If we find a CorBreakpoint that already matches this location // don't add a new one, or the debugger will stop twice when it's hit. // Note that CorFunction instances are 1:1 with a specific function in a // specific module and AppDomain (but represents all generic instantiations). if (cb.Function == func.CorFunction && cb.Offset == ILoffset) { return(false); } } } // Use the resolved information to get a raw CorBreakpoint object. CorBreakpoint breakpoint = null; try { if (ILoffset == 0) { breakpoint = func.CorFunction.CreateBreakpoint(); } else { // we need to set a breakpoint on code rather than directly on function CorCode code = func.CorFunction.ILCode; if (code == null) { throw new MDbgException(String.Format(CultureInfo.InvariantCulture, "IL Code for function {0} is null", new Object[] { func.FullName })); } breakpoint = code.CreateBreakpoint(ILoffset); } } catch (COMException) { return(false); } // Add the new CorBreakpoint object to our internal list and register a handler for it. Debug.Assert(breakpoint != null); breakpoint.Activate(true); if (m_breakpoints == null) { m_breakpoints = new ArrayList(); } m_breakpoints.Add(breakpoint); MDbgProcess p = managedModule.Process; CustomBreakpointEventHandler handler = new CustomBreakpointEventHandler(this.InternalOnHitHandler); p.RegisterCustomBreakpoint(breakpoint, handler); return(true); }
// Print CorType to the given string builder. // Will print generic info. internal static void PrintCorType(StringBuilder sb, MDbgProcess proc, CorType ct) { switch (ct.Type) { case CorElementType.ELEMENT_TYPE_CLASS: case CorElementType.ELEMENT_TYPE_VALUETYPE: // We need to get the name from the metadata. We can get a cached metadata importer // from a MDbgModule, or we could get a new one from the CorModule directly. // Is this hash lookup to get a MDbgModule cheaper than just re-querying for the importer? CorClass cc = ct.Class; MDbgModule m = proc.Modules.Lookup(cc.Module); Type tn = m.Importer.GetType(cc.Token); sb.Append(tn.FullName); AddGenericArgs(sb, proc, ct.TypeParameters); return; // Primitives case CorElementType.ELEMENT_TYPE_BOOLEAN: sb.Append("System.Boolean"); return; case CorElementType.ELEMENT_TYPE_CHAR: sb.Append("System.Char"); return; case CorElementType.ELEMENT_TYPE_I1: sb.Append("System.SByte"); return; case CorElementType.ELEMENT_TYPE_U1: sb.Append("System.Byte"); return; case CorElementType.ELEMENT_TYPE_I2: sb.Append("System.Int16"); return; case CorElementType.ELEMENT_TYPE_U2: sb.Append("System.UInt16"); return; case CorElementType.ELEMENT_TYPE_I4: sb.Append("System.Int32"); return; case CorElementType.ELEMENT_TYPE_U4: sb.Append("System.Uint32"); return; case CorElementType.ELEMENT_TYPE_I8: sb.Append("System.Int64"); return; case CorElementType.ELEMENT_TYPE_U8: sb.Append("System.UInt64"); return; case CorElementType.ELEMENT_TYPE_I: sb.Append("System.IntPtr"); return; case CorElementType.ELEMENT_TYPE_U: sb.Append("System.UIntPtr"); return; case CorElementType.ELEMENT_TYPE_R4: sb.Append("System.Single"); return; case CorElementType.ELEMENT_TYPE_R8: sb.Append("System.Double"); return; // Well known class-types. case CorElementType.ELEMENT_TYPE_OBJECT: sb.Append("System.Object"); return; case CorElementType.ELEMENT_TYPE_STRING: sb.Append("System.String"); return; // Special compound types. Based off first type-param case CorElementType.ELEMENT_TYPE_SZARRAY: case CorElementType.ELEMENT_TYPE_ARRAY: case CorElementType.ELEMENT_TYPE_BYREF: case CorElementType.ELEMENT_TYPE_PTR: CorType t = ct.FirstTypeParameter; PrintCorType(sb, proc, t); switch (ct.Type) { case CorElementType.ELEMENT_TYPE_SZARRAY: sb.Append("[]"); return; case CorElementType.ELEMENT_TYPE_ARRAY: int rank = ct.Rank; sb.Append('['); for (int i = 0; i < rank - 1; i++) { sb.Append(','); } sb.Append(']'); return; case CorElementType.ELEMENT_TYPE_BYREF: sb.Append("&"); return; case CorElementType.ELEMENT_TYPE_PTR: sb.Append("*"); return; } Debug.Assert(false); // shouldn't have gotten here. return; case CorElementType.ELEMENT_TYPE_FNPTR: sb.Append("*(...)"); return; case CorElementType.ELEMENT_TYPE_TYPEDBYREF: sb.Append("typedbyref"); return; default: sb.Append("<unknown>"); return; } } // end PrintClass
/// <summary> /// Function tries to resolve the breakpoint from breakpoint description. /// </summary> /// <param name="functionBreakpoint">A breakpoint object.</param> /// <param name="managedModule">A module that the breakpoint should be resolved at.</param> /// <param name="managedFunction">A function that is resolved from the breakpoint description.</param> /// <param name="ilOffset">An il offset within a function resolved from the breakpoint description.</param> /// <returns>true if breakpoint was successfully resolved</returns> /// <remarks> /// Resolved is usually called for every loaded module. /// </remarks> public bool ResolveLocation(MDbgFunctionBreakpoint functionBreakpoint, MDbgModule managedModule, out MDbgFunction managedFunction, out int ilOffset) { managedFunction = null; ilOffset = -1; // check if the function is from the module we specified. if (m_function.Module != managedModule) return false; managedFunction = m_function; ilOffset = m_ILoffset; return true; }
/// <summary> /// Event handler for a module unload /// </summary> /// <param name="module">Module that is being unloaded</param> public override void OnModuleUnloaded(MDbgModule module) { if (m_breakpoints != null) { m_breakpoints.Remove(module); } }
internal MDbgFunctionMgr(MDbgModule module) { m_module = module; }
private bool SetUserEntryBreakpointInModule(MDbgModule m) { bool ok = true; if (m.SymReader != null) { int st = 0; st = m.SymReader.UserEntryPoint.GetToken(); if (st != 0) { MDbgFunction mfunc = m.GetFunction(st); m_userEntryBreakpoint = new UserEntryBreakpoint(this, mfunc); ok = m_userEntryBreakpoint.BindToModule(m); // Issue a warning if we failed to set the user entry breakpoint. if (!ok) { Trace.WriteLine(string.Format("Failed to set user entry breakpoint at {0}", mfunc.FullName)); } // now we cannot call BindBreakpoints again otherwise userEntrBreakpoint will be bound // twice } // We explicitly don't set JMC. An extension can hook up to this module and set JMC policy if it wants. } return ok; }
/// <summary> /// Resolves a class from a Variable Name. /// </summary> /// <param name="typeName">The name of the type to resolve.</param> /// <param name="appDomain">The AppDomain to resolve the type in or null if any AppDomain can be used</param> /// <param name="mod"> /// Returns the module in which the class was resolved. value is /// null if the resolution fails. /// </param> /// <returns>The CorClass of that Variable.</returns> public CorClass ResolveClass(string typeName, CorAppDomain appDomain, out MDbgModule mod) { mod = null; int classToken = CorMetadataImport.TokenNotFound; Debug.Assert(typeName.Length != 0); // we cannot resolve to global token, since there is a global token for module. foreach (MDbgModule m in Modules) { // debugger modules are scoped by app domain // we need to find a module in the correct domain to resolve the // class in the correct domain if (appDomain != null && m.CorModule.Assembly.AppDomain != appDomain) continue; classToken = m.Importer.GetTypeTokenFromName(typeName); if (classToken != CorMetadataImport.TokenNotFound) { mod = m; return mod.CorModule.GetClassFromToken(classToken); } } return null; }
internal void BindBreakpoints(MDbgModule loadedModule) { foreach (MDbgBreakpoint b in m_items) { b.BindToModule(loadedModule); } }
/// <summary> /// Function tries to bind a breakpoint to the specified module. /// </summary> /// <param name="managedModule">A module the breakpoint should be bound to.</param> /// <returns>true if breakpoint was successfully bound</returns> /// <remarks> /// This function is called by breakpoint manager for every brekapoint whenever a new module /// gets loaded into the debugged process. /// </remarks> public abstract bool BindToModule(MDbgModule managedModule);
/// <summary> /// Called by the breakpoint manager everytime a managed module unloads /// </summary> /// <param name="module">The module which is being unloaded</param> public abstract void OnModuleUnloaded(MDbgModule module);
/// <summary> /// Function tries to bind a breakpoint to the specified module. /// </summary> /// <param name="managedModule">A module the breakpoint should be bound to.</param> /// <returns>true if breakpoint was successfully bound</returns> /// <remarks> /// This function is called by breakpoint manager for every brekapoint whenever a new module /// gets loaded into the debugged process. /// </remarks> public abstract bool BindToModule(MDbgModule managedModule);
/// <summary> /// Create a new instance of the ModuleLoadedStopReason class. /// </summary> /// <param name="managedModule">The module that has been loaded.</param> public ModuleLoadedStopReason(MDbgModule managedModule) { Debug.Assert(managedModule != null); m_module = managedModule; }
internal MDbgFunctionMgr(MDbgModule module) { m_module = module; }
/// <summary> /// Create a new instance of the ModuleLoadedStopReason class. /// </summary> /// <param name="managedModule">The module that has been loaded.</param> public ModuleLoadedStopReason(MDbgModule managedModule) { Debug.Assert(managedModule != null); m_module = managedModule; }
internal MDbgModule Register(CorModule managedModule) { MDbgModule mdbgModule; if (m_items.ContainsKey(managedModule)) { mdbgModule = (MDbgModule)m_items[managedModule]; return mdbgModule; } mdbgModule = new MDbgModule(m_process, managedModule, m_freeModuleNumber++); m_items.Add(managedModule, mdbgModule); return mdbgModule; }
/* * We want to have following commnads: * * symbol path "value" -- sets symbol paths * symbol addpath "value" -- adds symbol path * symbol reload [module] -- reloads symbol for a module * symbol list [module] -- shows currently loaded symbols */ public static void SymbolCmd(string arguments) { ArgParser ap = new ArgParser(arguments); if (!ap.Exists(0)) { ExecuteCommand("help symbol"); return; } switch (ap.AsCommand(0, new CommandArgument("path", "addpath", "reload", "list"))) { case "path": if (!ap.Exists(1)) { // we want to print current path string p = Debugger.Options.SymbolPath; WriteOutput("Current symbol path: " + p); } else { // we are setting path Debugger.Options.SymbolPath = ap.AsString(1); WriteOutput("Current symbol path: " + Debugger.Options.SymbolPath); } break; case "addpath": Debugger.Options.SymbolPath = Debugger.Options.SymbolPath + Path.PathSeparator + ap.AsString(1); WriteOutput("Current symbol path: " + Debugger.Options.SymbolPath); break; case "reload": { IEnumerable modules; if (ap.Exists(1)) { // we want to reload only one module MDbgModule m = Debugger.Processes.Active.Modules.Lookup(ap.AsString(1)); if (m == null) { throw new MDbgShellException("No such module."); } modules = new MDbgModule[] { m }; } else { modules = Debugger.Processes.Active.Modules; } foreach (MDbgModule m in modules) { WriteOutput("Reloading symbols for module " + m.CorModule.Name); m.ReloadSymbols(true); WriteModuleStatus(m, true); } } break; case "list": { IEnumerable modules; if (ap.Exists(1)) { // we want to list only one module MDbgModule m = Debugger.Processes.Active.Modules.Lookup(ap.AsString(1)); if (m == null) { throw new MDbgShellException("No such module."); } modules = new MDbgModule[] { m }; } else { modules = Debugger.Processes.Active.Modules; } foreach (MDbgModule m in modules) { WriteModuleStatus(m, false); } } break; default: Debug.Assert(false); break; } }
/// <summary> /// Resolves a Function from a Module, Class Name, and Function Name. /// </summary> /// <param name="mdbgModule">The Module that has the Function.</param> /// <param name="className">The name of the Class that has the Function.</param> /// <param name="functionName">The name of the Function.</param> /// <returns>The MDbgFunction that matches the given parameters.</returns> public MDbgFunction ResolveFunctionName(MDbgModule mdbgModule, string className, string functionName) { int typeToken = mdbgModule.Importer.GetTypeTokenFromName(className); if (typeToken == CorMetadataImport.TokenNotFound) return null; MDbgFunction func = null; Type t = mdbgModule.Importer.GetType(typeToken); foreach (MethodInfo mi in t.GetMethods()) { if (mi.Name.Equals(functionName)) { func = mdbgModule.GetFunction((mi as MetadataMethodInfo).MetadataToken); break; } } return func; }
private static void WriteModuleStatus(MDbgModule module, bool reloadMode) { string symbolLocation = null; bool bHaveSyms = module.SymReader != null; if (bHaveSyms) { symbolLocation = module.SymbolFilename; if (symbolLocation == null || symbolLocation.Length == 0) symbolLocation = "<loaded from unknown location>"; } string outputString; if (reloadMode) { if (bHaveSyms) outputString = string.Format(CultureInfo.InvariantCulture, "Symbols loaded from: {0}\n", symbolLocation); else outputString = "No symbols could be loaded.\n"; } else { outputString = string.Format(CultureInfo.InvariantCulture, "Module: {0}\nSymbols: {1}\n", module.CorModule.Name, bHaveSyms ? symbolLocation : "<no available>"); } WriteOutput(outputString); }
/// <summary> /// Function tries to bind a breakpoint to the specified module. /// </summary> /// <param name="managedModule">A module the breakpoint should be bound to.</param> /// <returns>true if breakpoint was successfully bound or false if it failed or was already bound.</returns> /// <remarks> /// This function is called by breakpoint manager for every brekapoint whenever a new module /// gets loaded into the debugged process or whenever a dynamic module loads a new class /// or new symbols. This adds any missing bindings, but will not duplicate any that already exist. /// </remarks> public override sealed bool BindToModule(MDbgModule managedModule) { MDbgFunction func; int ILoffset; // If we already bound a breakpoint in this module then nothing to do if (m_breakpoints != null && m_breakpoints.ContainsKey(managedModule)) return false; // If we can't resolve the location in this module then there is nothing to do if (!m_location.ResolveLocation(this, managedModule, out func, out ILoffset)) return false; // Use the resolved information to get a raw CorBreakpoint object. CorFunctionBreakpoint breakpoint = null; try { if (ILoffset == 0) { breakpoint = func.CorFunction.CreateBreakpoint(); } else { // we need to set a breakpoint on code rather than directly on function CorCode code = func.CorFunction.ILCode; if (code == null) { throw new MDbgException(String.Format(CultureInfo.InvariantCulture, "IL Code for function {0} is null", new Object[] { func.FullName })); } breakpoint = code.CreateBreakpoint(ILoffset); } } catch (NotImplementedException) { return false; } catch (COMException) { return false; } // Add the new CorBreakpoint object to our internal list and register a handler for it. Debug.Assert(breakpoint != null); breakpoint.Activate(true); if (m_breakpoints == null) { m_breakpoints = new Dictionary<MDbgModule, CorFunctionBreakpoint>(); } m_breakpoints.Add(managedModule, breakpoint); MDbgProcess p = managedModule.Process; CustomBreakpointEventHandler handler = new CustomBreakpointEventHandler(this.InternalOnHitHandler); p.RegisterCustomBreakpoint(breakpoint, handler); return true; }
/// <summary> /// Function tries to bind a breakpoint to the specified module. /// </summary> /// <param name="managedModule">A module the breakpoint should be bound to.</param> /// <returns>true if breakpoint was successfully bound or false if it failed or was already bound.</returns> /// <remarks> /// This function is called by breakpoint manager for every brekapoint whenever a new module /// gets loaded into the debugged process or whenever a dynamic module loads a new class /// or new symbols. This adds any missing bindings, but will not duplicate any that already exist. /// </remarks> public override sealed bool BindToModule(MDbgModule managedModule) { MDbgFunction func; int ILoffset; // Note that in some cases (eg. source/line breakpoints) we may actually // want to bind to multiple locations in this module instead of just one. if (!m_location.ResolveLocation(this, managedModule, out func, out ILoffset)) return false; if (m_breakpoints != null) { // Assume all breakpoints are CorFunctionBreakpoints. // If this ever becomes invalid, we'll need a new check here to avoid // duplicating that type of breakpoint. foreach (CorFunctionBreakpoint cb in m_breakpoints) { // If we find a CorBreakpoint that already matches this location // don't add a new one, or the debugger will stop twice when it's hit. // Note that CorFunction instances are 1:1 with a specific function in a // specific module and AppDomain (but represents all generic instantiations). if (cb.Function == func.CorFunction && cb.Offset == ILoffset) return false; } } // Use the resolved information to get a raw CorBreakpoint object. CorBreakpoint breakpoint = null; try { if (ILoffset == 0) { breakpoint = func.CorFunction.CreateBreakpoint(); } else { // we need to set a breakpoint on code rather than directly on function CorCode code = func.CorFunction.ILCode; if (code == null) { throw new MDbgException(String.Format(CultureInfo.InvariantCulture, "IL Code for function {0} is null", new Object[] { func.FullName })); } breakpoint = code.CreateBreakpoint(ILoffset); } } catch (COMException) { return false; } // Add the new CorBreakpoint object to our internal list and register a handler for it. Debug.Assert(breakpoint != null); breakpoint.Activate(true); if (m_breakpoints == null) { m_breakpoints = new ArrayList(); } m_breakpoints.Add(breakpoint); MDbgProcess p = managedModule.Process; CustomBreakpointEventHandler handler = new CustomBreakpointEventHandler(this.InternalOnHitHandler); p.RegisterCustomBreakpoint(breakpoint, handler); return true; }
/// <summary> /// Function tries to resolve the breakpoint from breakpoint description. /// </summary> /// <param name="functionBreakpoint">A breakpoint object.</param> /// <param name="managedModule">A module that the breakpoint should be resolved at.</param> /// <param name="managedFunction">A function that is resolved from the breakpoint description.</param> /// <param name="ilOffset">An il offset within a function resolved from the breakpoint description.</param> /// <returns>true if breakpoint was successfully resolved</returns> /// <remarks> /// Resolved is usually called for every loaded module. /// </remarks> public bool ResolveLocation(MDbgFunctionBreakpoint functionBreakpoint, MDbgModule managedModule, out MDbgFunction managedFunction, out int ilOffset) { managedFunction = null; ilOffset = m_ILoffset; if (m_moduleName != null && m_moduleName.Length > 0) { if (!managedModule.MatchesModuleName(m_moduleName)) return false; } managedFunction = functionBreakpoint.m_breakpointCollection.m_process.ResolveFunctionName(managedModule, m_className, m_methodName); return managedFunction != null; }
/// <summary> /// Returns a string that represents current frame /// Currently supported formats: /// null or empty string: returns short frame format (just frame name) /// "v" : returns long frame format (including module & arguments) /// </summary> /// <param name="format">Which format to use.</param> /// <returns>The formatted string that represtents the current frame.</returns> public override string ToString(string format) { string fn; switch (m_frame.FrameType) { case CorFrameType.ILFrame: MDbgSourcePosition sl = SourcePosition; string sp; if (sl != null) { string filePath = sl.Path; if (!Thread.m_threadMgr.m_process.m_engine.Options.ShowFullPaths) { filePath = Path.GetFileName(sl.Path); } sp = " (" + filePath + ":" + sl.Line.ToString(System.Globalization.CultureInfo.CurrentUICulture) + ")"; } else { sp = " (source line information unavailable)"; } StringBuilder sbFuncName = new StringBuilder(); MDbgModule module = this.Function.Module; MDbgProcess proc = Thread.m_threadMgr.m_process; // Get class name w/ generic args. CorType tClass = this.FunctionType; if (tClass != null) { InternalUtil.PrintCorType(sbFuncName, proc, tClass); } sbFuncName.Append('.'); // Get method name w/ generic args. MethodInfo mi = this.Function.MethodInfo; sbFuncName.Append(mi.Name); InternalUtil.AddGenericArgs(sbFuncName, proc, this.FunctionTypeParameters); string stFuncName = sbFuncName.ToString(); if (format == "v") { CorModule m = module.CorModule; // verbose frame output // in verbose output we'll print module name + arguments to the functions StringBuilder sb = new StringBuilder(); bool bFirst = true; foreach (MDbgValue v in this.Function.GetArguments(this)) { if (sb.Length != 0) { sb.Append(", "); } // skip this references if (!(bFirst && v.Name == "this")) { sb.Append(v.Name).Append("=").Append(v.GetStringValue(0)); } bFirst = false; } if (m.IsDynamic || m.IsInMemory) { fn = m.Name; } else { fn = System.IO.Path.GetFileName(m.Name); } MDbgAppDomain ad = this.Thread.m_threadMgr.m_process.AppDomains.Lookup(m.Assembly.AppDomain); fn += "#" + ad.Number + "!" + stFuncName + "(" + sb.ToString() + ") " + sp; } else { fn = stFuncName + sp; } break; case CorFrameType.NativeFrame: fn = "[IL Method without Metadata]"; break; case CorFrameType.InternalFrame: switch (m_frame.InternalFrameType) { case CorDebugInternalFrameType.STUBFRAME_NONE: fn = "None"; break; case CorDebugInternalFrameType.STUBFRAME_M2U: fn = "M-->U"; break; case CorDebugInternalFrameType.STUBFRAME_U2M: fn = "U-->M"; break; case CorDebugInternalFrameType.STUBFRAME_APPDOMAIN_TRANSITION: fn = "AD Switch"; break; case CorDebugInternalFrameType.STUBFRAME_LIGHTWEIGHT_FUNCTION: fn = "LightWeight"; break; case CorDebugInternalFrameType.STUBFRAME_FUNC_EVAL: fn = "FuncEval"; break; case CorDebugInternalFrameType.STUBFRAME_INTERNALCALL: fn = "InternalCall"; break; case CorDebugInternalFrameType.STUBFRAME_CLASS_INIT: fn = "ClassInit"; break; case CorDebugInternalFrameType.STUBFRAME_EXCEPTION: fn = "Exception"; break; case CorDebugInternalFrameType.STUBFRAME_SECURITY: fn = "Security"; break; case CorDebugInternalFrameType.STUBFRAME_JIT_COMPILATION: fn = "JitCompilation"; break; default: fn = "UNKNOWN"; break; } fn = "[Internal Frame, '" + fn + "']"; break; default: fn = "UNKNOWN Frame Type"; break; } return(fn); }
/// <summary> /// Function tries to resolve the breakpoint from breakpoint description. /// </summary> /// <param name="functionBreakpoint">A breakpoint object.</param> /// <param name="managedModule">A module that the breakpoint should be resolved at.</param> /// <param name="managedFunction">A function that is resolved from the breakpoint description.</param> /// <param name="ILoffset">An il offset within a function resolved from the breakpoint description.</param> /// <returns>true if breakpoint was successfully resolved</returns> /// <remarks> /// Resolved is usually called for every loaded module. /// </remarks> public bool ResolveLocation(MDbgFunctionBreakpoint functionBreakpoint, MDbgModule managedModule, out MDbgFunction managedFunction, out int ILoffset) { Debug.Assert(m_lineNo > 0 && m_file.Length > 0); managedFunction = null; ILoffset = 0; if (managedModule.SymReader == null) // no symbols for current module, skip it. return false; foreach (ISymbolDocument doc in managedModule.SymReader.GetDocuments()) { if (String.Compare(doc.URL, m_file, true, CultureInfo.InvariantCulture) == 0 || String.Compare(System.IO.Path.GetFileName(doc.URL), m_file, true, CultureInfo.InvariantCulture) == 0) { int lineNo = 0; try { lineNo = doc.FindClosestLine(m_lineNo); } catch (System.Runtime.InteropServices.COMException e) { if (e.ErrorCode == (int)HResult.E_FAIL) // we continue, because this location is not in this file, let's // keep trying to search for next file. continue; } ISymbolMethod symMethod = managedModule.SymReader.GetMethodFromDocumentPosition(doc, lineNo, 0); managedFunction = managedModule.GetFunction(symMethod.Token.GetToken()); ILoffset = managedFunction.GetIPFromPosition(doc, lineNo); // If this IL if (ILoffset == -1) { return false; } Debug.Assert(ILoffset != -1); return true; } } managedFunction = null; ILoffset = -1; return false; }
/// <summary> /// Function tries to bind a breakpoint to the specified module. /// </summary> /// <param name="managedModule">A module the breakpoint should be bound to.</param> /// <returns>true if breakpoint was successfully bound or false if it failed or was already bound.</returns> /// <remarks> /// This function is called by breakpoint manager for every brekapoint whenever a new module /// gets loaded into the debugged process or whenever a dynamic module loads a new class /// or new symbols. This adds any missing bindings, but will not duplicate any that already exist. /// </remarks> public sealed override bool BindToModule(MDbgModule managedModule) { MDbgFunction func; int ILoffset; // If we already bound a breakpoint in this module then nothing to do if (m_breakpoints != null && m_breakpoints.ContainsKey(managedModule)) { return(false); } // If we can't resolve the location in this module then there is nothing to do if (!m_location.ResolveLocation(this, managedModule, out func, out ILoffset)) { return(false); } // Use the resolved information to get a raw CorBreakpoint object. CorFunctionBreakpoint breakpoint = null; try { if (ILoffset == 0) { breakpoint = func.CorFunction.CreateBreakpoint(); } else { // we need to set a breakpoint on code rather than directly on function CorCode code = func.CorFunction.ILCode; if (code == null) { throw new MDbgException(String.Format(CultureInfo.InvariantCulture, "IL Code for function {0} is null", new Object[] { func.FullName })); } breakpoint = code.CreateBreakpoint(ILoffset); } } catch (NotImplementedException) { return(false); } catch (COMException) { return(false); } // Add the new CorBreakpoint object to our internal list and register a handler for it. Debug.Assert(breakpoint != null); breakpoint.Activate(true); if (m_breakpoints == null) { m_breakpoints = new Dictionary <MDbgModule, CorFunctionBreakpoint>(); } m_breakpoints.Add(managedModule, breakpoint); MDbgProcess p = managedModule.Process; CustomBreakpointEventHandler handler = new CustomBreakpointEventHandler(this.InternalOnHitHandler); p.RegisterCustomBreakpoint(breakpoint, handler); return(true); }
/// <summary> /// Called by the breakpoint manager everytime a managed module unloads /// </summary> /// <param name="module">The module which is being unloaded</param> public abstract void OnModuleUnloaded(MDbgModule module);
private static void ListModuleInternal(MDbgModule module, bool verbose) { string symbolsStatus = " (no symbols loaded)"; // There's no guarantee that we can read syms on a dump. try { if (module.SymReader != null) { symbolsStatus = String.Empty; } } catch (System.Runtime.InteropServices.COMException e) { // Nothing to be done for it when the target can't find memory; just swallow the exception. if (e.ErrorCode != (int)HResult.E_PARTIAL_COPY) { throw; } } CorAppDomain ad = module.CorModule.Assembly.AppDomain; int adNumber = Debugger.Processes.Active.AppDomains.Lookup(ad).Number; if (verbose) { WriteOutput(string.Format(CultureInfo.InvariantCulture, ":{0}\t{1}#{2} {3}", module.Number, module.CorModule.Name, adNumber, symbolsStatus)); } else { string moduleBaseName; try { moduleBaseName = System.IO.Path.GetFileName(module.CorModule.Name); } catch { moduleBaseName = module.CorModule.Name; } WriteOutput(string.Format(CultureInfo.InvariantCulture, ":{0}\t{1}#{2} {3}", module.Number, moduleBaseName, adNumber, symbolsStatus)); } }
internal void OnModuleUnloaded(MDbgModule unloadedModule) { foreach (MDbgBreakpoint b in m_items) { b.OnModuleUnloaded(unloadedModule); } }
/// <summary> /// Resolves a class from a Variable Name. /// </summary> /// <param name="typeName">The name of the type to resolve.</param> /// <param name="mod"> /// Returns the module in which the class was resolved. value is /// null if the resolution fails. /// </param> /// <returns>The CorClass of that Variable.</returns> public CorClass ResolveClass(string typeName, out MDbgModule mod) { return ResolveClass(typeName, null, out mod); }