Ejemplo n.º 1
0
        /// <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 &amp; 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);
        }
Ejemplo n.º 2
0
        private string PrintObject(int indentLevel, CorObjectValue ov, int expandDepth, bool canDoFunceval)
        {
            Debug.Assert(expandDepth >= 0);

            bool fNeedToResumeThreads = true;

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

            StringBuilder 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.
                StringBuilder 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 the value we're printing is a nullable type that has no value (is null), we can't do a func eval
                // to get its value, since it will be boxed as a null pointer. We already have the information we need, so
                // we'll just take care of it now. Note that ToString() for null-valued nullable types just prints the
                // empty string.

                // bool hasValue = (bool)(GetField("hasValue").CorValue.CastToGenericValue().GetValue());

                if (IsNullableType(ov.ExactType) && !(bool)(GetField("hasValue").CorValue.CastToGenericValue().GetValue()))
                {
                    txt.Append(" < >");
                }

                else if (ov.IsValueClass && canDoFunceval)
                // we could display even values for real Objects, but we will just show
                // "description" for valueclasses.
                {
                    CorClass          cls      = ov.ExactType.Class;
                    CorMetadataImport importer = m_process.Modules.Lookup(cls.Module).Importer;
                    MetadataType      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;

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

                        try
                        {
                            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)[0];

                            Debug.Assert(toStringFunc != null); // we should be always able to resolve ToString function.

                            eval.CallFunction(toStringFunc.CorFunction, new CorValue[] { thisValue });
                            m_process.Go();
                            do
                            {
                                m_process.StopEvent.WaitOne();
                                if (m_process.StopReason is EvalCompleteStopReason)
                                {
                                    CorValue cv = eval.Result;
                                    Debug.Assert(cv != null);
                                    MDbgValue 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 cannot copy a VC class error - Can't copy a VC with object refs in it.
                            if (e.ErrorCode != (int)HResult.CORDBG_E_OBJECT_IS_NOT_COPYABLE_VALUE_CLASS)
                            {
                                throw;
                            }
                        }
                        catch (System.NotImplementedException)
                        {
                            fNeedToResumeThreads = false;
                        }
                        finally
                        {
                            if (fNeedToResumeThreads)
                            {
                                // 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());
        }