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))); } }