Example #1
0
 /// <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);
 }
Example #2
0
        public MDbgFunction Get(CorDebug.CorFunction managedFunction)
        {
            int funcVersion;
            funcVersion = managedFunction.Version;

            // now get version from our cache.
            MDbgFunction mdbgFunction = RetrieveFromCache(managedFunction.Token, funcVersion);
            if (mdbgFunction == null)
            {
                mdbgFunction = new MDbgFunction(m_module, managedFunction);
                AddToCache(managedFunction.Token, funcVersion, mdbgFunction);
            }
            return mdbgFunction;
        }
Example #3
0
        // http://stackoverflow.com/questions/8094441/is-it-ok-to-abuse-coclassattribute-to-provide-a-default-implementation-for-an

        static void Main(string[] args)
        {
            // Error	2	Cannot create an instance of the abstract class or interface 'TestCoClass.IApp'	X:\jsc.svn\examples\rewrite\TestCoClass\TestCoClass\Program.cs	37	21	TestCoClass
            var x = new IApp { foo = "foo" };
            var doc = new Document();

            // Error	1	Cannot implicitly convert type 'TestCoClass.Document' to 'TestCoClass.IApp'. An explicit conversion exists (are you missing a cast?)	X:\jsc.svn\examples\rewrite\TestCoClass\TestCoClass\Program.cs	41	23	TestCoClass
            //IApp xx = doc;

            var xx = doc.ToApp();


            // Constructs a FooImpl
            ICorDebug foo = new CorDebug { MyProperty = 5 };

            foo.Bar();
        }
Example #4
0
        protected virtual void Dispose(bool disposing)
        {
            if (_isDisposed)
            {
                return;
            }

            if (disposing)
            {
            }

            CorDebug?.Dispose();
            CorProcess?.Dispose();
            _callbacks?.Dispose();
            CorDebug   = null;
            _process   = null;
            _callbacks = null;

            _isDisposed = true;
        }
Example #5
0
        private string PrintObject(int indentLevel, CorDebug.CorObjectValue ov, int expandDepth, bool canDoFunceval)
        {
            Debug.Assert(expandDepth >= 0);

            // Print generics-aware type.
            string name = InternalUtil.PrintCorType(m_process, ov.ExactType);

            var txt = new StringBuilder();
            txt.Append(name);

            if (expandDepth > 0)
            {
                // we gather the field info of the class before we do
                // funceval since funceval requires running the debugger process
                // and this in turn can cause GC and invalidate our references.
                var expandedDescription = new StringBuilder();
                if (IsComplexType)
                {
                    foreach (MDbgValue v in GetFields())
                    {
                        expandedDescription.Append("\n").Append(IndentedString(indentLevel + 1, v.Name)).
                            Append("=").Append(IndentedBlock(indentLevel + 2,
                                                             v.GetStringValue(expandDepth - 1, false)));
                    }
                }

                if (ov.IsValueClass && canDoFunceval)
                    // we could display even values for real Objects, but we will just show 
                    // "description" for valueclasses.
                {
                    CorDebug.CorClass cls = ov.ExactType.Class;
                    CorMetadataImport importer = m_process.Modules.Lookup(cls.Module).Importer;
                    var mdType = importer.GetType(cls.Token) as MetadataType;

                    if (mdType.ReallyIsEnum)
                    {
                        txt.AppendFormat(" <{0}>", InternalGetEnumString(ov, mdType));
                    }
                    else if (m_process.IsRunning)
                        txt.Append(" <N/A during run>");
                    else
                    {
                        MDbgThread activeThread = m_process.Threads.Active;

                        CorDebug.CorValue thisValue;
                        CorDebug.CorHeapValue hv = ov.CastToHeapValue();
                        if (hv != null)
                        {
                            // we need to pass reference value.
                            CorDebug.CorHandleValue handle = hv.CreateHandle(CorDebugHandleType.HANDLE_WEAK_TRACK_RESURRECTION);
                            thisValue = handle;
                        }
                        else
                            thisValue = ov;

                        try
                        {
                            CorDebug.CorEval eval = m_process.Threads.Active.CorThread.CreateEval();
                            m_process.CorProcess.SetAllThreadsDebugState(CorDebugThreadState.THREAD_SUSPEND,
                                                                         activeThread.CorThread);

                            MDbgFunction toStringFunc =
                                m_process.ResolveFunctionName(null, "System.Object", "ToString"
                                                              , thisValue.ExactType.Class.Module.Assembly.AppDomain);
                            Debug.Assert(toStringFunc != null);
                            // we should be always able to resolve ToString function.

                            eval.CallFunction(toStringFunc.CorFunction, new[] {thisValue});
                            m_process.Go();
                            do
                            {
                                m_process.StopEvent.WaitOne();
                                if (m_process.StopReason is EvalCompleteStopReason)
                                {
                                    CorDebug.CorValue cv = eval.Result;
                                    Debug.Assert(cv != null);
                                    var mv = new MDbgValue(m_process, cv);
                                    string valName = mv.GetStringValue(0);

                                    // just purely for esthetical reasons we 'discard' "
                                    if (valName.StartsWith("\"") && valName.EndsWith("\""))
                                        valName = valName.Substring(1, valName.Length - 2);

                                    txt.Append(" <").Append(valName).Append(">");
                                    break;
                                }
                                if ((m_process.StopReason is ProcessExitedStopReason) ||
                                    (m_process.StopReason is EvalExceptionStopReason))
                                {
                                    txt.Append(" <N/A cannot evaluate>");
                                    break;
                                }
                                // hitting bp or whatever should not matter -- we need to ignore it
                                m_process.Go();
                            } while (true);
                        }
                        catch (COMException e)
                        {
                            // Ignore canot copy a VC class error - Can't copy a VC with object refs in it.
                            if (e.ErrorCode != (int) CorDebug.HResult.CORDBG_E_OBJECT_IS_NOT_COPYABLE_VALUE_CLASS)
                                throw;
                        }
                        finally
                        {
                            // we need to resume all the threads that we have suspended no matter what.
                            m_process.CorProcess.SetAllThreadsDebugState(CorDebugThreadState.THREAD_RUN,
                                                                         activeThread.CorThread);
                        }
                    }
                }
                txt.Append(expandedDescription.ToString());
            }
            return txt.ToString();
        }
Example #6
0
 public StepCompleteStopReason(CorDebug.CorStepper stepper, CorDebugStepReason stepReason)
 {
     Debug.Assert(stepper != null);
     m_stepReason = stepReason;
     m_stepper = stepper;
 }
Example #7
0
        // Builds the friendly string for an enum value
        private string InternalGetEnumString(CorDebug.CorObjectValue ov, MetadataType type)
        {
            Debug.Assert(type != null); // Enums should always have a type

            IList<KeyValuePair<string, ulong>> values = type.EnumValues;

            // Get the underlying value
            ulong value = Convert.ToUInt64(ov.CastToGenericValue().UnsafeGetValueAsType(type.EnumUnderlyingType),
                                           CultureInfo.InvariantCulture);

            // Find a reasonable value to display
            var result = new StringBuilder();
            ulong remainingValue = value;
            bool firstTime = true;
            for (int i = values.Count - 1; i >= 0; i--)
            {
                if ((values[i].Value == value) ||
                    (type.ReallyIsFlagsEnum && (values[i].Value != 0) && ((values[i].Value & value) == values[i].Value)))
                {
                    remainingValue &= ~(values[i].Value); // Remove the flags from the total needed for flags enums

                    if (!firstTime)
                    {
                        if (type.ReallyIsFlagsEnum)
                        {
                            result.Insert(0, ", ");
                        }
                        else
                        {
                            result.Insert(0, " / ");
                        }
                    }
                    result.Insert(0, values[i].Key);
                    firstTime = false;
                }
            }
            if (remainingValue != 0)
            {
                if (firstTime)
                {
                    // No matches whatsoever
                    result.Insert(0, remainingValue);
                }
                else
                {
                    // Flags enum with leftover bits
                    result.AppendFormat(" (Unnamed bits: {0})", remainingValue);
                }
            }

            return result.ToString();
        }
Example #8
0
 /// <summary>
 /// Create a new instance of the FunctionRemapCompleteStopReason class.
 /// </summary>
 /// <param name="appDomain">The appDomain where remapping is occuring.</param>
 /// <param name="thread">The thread on which the remapping is occuring.</param>
 /// <param name="managedFunction">The version of function the debugger remapped to.</param>
 public FunctionRemapCompleteStopReason(CorDebug.CorAppDomain appDomain,
                                        CorDebug.CorThread thread,
                                        CorDebug.CorFunction managedFunction)
 {
     Debug.Assert(appDomain != null);
     Debug.Assert(thread != null);
     Debug.Assert(managedFunction != null);
     m_appDomain = appDomain;
     m_thread = thread;
     m_function = managedFunction;
 }
Example #9
0
 /// <summary>
 /// Looks up a CorFunction.
 /// </summary>
 /// <param name="managedFunction">Which CorFunction to lookup.</param>
 /// <returns>The coresponding MDbgFunction.</returns>
 public MDbgFunction LookupFunction(CorDebug.CorFunction managedFunction)
 {
     return Lookup(managedFunction.Module).GetFunction(managedFunction);
 }
Example #10
0
 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;
 }
Example #11
0
 /// <summary>
 /// Lookup an MDbgProcss from a CorProcess.
 /// </summary>
 /// <param name="process">The CorProcess.</param>
 /// <returns>The MDbgProcess.</returns>
 public MDbgProcess Lookup(CorDebug.CorProcess process)
 {
     foreach (MDbgProcess p in m_items)
     {
         if (p.CorProcess == process)
         {
             return p;
         }
     }
     return null;
 }
 internal void Unregister(CorDebug.CorAppDomain appDomain)
 {
     Debug.Assert(m_items.ContainsKey(appDomain));
     m_items.Remove(appDomain);
 }
 /// <summary>
 /// Locates MDbgAppDomain object from CorAppDomain object.
 /// </summary>
 /// <param name="appDomain">appDomain object from CorXXX layer.</param>
 /// <returns>MdbgAppDomain object</returns>
 public MDbgAppDomain Lookup(CorDebug.CorAppDomain appDomain)
 {
     return (MDbgAppDomain) m_items[appDomain];
 }
Example #14
0
        internal MDbgFunction(MDbgModule managedModule, CorDebug.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();
        }
Example #15
0
 /// <summary>
 /// Registers a Custom Stepper
 /// Registrations are valid only for one callback, i.e. the object is
 /// automatically deregistered after the callback is fired. If the user wishes to
 /// receive additional callback, the registration has to be done again in the
 /// callback.
 /// </summary>
 /// <param name="stepper">The CorStepper to run.</param>
 /// <param name="handler">The CustomStepperEventHandler to use.</param>
 public void RegisterCustomStepper(CorDebug.CorStepper stepper, CustomStepperEventHandler handler)
 {
     Debug.Assert(stepper != null);
     if (stepper == null)
         throw new ArgumentException("cannot be null", "stepper");
     if (handler == null)
     {
         // explicit deregistration
         if (customSteppers != null)
             customSteppers.Remove(stepper);
     }
     else
     {
         // adding registration
         if (customSteppers == null)
             customSteppers = new ListDictionary();
         else if (customSteppers.Contains(stepper))
             throw new InvalidOperationException("Handler alrady registered for the custom stepper");
         customSteppers.Add(stepper, handler);
     }
 }
Example #16
0
        /// <summary>
        /// Sets a stepper for the process. Process will stop with step complete,
        /// once this stepper completes the step.
        /// This function just sets the active stepper, but it doesn't continue the process.
        /// Once the stepper is set, a Go() command needs to be called.
        /// </summary>
        /// <returns>A WaitHandle for the Stop event.</returns>
        public void SetActiveStepper(CorDebug.CorStepper activeStepper)
        {
            // we are not interested in finishing old step.
            if (m_activeStepper != null)
                m_activeStepper.Deactivate();

            m_activeStepper = activeStepper;
        }
Example #17
0
        /// <summary>Creates an empty process object.
        /// This object can be used to start a debugging session by calling
        /// CreateProcess or Attach method on it.
        /// </summary>
        /// <param name="engine">Root engine object that manages this process.</param>
        /// <param name="debugger">CorDebugger object that will be used to do an actual
        /// debugging</param>
        public MDbgProcess(MDbgEngine engine, CorDebug.CorDebugger debugger)
        {
            Debug.Assert(engine != null && debugger != null);
            if (engine == null)
                throw new ArgumentException("Value cannot be null.", "engine");
            if (debugger == null)
                throw new ArgumentException("Value cannot be null.", "debugger");

            m_engine = engine;

            m_threadMgr = new MDbgThreadCollection(this);
            m_appDomainMgr = new MDbgAppDomainCollection(this);
            m_moduleMgr = new MDbgModuleCollection(this);
            m_breakpointMgr = new MDbgBreakpointCollection(this);
            m_debuggerVarMgr = new MDbgDebuggerVarCollection(this);
            m_corDebugger = debugger;
            // we'll register as last code, so that other fields are already registered.
            m_number = engine.Processes.RegisterProcess(this);
        }
Example #18
0
        private string PrintArray(int indentLevel, CorDebug.CorArrayValue av, int expandDepth, bool canDoFunceval)
        {
            Debug.Assert(expandDepth >= 0);

            var txt = new StringBuilder();
            txt.Append("array [");
            int[] dims = av.GetDimensions();
            Debug.Assert(dims != null);

            for (int i = 0; i < dims.Length; ++i)
            {
                if (i != 0)
                    txt.Append(",");
                txt.Append(dims[i]);
            }
            txt.Append("]");

            if (expandDepth > 0 && av.Rank == 1 && av.ElementType != CorElementType.ELEMENT_TYPE_VOID)
            {
                for (int i = 0; i < dims[0]; i++)
                {
                    // Arrays not starting with 0 are not implemented
                    var v = new MDbgValue(Process, av.GetElementAtPosition(i));
                    txt.Append("\n").Append(IndentedString(indentLevel + 1, "[" + i + "] = ")).
                        Append(IndentedBlock(indentLevel + 2,
                                             v.GetStringValue(expandDepth - 1, canDoFunceval)));
                }
            }
            return txt.ToString();
        }
Example #19
0
        internal MDbgModule Register(CorDebug.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;
        }
Example #20
0
 /// <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);
 }
Example #21
0
 /// <summary>
 /// Create a new instance of the MDANotificationStopReason class.
 /// </summary>
 /// <param name="mda">Generated MDA notification.</param>
 public MDANotificationStopReason(CorDebug.CorMDA mda)
 {
     Debug.Assert(mda != null);
     m_mda = mda;
 }
        internal MDbgAppDomain Register(CorDebug.CorAppDomain appDomain)
        {
            MDbgAppDomain mdbgAppDomain;

            // appdomains may get registered mutliple times if we get a fake-attach event right before a real event.
            if (!m_items.Contains(appDomain))
            {
                mdbgAppDomain = new MDbgAppDomain(m_process, appDomain, m_freeAppDomainNumber++);
                m_items.Add(appDomain, mdbgAppDomain);
                return mdbgAppDomain;
            }
            return (MDbgAppDomain) m_items[appDomain];
        }
 /// <summary>
 /// Locates MDbgBreakpoint object from the CorBreakpoint object.
 /// </summary>
 /// <param name="corBreakpoint">breakpoint object from CorXXX layer.</param>
 /// <returns>MDbgBreakpoint object</returns>
 /// <remarks>
 ///     returns null if there the breakpoint was not known to the breakpoint
 ///     collection.
 /// </remarks>
 public MDbgBreakpoint Lookup(CorDebug.CorBreakpoint corBreakpoint)
 {
     foreach (MDbgBreakpoint b in m_items)
     {
         foreach (CorDebug.CorBreakpoint cb in b.CorBreakpoints)
         {
             if (cb == corBreakpoint)
             {
                 return b;
             }
         }
     }
     return null;
 }
 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;
 }
Example #25
0
 private void Initialize(MDbgProcess process, string name, CorDebug.CorValue value)
 {
     m_process = process;
     m_name = name;
     m_corValue = value;
 }
Example #26
0
 internal void Unregister(CorDebug.CorModule managedModule)
 {
     Debug.Assert(m_items.ContainsKey(managedModule));
     m_items.Remove(managedModule);
 }
Example #27
0
 private void Unbox(ref CorDebug.CorValue value)
 {
     CorDebug.CorBoxValue boxVal = value.CastToBoxValue();
     if (boxVal != null)
         value = boxVal.GetObject();
 }
Example #28
0
 /// <summary>
 /// Gets the MDbgFunction for a given CorFunction.
 /// </summary>
 /// <param name="managedFunction">The CorFunction to lookup.</param>
 /// <returns>The coresponding MDbgFunction.</returns>
 public MDbgFunction GetFunction(CorDebug.CorFunction managedFunction)
 {
     return m_functions.Get(managedFunction);
 }
Example #29
0
        private string MakePtrString(CorDebug.CorValue value)
        {
            var sb = new StringBuilder();

            while (true)
            {
                CorDebug.CorReferenceValue rv = value.CastToReferenceValue();
                if (rv == null)
                    break; // not a reference

                if (sb.Length > 0)
                {
                    sb.Append("->");
                }
                sb.Append("0x" + rv.Value.ToString("X", CultureInfo.CurrentUICulture));

                CorDebug.CorValue newValue = null;
                try
                {
                    newValue = rv.Dereference();
                }
                catch (COMException ce)
                {
                    if (ce.ErrorCode != (int) CorDebug.HResult.CORDBG_E_BAD_REFERENCE_VALUE)
                    {
                        throw; // some other error
                    }
                }

                if (newValue == null)
                    break; // couldn't dereference the reference (eg. void* or invalid ref)

                value = newValue;
            }

            return sb.ToString();
        }
Example #30
0
 /// <summary>
 /// Looks up a CorModule.
 /// </summary>
 /// <param name="managedModule">Which CorModule to lookup.</param>
 /// <returns>The coresponding MDbgModule.</returns>
 public MDbgModule Lookup(CorDebug.CorModule managedModule)
 {
     return (MDbgModule) m_items[managedModule];
 }
Example #31
0
        private CorDebug.CorValue Dereference(CorDebug.CorValue value)
        {
            while (true)
            {
                CorDebug.CorReferenceValue rv = value.CastToReferenceValue();
                if (rv == null)
                    break; // not a reference

                if (rv.IsNull)
                    return null; // reference to null

                CorDebug.CorValue newValue = rv.Dereference();
                if (newValue == null)
                    break; // couldn't dereference the reference (eg. void*)

                value = newValue;
            }
            return value;
        }