Example #1
0
        public static void UnwrapGCHandleCmd(string arguments)
        {
            ArgParser ap = new ArgParser(arguments);
            if (ap.Count != 1)
            {
                WriteError("Wrong arguments, should be name or address of a \"System.Runtime.InteropServices.GCHandle\" object.");
                return;
            }

            long handleAdd = 0;

            // First try to resolve the argument as a variable in the current frame
            MDbgValue var = Debugger.Processes.Active.ResolveVariable(
                                                                      ap.AsString(0),
                                                                      Debugger.Processes.Active.Threads.Active.CurrentFrame);
            if (var != null)
            {
                if (var.TypeName != "System.Runtime.InteropServices.GCHandle")
                {
                    WriteError("Variable is not of type \"System.Runtime.InteropServices.GCHandle\".");
                    return;
                }

                foreach (MDbgValue field in var.GetFields())
                {
                    if (field.Name == "m_handle")
                    {
                        handleAdd = Int64.Parse(field.GetStringValue(0));
                        break;
                    }
                }
            }
            else
            {
                // Trying to resolve as a raw address now
                try
                {
                    handleAdd = ap.GetArgument(0).AsAddress;
                }
                catch (System.FormatException)
                {
                    WriteError("Couldn't recognize the argument as a variable name or address");
                    return;
                }
            }

            IntPtr add = new IntPtr(handleAdd);
            CorReferenceValue result;

            try
            {
                result = Debugger.Processes.Active.CorProcess.GetReferenceValueFromGCHandle(add);
            }
            catch (System.Runtime.InteropServices.COMException e)
            {
                if (e.ErrorCode == (int)HResult.CORDBG_E_BAD_REFERENCE_VALUE)
                {
                    WriteError("Invalid handle address.");
                    return;
                }
                else
                {
                    throw;
                }
            }

            CorValue v = result.Dereference();
            MDbgValue mv = new MDbgValue(Debugger.Processes.Active, v);
            if (mv.IsComplexType)
            {
                WriteOutput(string.Format("GCHandle to <{0}>",
                                          InternalUtil.PrintCorType(Debugger.Processes.Active, v.ExactType)));

                // now print fields as well
                foreach (MDbgValue f in mv.GetFields())
                    CommandBase.WriteOutput(" " + f.Name + "=" + f.GetStringValue(0));
            }
            else
            {
                WriteOutput(string.Format("GCHandle to {0}", mv.GetStringValue(0)));
            }
        }