/// <summary> /// Creates a new instance of the MDbgValue Object. /// This constructor is public so that applications can use this class to print values (CorValue). /// CorValue's can be returned for example by funceval(CorEval.Result). /// </summary> /// <param name="process">The Process that will own the Value.</param> /// <param name="value">The CorValue that this MDbgValue will start with.</param> public MDbgValue(MDbgProcess process, CorDebug.CorValue value) { // value can be null, but we should always know what process we are // looking at. Debug.Assert(process != null); Initialize(process, null, value); }
// Helper to append generic args from tyenum in pretty format. // This will add a string like '<int, Foo<string>>' internal static void AddGenericArgs(StringBuilder sb, MDbgProcess proc, IEnumerable tyenum) { int i = 0; foreach (CorType t1 in tyenum) { sb.Append((i == 0) ? '<' : ','); PrintCorType(sb, proc, t1); i++; } if (i > 0) { sb.Append('>'); } }
public CorValue ParseExpression2(string value, MDbgProcess process, MDbgFrame scope) { if (value.Length == 0) { return null; } if (RepresentsPrimitiveValue(value)) { //value is a primitive type return CreatePrimitiveValue(value); } if (value[0] == '"' && value[value.Length - 1] == '"') { //value is a string return CreateString(value); } //value is some variable Debug.Assert(process != null); MDbgValue var = process.ResolveVariable(value, scope); return (var == null ? null : var.CorValue); }
internal MDbgModule(MDbgProcess process, CorDebug.CorModule managedModule, int number) { Debug.Assert(process != null && managedModule != null); m_process = process; m_module = managedModule; m_functions = new MDbgFunctionMgr(this); m_number = number; }
internal MDbgAppDomain(MDbgProcess process, CorDebug.CorAppDomain appDomain, int number) { Debug.Assert(process != null); Debug.Assert(appDomain != null); m_process = process; m_appDomain = appDomain; m_number = number; }
internal MDbgBreakpointCollection(MDbgProcess process) { Debug.Assert(process != null); m_process = process; }
/// <summary> /// Does nothing - an ExceptionEnhancedStopOptionPolicy object is only meant to control the /// ExceptionEnhanced switch in an ExceptionStopOptionPolicy object, not to directly stop the /// debugger or to log a callback. /// </summary> /// <param name="currentProcess">Current MDbgProcess.</param> /// <param name="args">Callback arguments.</param> public override void ActOnCallback(MDbgProcess currentProcess, CustomPostCallbackEventArgs args) { }
/// <summary> /// Acts on the current callback, based on the current debugger behavior for this stop /// option policy. /// </summary> /// <param name="currentProcess">Current MDbgProcess.</param> /// <param name="args">Callback arguments.</param> public override void ActOnCallback(MDbgProcess currentProcess, CustomPostCallbackEventArgs args) { var eventArgs = args.CallbackArgs as CorEventArgs; switch (m_behavior) { case DebuggerBehavior.Stop: args.Controller.Stop(eventArgs.Thread, MDbgUtil.CreateStopReasonFromEventArgs(eventArgs, currentProcess)); break; case DebuggerBehavior.Log: CommandBase.WriteOutput(eventArgs + "\n"); break; } }
public MDbgProcessStopController(MDbgProcess process, CorEventArgs eventArgs, bool needAsyncStopCall) { Debug.Assert(process != null); Debug.Assert(eventArgs != null); this.process = process; this.eventArgs = eventArgs; this.needAsyncStopCall = needAsyncStopCall; }
/// <summary> /// Creates a local process object that will be able to debug specified program. /// </summary> /// <remarks>The created process object will be empty -- you still have to call /// CreateProcess method on it to start debugging /// </remarks> /// <param name="version">versin of CLR to use for the process</param> /// <returns>The Process that got created.</returns> public MDbgProcess CreateLocalProcess(string version) { // This is called on the Main thread so it's safe to flush FreeStaleUnmanagedResources(); CorDebug.CorDebugger debugger; if (version == null) debugger = DefaultLocalDebugger; else { debugger = new CorDebugger(version); lock (m_CleanupList) { m_CleanupList.Add(debugger, false); } } var p = new MDbgProcess(m_engine, debugger); return p; }
internal MDbgDebuggerVarCollection(MDbgProcess process) { m_process = process; }
internal MDbgThreadCollection(MDbgProcess process) { m_process = process; m_freeThreadNumber = 0; }
/// <summary> /// Acts on debugger callback based on the contained stop option policies matching /// the callback type. /// </summary> /// <param name="currentProcess">Current MDbgProcess.</param> /// <param name="args">Debugger callback arguments.</param> public void ActOnCallback(MDbgProcess currentProcess, CustomPostCallbackEventArgs args) { if (m_stopOptions[(int) args.CallbackType] != null) { foreach (MDbgStopOptionPolicy sop in m_stopOptions[(int) args.CallbackType]) { sop.ActOnCallback(currentProcess, args); } } }
/// <summary> /// Given a CorEventArgs object, returns a corresponding StopReason. /// </summary> /// <param name="args">Callback Arguments.</param> /// <param name="currentProcess">Current MDbgProcess.</param> /// <returns>A stop reason corresponsing to the given callback arguments. This /// function currently creates StopReason objects for CorEventArgs with the following /// callback types: OnCreateThread, OnExceptionUnwind2, OnModuleLoad, OnMDANotification. /// For all other callback types, this function returns args.ToString().</returns> public static Object CreateStopReasonFromEventArgs(CorEventArgs args, MDbgProcess currentProcess) { if (args.CallbackType == ManagedCallbackType.OnCreateThread) { return new ThreadCreatedStopReason(currentProcess.Threads.GetThreadFromThreadId(args.Thread.Id)); } if (args.CallbackType == ManagedCallbackType.OnExceptionUnwind2) { var ea = args as CorExceptionUnwind2EventArgs; return new ExceptionUnwindStopReason(ea.AppDomain, ea.Thread, ea.EventType, ea.Flags); } if (args.CallbackType == ManagedCallbackType.OnModuleLoad) { var ea = args as CorModuleEventArgs; return new ModuleLoadedStopReason(currentProcess.Modules.Lookup(ea.Module)); } if (args.CallbackType == ManagedCallbackType.OnMDANotification) { var ea = args as CorMDAEventArgs; return new MDANotificationStopReason(ea.MDA); } return args.ToString(); }
// Return class as a string. /// <summary> /// Creates a string representation of CorType. /// </summary> /// <param name="proc">A debugged process.</param> /// <param name="ct">A CorType object representing a type in the debugged process.</param> /// <returns>String representaion of the passed in type.</returns> public static string PrintCorType(MDbgProcess proc, CorType ct) { var sb = new StringBuilder(); PrintCorType(sb, proc, ct); return sb.ToString(); }
// 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
public void Dispose() { process = null; }
/// <summary> /// Acts on the debugger callback, based on the stop option policy settings and the /// type of exception thrown. /// </summary> /// <param name="currentProcess">Current MDbgProcess.</param> /// <param name="args">Callback arguments.</param> public override void ActOnCallback(MDbgProcess currentProcess, CustomPostCallbackEventArgs args) { var ea = args.CallbackArgs as CorException2EventArgs; var ua = args.CallbackArgs as CorExceptionUnwind2EventArgs; bool bException2 = (ea != null); if (m_exceptionEnhancedOn || (bException2 && (ea.EventType == CorDebugExceptionCallbackType.DEBUG_EXCEPTION_FIRST_CHANCE))) { MDbgThread currentThread = null; currentThread = currentProcess.Threads.GetThreadFromThreadId((args.CallbackArgs as CorThreadEventArgs).Thread.Id); string exceptionType = currentThread.CurrentException.TypeName; switch (DetermineBehavior(exceptionType)) { case DebuggerBehavior.Stop: if (bException2) { args.Controller.Stop(ea.Thread, new ExceptionThrownStopReason(ea.AppDomain, ea.Thread, ea.Frame, ea.Offset, ea.EventType, ea.Flags, m_exceptionEnhancedOn)); } else { args.Controller.Stop(ua.Thread, new ExceptionUnwindStopReason(ua.AppDomain, ua.Thread, ua.EventType, ua.Flags)); } break; case DebuggerBehavior.Log: CommandBase.WriteOutput("Exception thrown: " + currentThread.CurrentException.TypeName + " at function " + currentThread.CurrentFrame.Function.FullName + " in source file " + currentThread.CurrentSourcePosition.Path + ":" + currentThread.CurrentSourcePosition.Line); if (m_exceptionEnhancedOn) { if (bException2) { CommandBase.WriteOutput("Event type: " + ea.EventType); } else { CommandBase.WriteOutput("Event type: " + ua.EventType); } } CommandBase.WriteOutput(""); break; } } }
internal UserEntryBreakpoint(MDbgProcess p, MDbgFunction mfunc) : base(null, new BreakpointFunctionToken(mfunc, 0)) { m_process = p; }
/// <summary> /// Acts on debugger callback. /// </summary> /// <param name="currentProcess">The current MDbgProcess. </param> /// <param name="args">The callback arguments.</param> public abstract void ActOnCallback(MDbgProcess currentProcess, CustomPostCallbackEventArgs args);
// (key, value) // Key is the CorDebugger object that we'll eventually call ICorDebug::Terminate on. // value is the state of the CorDebugger object: // false - that means object is live // true - means that object is now dead and can be cleaned up. /// <summary> /// Called by MDbgProcess constructor to register a process into process collection /// </summary> /// <param name="process">process to register</param> /// <returns>Logical process number that should be assigned to the registered process.</returns> internal int RegisterProcess(MDbgProcess process) { m_items.Add(process); m_active = process; // We don't fire the ProcessAdded event yet because we don't yet have a valid CorProcess object. // We'll fire the event when we initialize the callbacks. return m_freeProcessNumber++; }
private void Initialize(MDbgProcess process, string name, CorDebug.CorValue value) { m_process = process; m_name = name; m_corValue = value; }
// Fired once process has an underlying CorProcess object. internal void OnProcessResolved(MDbgProcess p) { if (ProcessAdded != null) { Debug.Assert(p != null); Debug.Assert(p.CorProcess != null); ProcessAdded(this, new ProcessCollectionChangedEventArgs(p)); } }
/// <summary> /// Creates a new instance of the MDbgValue Object. /// This constructor is public so that applications can use this class to print values (CorValue). /// CorValue's can be returned for example by funceval(CorEval.Result). /// </summary> /// <param name="process">The Process that will own the Value.</param> /// <param name="name">The name of the variable.</param> /// <param name="value">The CorValue that this MDbgValue will start with.</param> public MDbgValue(MDbgProcess process, string name, CorDebug.CorValue value) { Debug.Assert(process != null && name != null); // corValue can be null for native variables in MC++ Initialize(process, name, value); }
/// <summary> /// Removes process from the process collection. /// </summary> /// <param name="process">process to unregister from collection</param> /// <remarks> /// If the process was active, the active process is set to none /// </remarks> internal void DeleteProcess(MDbgProcess process) { Debug.Assert(m_items.Contains(process)); if (m_active == process) { m_active = null; } m_items.Remove(process); lock (m_CleanupList) { // We may need to call IcorDebug::Terminate. However, we can't call that on a callback thread, // but this function may be on a callback thread. So queue the call and we can call it later. CorDebug.CorDebugger d = process.CorDebugger; if (m_CleanupList.Contains(d)) { m_CleanupList[d] = true; } } }
internal MDbgAppDomainCollection(MDbgProcess process) { Debug.Assert(process != null); m_process = process; }
internal ProcessCollectionChangedEventArgs(MDbgProcess p) { m_process = p; }
internal MDbgModuleCollection(MDbgProcess process) { Debug.Assert(process != null); m_process = process; }
public MDbgValue ParseExpression(string variableName, MDbgProcess process, MDbgFrame scope) { Debug.Assert(process != null); return process.ResolveVariable(variableName, scope); }