internal DbgDotNetValueResult CreateValue_CorDebug(DbgEvaluationInfo evalInfo, ILDbgEngineStackFrame ilFrame, object?value) { debuggerThread.VerifyAccess(); evalInfo.CancellationToken.ThrowIfCancellationRequested(); if (value is DbgDotNetValueImpl) { return(DbgDotNetValueResult.Create((DbgDotNetValueImpl)value)); } var tmp = CheckFuncEval(evalInfo); if (!(tmp is null)) { return(tmp.Value); } var dnThread = GetThread(evalInfo.Frame.Thread); var createdValues = new List <CorValue>(); CorValue?createdCorValue = null; try { var appDomain = ilFrame.GetCorAppDomain(); var reflectionAppDomain = ilFrame.GetReflectionModule().AppDomain; using (var dnEval = dnDebugger.CreateEval(evalInfo.CancellationToken, suspendOtherThreads: (evalInfo.Context.Options & DbgEvaluationContextOptions.RunAllThreads) == 0)) { dnEval.SetThread(dnThread); dnEval.SetTimeout(evalInfo.Context.FuncEvalTimeout); dnEval.EvalEvent += (s, e) => DnEval_EvalEvent(dnEval, evalInfo); var converter = new EvalArgumentConverter(this, dnEval, appDomain, reflectionAppDomain, createdValues); var evalRes = converter.Convert(value, reflectionAppDomain.System_Object, out var newValueType); if (!(evalRes.ErrorMessage is null)) { return(DbgDotNetValueResult.CreateError(evalRes.ErrorMessage)); } var resultValue = CreateDotNetValue_CorDebug(evalRes.CorValue !, reflectionAppDomain, tryCreateStrongHandle: true); createdCorValue = evalRes.CorValue; return(DbgDotNetValueResult.Create(resultValue)); } } catch (TimeoutException) { return(DbgDotNetValueResult.CreateError(PredefinedEvaluationErrorMessages.FuncEvalTimedOut)); } catch (Exception ex) when(ExceptionUtils.IsInternalDebuggerError(ex)) { return(DbgDotNetValueResult.CreateError(CordbgErrorHelper.InternalError)); } finally { foreach (var v in createdValues) { if (!v.Equals(createdCorValue)) { dnDebugger.DisposeHandle(v); } } } }
DbgDotNetValueResult GetArrayElementAt_MonoDebug(uint index) { Debug.Assert(Type.IsArray); engine.VerifyMonoDebugThread(); var info = GetArrayElementValueLocation_MonoDebug(index); if (info.errorMessage != null) { return(DbgDotNetValueResult.CreateError(info.errorMessage)); } return(DbgDotNetValueResult.Create(engine.CreateDotNetValue_MonoDebug(info.valueLocation))); }
DbgDotNetValueResult CreateInstanceCore(DmdConstructorInfo ctor, ILValue[] arguments) { if (ctor.IsStatic) { return(DbgDotNetValueResult.CreateError(PredefinedEvaluationErrorMessages.InternalDebuggerError)); } const DotNetClassHookCallOptions options = DotNetClassHookCallOptions.None; foreach (var anyHook in anyClassHooks) { var res = anyHook.CreateInstance(options, ctor, arguments); if (res != null) { return(DbgDotNetValueResult.Create(res)); } } var type = ctor.DeclaringType; if (type.IsConstructedGenericType) { type = type.GetGenericTypeDefinition(); } var typeName = DmdTypeName.Create(type); if (classHooks.TryGetValue(typeName, out var hook)) { if (DmdWellKnownTypeUtils.TryGetWellKnownType(typeName, out var wellKnownType)) { if (type != type.AppDomain.GetWellKnownType(wellKnownType, isOptional: true)) { hook = null; } } if (hook != null) { var res = hook.CreateInstance(options, ctor, arguments); if (res != null) { return(DbgDotNetValueResult.Create(res)); } } } if (!canFuncEval) { throw new InterpreterMessageException(PredefinedEvaluationErrorMessages.FuncEvalDisabled); } return(runtime.CreateInstance(evalInfo, ctor, Convert(arguments, ctor.GetMethodSignature().GetParameterTypes()), DbgDotNetInvokeOptions.None)); }
DbgDotNetValueResult Dereference_CorDebug() { Debug.Assert((Type.IsByRef && !IsNullByRef) || (Type.IsPointer && !IsNull)); engine.VerifyCorDebugThread(); int hr = -1; var dereferencedValue = TryGetCorValue()?.GetDereferencedValue(out hr); // We sometimes get 0x80131C49 = CORDBG_E_READVIRTUAL_FAILURE if (dereferencedValue is null) { return(DbgDotNetValueResult.CreateError(CordbgErrorHelper.GetErrorMessage(hr))); } return(DbgDotNetValueResult.Create(engine.CreateDotNetValue_CorDebug(dereferencedValue, Type.AppDomain, tryCreateStrongHandle: true))); }
// This method calls ICorDebugEval2.NewParameterizedArray() which doesn't support creating SZ arrays // with any element type. See the caller of this method (CreateSZArrayCore) for more info. internal DbgDotNetValueResult CreateSZArray_CorDebug(DbgEvaluationInfo evalInfo, CorAppDomain appDomain, DmdType elementType, int length) { debuggerThread.VerifyAccess(); evalInfo.CancellationToken.ThrowIfCancellationRequested(); var tmp = CheckFuncEval(evalInfo); if (tmp != null) { return(tmp.Value); } var dnThread = GetThread(evalInfo.Frame.Thread); try { using (var dnEval = dnDebugger.CreateEval(evalInfo.CancellationToken, suspendOtherThreads: (evalInfo.Context.Options & DbgEvaluationContextOptions.RunAllThreads) == 0)) { dnEval.SetThread(dnThread); dnEval.SetTimeout(evalInfo.Context.FuncEvalTimeout); dnEval.EvalEvent += (s, e) => DnEval_EvalEvent(dnEval, evalInfo); var corType = GetType(appDomain, elementType); var res = dnEval.CreateSZArray(corType, length, out int hr); if (res == null) { return(DbgDotNetValueResult.CreateError(CordbgErrorHelper.GetErrorMessage(hr))); } Debug.Assert(!res.Value.WasException, "Shouldn't throw " + nameof(ArgumentOutOfRangeException)); if (res.Value.WasCustomNotification) { return(DbgDotNetValueResult.CreateError(CordbgErrorHelper.FuncEvalRequiresAllThreadsToRun)); } if (res.Value.WasCancelled) { return(DbgDotNetValueResult.CreateError(PredefinedEvaluationErrorMessages.FuncEvalTimedOut)); } if (res.Value.WasException) { return(DbgDotNetValueResult.CreateException(CreateDotNetValue_CorDebug(res.Value.ResultOrException, elementType.AppDomain, tryCreateStrongHandle: true))); } return(DbgDotNetValueResult.Create(CreateDotNetValue_CorDebug(res.Value.ResultOrException, elementType.AppDomain, tryCreateStrongHandle: true))); } } catch (TimeoutException) { return(DbgDotNetValueResult.CreateError(PredefinedEvaluationErrorMessages.FuncEvalTimedOut)); } catch (Exception ex) when(ExceptionUtils.IsInternalDebuggerError(ex)) { return(DbgDotNetValueResult.CreateError(CordbgErrorHelper.InternalError)); } }
DbgDotNetValueResult CallCore(DbgDotNetValue obj, bool isCallvirt, DmdMethodBase method, ILValue[] arguments) { var options = isCallvirt ? DotNetClassHookCallOptions.IsCallvirt : DotNetClassHookCallOptions.None; foreach (var anyHook in anyClassHooks) { var res = anyHook.Call(options, obj, method, arguments); if (res != null) { return(DbgDotNetValueResult.Create(res)); } } var type = method.DeclaringType; if (type.IsConstructedGenericType) { type = type.GetGenericTypeDefinition(); } var typeName = DmdTypeName.Create(type); if (classHooks.TryGetValue(typeName, out var hook)) { if (DmdWellKnownTypeUtils.TryGetWellKnownType(typeName, out var wellKnownType)) { if (type != type.AppDomain.GetWellKnownType(wellKnownType, isOptional: true)) { hook = null; } } if (hook != null) { var res = hook.Call(options, obj, method, arguments); if (res != null) { return(DbgDotNetValueResult.Create(res)); } } } if (!canFuncEval) { throw new InterpreterMessageException(PredefinedEvaluationErrorMessages.FuncEvalDisabled); } var invokeOptions = isCallvirt ? DbgDotNetInvokeOptions.None : DbgDotNetInvokeOptions.NonVirtual; return(runtime.Call(evalInfo, obj, method, Convert(arguments, method.GetMethodSignature().GetParameterTypes()), invokeOptions)); }
public override DbgDotNetValueResult LoadIndirect() { if (!Type.IsByRef) { return(base.LoadIndirect()); } if (IsNullByRef) { return(DbgDotNetValueResult.Create(new SyntheticNullValue(Type.GetElementType()))); } if (engine.CheckMonoDebugThread()) { return(Dereference_MonoDebug()); } return(engine.InvokeMonoDebugThread(() => Dereference_MonoDebug())); }
internal DbgDotNetValueResult Box_CorDebug(DbgEvaluationInfo evalInfo, CorAppDomain appDomain, CorValue value, DmdType type) { debuggerThread.VerifyAccess(); evalInfo.CancellationToken.ThrowIfCancellationRequested(); var tmp = CheckFuncEval(evalInfo); if (!(tmp is null)) { return(tmp.Value); } var dnThread = GetThread(evalInfo.Frame.Thread); var createdValues = new List <CorValue>(); CorValue?boxedValue = null; try { using (var dnEval = dnDebugger.CreateEval(evalInfo.CancellationToken, suspendOtherThreads: (evalInfo.Context.Options & DbgEvaluationContextOptions.RunAllThreads) == 0)) { dnEval.SetThread(dnThread); dnEval.SetTimeout(evalInfo.Context.FuncEvalTimeout); dnEval.EvalEvent += (s, e) => DnEval_EvalEvent(dnEval, evalInfo); boxedValue = BoxIfNeeded(dnEval, appDomain, createdValues, value, type.AppDomain.System_Object, type); if (boxedValue is null) { return(DbgDotNetValueResult.CreateError(CordbgErrorHelper.GetErrorMessage(-1))); } return(DbgDotNetValueResult.Create(CreateDotNetValue_CorDebug(boxedValue, type.AppDomain, tryCreateStrongHandle: true))); } } catch (TimeoutException) { return(DbgDotNetValueResult.CreateError(PredefinedEvaluationErrorMessages.FuncEvalTimedOut)); } catch (Exception ex) when(ExceptionUtils.IsInternalDebuggerError(ex)) { return(DbgDotNetValueResult.CreateError(CordbgErrorHelper.InternalError)); } finally { foreach (var v in createdValues) { if (!v.Equals(boxedValue)) { dnDebugger.DisposeHandle(v); } } } }
public override DbgDotNetValueResult GetVariable(int index) { if ((uint)index < (uint)realLocalVariables.Count) { return(localsProvider.GetVariable(index)); } if ((uint)index < (uint)localVariables.Count) { var type = localVariables[index].LocalType; if (!extraLocals.TryGetValue(index, out var localValue)) { localValue = runtime.GetDefaultValue(type); extraLocals.Add(index, localValue); } return(DbgDotNetValueResult.Create(localValue)); } return(DbgDotNetValueResult.CreateError(PredefinedEvaluationErrorMessages.InternalDebuggerError)); }
DbgDotNetValueResult GetArrayElementAt_CorDebug(uint index) { Debug.Assert(Type.IsArray); engine.VerifyCorDebugThread(); var corValue = TryGetCorValue(); if (corValue == null || corValue.IsNull) { return(DbgDotNetValueResult.CreateError(CordbgErrorHelper.InternalError)); } using (var obj = new ArrayObjectValue(engine, corValue)) { int hr = -1; var elemValue = obj.Value?.GetElementAtPosition(index, out hr); if (elemValue == null) { return(DbgDotNetValueResult.CreateError(CordbgErrorHelper.GetErrorMessage(hr))); } return(DbgDotNetValueResult.Create(engine.CreateDotNetValue_CorDebug(elemValue, Type.AppDomain, tryCreateStrongHandle: true))); } }
DbgDotNetValueResult Dereference_MonoDebug() { Debug.Assert(Type.IsByRef && !IsNullByRef); engine.VerifyMonoDebugThread(); return(DbgDotNetValueResult.Create(engine.CreateDotNetValue_MonoDebug(valueLocation.Dereference()))); }
internal DbgDotNetValueResult FuncEvalCall_CorDebug(DbgEvaluationInfo evalInfo, CorAppDomain appDomain, DmdMethodBase method, DbgDotNetValue obj, object[] arguments, bool newObj) { debuggerThread.VerifyAccess(); evalInfo.CancellationToken.ThrowIfCancellationRequested(); var tmp = CheckFuncEval(evalInfo); if (tmp != null) { return(tmp.Value); } Debug.Assert(!newObj || method.IsConstructor); Debug.Assert(method.SpecialMethodKind == DmdSpecialMethodKind.Metadata, "Methods not defined in metadata should be emulated by other code (i.e., the caller)"); if (method.SpecialMethodKind != DmdSpecialMethodKind.Metadata) { return(DbgDotNetValueResult.CreateError(CordbgErrorHelper.InternalError)); } var reflectionAppDomain = method.AppDomain; var methodDbgModule = method.Module.GetDebuggerModule() ?? throw new InvalidOperationException(); if (!TryGetDnModule(methodDbgModule, out var methodModule)) { return(DbgDotNetValueResult.CreateError(CordbgErrorHelper.InternalError)); } var func = methodModule.CorModule.GetFunctionFromToken((uint)method.MetadataToken) ?? throw new InvalidOperationException(); int hr; var dnThread = GetThread(evalInfo.Frame.Thread); var createdValues = new List <CorValue>(); try { using (var dnEval = dnDebugger.CreateEval(evalInfo.CancellationToken, suspendOtherThreads: (evalInfo.Context.Options & DbgEvaluationContextOptions.RunAllThreads) == 0)) { dnEval.SetThread(dnThread); dnEval.SetTimeout(evalInfo.Context.FuncEvalTimeout); dnEval.EvalEvent += (s, e) => DnEval_EvalEvent(dnEval, evalInfo); var converter = new EvalArgumentConverter(this, dnEval, appDomain, reflectionAppDomain, createdValues); var genTypeArgs = method.DeclaringType.GetGenericArguments(); var methTypeArgs = method.GetGenericArguments(); var typeArgs = genTypeArgs.Count == 0 && methTypeArgs.Count == 0 ? Array.Empty <CorType>() : new CorType[genTypeArgs.Count + methTypeArgs.Count]; int w = 0; for (int i = 0; i < genTypeArgs.Count; i++) { typeArgs[w++] = GetType(appDomain, genTypeArgs[i]); } for (int i = 0; i < methTypeArgs.Count; i++) { typeArgs[w++] = GetType(appDomain, methTypeArgs[i]); } if (typeArgs.Length != w) { throw new InvalidOperationException(); } var paramTypes = GetAllMethodParameterTypes(method.GetMethodSignature()); if (paramTypes.Count != arguments.Length) { throw new InvalidOperationException(); } bool hiddenThisArg = !method.IsStatic && !newObj; int argsCount = arguments.Length + (hiddenThisArg ? 1 : 0); var args = argsCount == 0 ? Array.Empty <CorValue>() : new CorValue[argsCount]; w = 0; DmdType origType; if (hiddenThisArg) { var declType = method.DeclaringType; if (method is DmdMethodInfo m) { declType = m.GetBaseDefinition().DeclaringType; } var val = converter.Convert(obj, declType, out origType); if (val.ErrorMessage != null) { return(DbgDotNetValueResult.CreateError(val.ErrorMessage)); } args[w++] = BoxIfNeeded(dnEval, appDomain, createdValues, val.CorValue, declType, origType); } for (int i = 0; i < arguments.Length; i++) { var paramType = paramTypes[i]; var val = converter.Convert(arguments[i], paramType, out origType); if (val.ErrorMessage != null) { return(DbgDotNetValueResult.CreateError(val.ErrorMessage)); } var valType = origType ?? new ReflectionTypeCreator(this, method.AppDomain).Create(val.CorValue.ExactType); args[w++] = BoxIfNeeded(dnEval, appDomain, createdValues, val.CorValue, paramType, valType); } if (args.Length != w) { throw new InvalidOperationException(); } // Derefence/unbox the values here now that they can't get neutered for (int i = 0; i < args.Length; i++) { DmdType argType; if (!hiddenThisArg) { argType = paramTypes[i]; } else if (i == 0) { argType = method.DeclaringType; } else { argType = paramTypes[i - 1]; } var arg = args[i]; if (argType.IsValueType || argType.IsPointer || argType.IsFunctionPointer) { if (arg.IsReference) { if (arg.IsNull) { throw new InvalidOperationException(); } arg = arg.GetDereferencedValue(out hr); if (arg == null) { return(DbgDotNetValueResult.CreateError(CordbgErrorHelper.GetErrorMessage(hr))); } } if (arg.IsBox) { arg = arg.GetBoxedValue(out hr); if (arg == null) { return(DbgDotNetValueResult.CreateError(CordbgErrorHelper.GetErrorMessage(hr))); } } args[i] = arg; } } var res = newObj ? dnEval.CallConstructor(func, typeArgs, args, out hr) : dnEval.Call(func, typeArgs, args, out hr); if (res == null) { return(DbgDotNetValueResult.CreateError(CordbgErrorHelper.GetErrorMessage(hr))); } if (res.Value.WasCustomNotification) { return(DbgDotNetValueResult.CreateError(CordbgErrorHelper.FuncEvalRequiresAllThreadsToRun)); } if (res.Value.WasCancelled) { return(DbgDotNetValueResult.CreateError(PredefinedEvaluationErrorMessages.FuncEvalTimedOut)); } if (res.Value.WasException) { return(DbgDotNetValueResult.CreateException(CreateDotNetValue_CorDebug(res.Value.ResultOrException, reflectionAppDomain, tryCreateStrongHandle: true))); } return(DbgDotNetValueResult.Create(CreateDotNetValue_CorDebug(res.Value.ResultOrException, reflectionAppDomain, tryCreateStrongHandle: true))); } } catch (TimeoutException) { return(DbgDotNetValueResult.CreateError(PredefinedEvaluationErrorMessages.FuncEvalTimedOut)); } catch (Exception ex) when(ExceptionUtils.IsInternalDebuggerError(ex)) { return(DbgDotNetValueResult.CreateError(CordbgErrorHelper.InternalError)); } finally { foreach (var value in createdValues) { dnDebugger.DisposeHandle(value); } } }