Example #1
0
 /// <summary>
 /// Constructor
 /// </summary>
 /// <param name="thread">Current thread</param>
 public DbgDotNetStepperBreakpointEventArgs(DbgThread thread) =>
 public void Initialize(DbgProcess process, DbgThread thread)
 {
     this.process = process ?? throw new ArgumentNullException(nameof(process));
     this.thread  = thread;
 }
 public override DbgCodeBreakpointCheckResult ShouldBreak(DbgBoundCodeBreakpoint boundBreakpoint, DbgThread thread, in DbgCodeBreakpointFilter filter)
 public abstract void Print(DbgBoundCodeBreakpoint boundBreakpoint, DbgThread thread, DbgCodeBreakpointTrace trace);
 public override DbgEngineStepper Create(IDbgDotNetRuntime runtime, DbgDotNetEngineStepper stepper, DbgThread thread)
 {
     if (runtime == null)
     {
         throw new ArgumentNullException(nameof(runtime));
     }
     if (stepper == null)
     {
         throw new ArgumentNullException(nameof(stepper));
     }
     if (thread == null)
     {
         throw new ArgumentNullException(nameof(thread));
     }
     return(new DbgEngineStepperImpl(dbgLanguageService, dbgDotNetDebugInfoService, debuggerSettings, runtime, stepper, thread));
 }
Example #6
0
 /// <summary>
 /// Sets a new instruction pointer
 /// </summary>
 /// <param name="thread">Thread</param>
 /// <param name="location">New location</param>
 public abstract void SetIP(DbgThread thread, DbgCodeLocation location);
Example #7
0
        /// <summary>
        /// Gets the first non-null frame location. This location must be <see cref="DbgCodeLocation.Close"/>'d
        /// by the caller.
        /// </summary>
        /// <param name="thread">Thread</param>
        /// <returns></returns>
        public static (DbgCodeLocation?location, int frameIndex) GetFirstFrameLocation(DbgThread thread)
        {
            DbgStackWalker?stackWalker = null;
            var            objsToFree  = new List <DbgObject>();

            try {
                stackWalker = thread.CreateStackWalker();
                objsToFree.Add(stackWalker);
                int frameIndex = 0;
                while (frameIndex < 20)
                {
                    // Usually the first frame contains a location and if not, the one after that.
                    var frames = stackWalker.GetNextStackFrames(2);
                    objsToFree.AddRange(frames);
                    if (frames.Length == 0)
                    {
                        break;
                    }
                    foreach (var frame in frames)
                    {
                        var location = frame.Location;
                        if (location is not null)
                        {
                            return(location.Clone(), frameIndex);
                        }
                        frameIndex++;
                    }
                }
            }
            finally {
                if (objsToFree.Count > 0)
                {
                    thread.Process.DbgManager.Close(objsToFree);
                }
            }
            return(null, -1);
        }
        public override DbgEngineStepper CreateStepper(DbgThread thread)
        {
            var data = thread.GetData <DbgThreadData>();

            return(dbgEngineStepperFactory.Create(DotNetRuntime, new DbgDotNetEngineStepperImpl(this), thread));
        }
 public abstract bool ShouldBreak(DbgBoundCodeBreakpoint boundBreakpoint, DbgThread thread, DbgCodeBreakpointFilter filter);
Example #10
0
 DbgDotNetValueResult FuncEvalCallCore_MonoDebug(DbgEvaluationContext?contextOpt, DbgStackFrame?frameOpt, DbgThread thread, DmdMethodBase method, DbgDotNetValue?obj, object?[] arguments, DbgDotNetInvokeOptions invokeOptions, bool newObj, CancellationToken cancellationToken)
 {
     // ReturnOutThis is only available since 2.35 so we'll special case the common case where a struct ctor
     // is called (CALL/CALLVIRT). We'll change it to a NEWOBJ and then copy the result to the input 'this' value.
     if (!newObj && obj is DbgDotNetValueImpl objImpl && method is DmdConstructorInfo ctor && ctor.ReflectedType !.IsValueType)
     {
         var res = FuncEvalCallCoreReal_MonoDebug(contextOpt, frameOpt, thread, method, null, arguments, invokeOptions, true, cancellationToken);
         if (res.IsNormalResult)
         {
             try {
                 var error = objImpl.ValueLocation.Store(((DbgDotNetValueImpl)res.Value !).Value);
                 if (!(error is null))
                 {
                     res.Value?.Dispose();
                     return(DbgDotNetValueResult.CreateError(error));
                 }
             }
             catch {
                 res.Value?.Dispose();
                 throw;
             }
         }
         return(res);
     }
Example #11
0
 public DbgEngineStackWalkerImpl(Lazy <DbgDotNetNativeCodeLocationFactory> dbgDotNetNativeCodeLocationFactory, Lazy <DbgDotNetCodeLocationFactory> dbgDotNetCodeLocationFactory, DbgEngineImpl engine, DnThread dnThread, DbgThread thread, ICorDebugFrame[] framesBuffer)
 {
     this.dbgDotNetNativeCodeLocationFactory = dbgDotNetNativeCodeLocationFactory ?? throw new ArgumentNullException(nameof(dbgDotNetNativeCodeLocationFactory));
     this.dbgDotNetCodeLocationFactory       = dbgDotNetCodeLocationFactory ?? throw new ArgumentNullException(nameof(dbgDotNetCodeLocationFactory));
     this.engine       = engine ?? throw new ArgumentNullException(nameof(engine));
     this.dnThread     = dnThread ?? throw new ArgumentNullException(nameof(dnThread));
     this.thread       = thread ?? throw new ArgumentNullException(nameof(thread));
     this.framesBuffer = framesBuffer ?? throw new ArgumentNullException(nameof(framesBuffer));
     continueCounter   = dnThread.Debugger.ContinueCounter;
 }
Example #12
0
        bool ShouldBreak(DbgBoundCodeBreakpoint boundBreakpoint, DbgThread thread)
        {
            if (thread == null)
            {
                return(false);
            }
            var bp = (DbgCodeBreakpointImpl)boundBreakpoint.Breakpoint;

            if (bp.IsClosed || boundBreakpoint.IsClosed)
            {
                return(false);
            }

            var settings = bp.Settings;

            if (!settings.IsEnabled)
            {
                return(false);
            }

            if (!bp.RaiseHitCheck(boundBreakpoint, thread))
            {
                return(false);
            }

            DbgCodeBreakpointCheckResult checkRes;

            if (settings.Filter is DbgCodeBreakpointFilter filter)
            {
                checkRes = dbgCodeBreakpointFilterChecker.Value.ShouldBreak(boundBreakpoint, thread, filter);
                if (checkRes.ErrorMessage != null)
                {
                    boundBreakpoint.Process.DbgManager.ShowError(checkRes.ErrorMessage);
                    return(true);
                }
                if (!checkRes.ShouldBreak)
                {
                    return(false);
                }
            }

            if (settings.Condition is DbgCodeBreakpointCondition condition)
            {
                checkRes = dbgCodeBreakpointConditionChecker.Value.ShouldBreak(boundBreakpoint, thread, condition);
                if (checkRes.ErrorMessage != null)
                {
                    boundBreakpoint.Process.DbgManager.ShowError(checkRes.ErrorMessage);
                    return(true);
                }
                if (!checkRes.ShouldBreak)
                {
                    return(false);
                }
            }

            // This counts as a hit, even if there's no 'hit count' option
            int currentHitCount = dbgCodeBreakpointHitCountService.Value.Hit_DbgThread(boundBreakpoint.Breakpoint);

            if (settings.HitCount is DbgCodeBreakpointHitCount hitCount)
            {
                checkRes = dbgCodeBreakpointHitCountChecker.Value.ShouldBreak(boundBreakpoint, thread, hitCount, currentHitCount);
                if (checkRes.ErrorMessage != null)
                {
                    boundBreakpoint.Process.DbgManager.ShowError(checkRes.ErrorMessage);
                    return(true);
                }
                if (!checkRes.ShouldBreak)
                {
                    return(false);
                }
            }

            bool shouldBreak;

            if (settings.Trace is DbgCodeBreakpointTrace trace)
            {
                dbgCodeBreakpointTraceMessagePrinter.Value.Print(boundBreakpoint, thread, trace);
                shouldBreak = !trace.Continue;
            }
            else
            {
                shouldBreak = true;
            }
            if (shouldBreak)
            {
                bp.RaiseHit(boundBreakpoint, thread);
            }
            return(shouldBreak);
        }
Example #13
0
 public DbgEngineStackWalkerImpl(Lazy <DbgDotNetCodeLocationFactory> dbgDotNetCodeLocationFactory, DbgEngineImpl engine, ThreadMirror monoThread, DbgThread thread)
 {
     this.dbgDotNetCodeLocationFactory = dbgDotNetCodeLocationFactory ?? throw new ArgumentNullException(nameof(dbgDotNetCodeLocationFactory));
     this.engine     = engine ?? throw new ArgumentNullException(nameof(engine));
     this.monoThread = monoThread ?? throw new ArgumentNullException(nameof(monoThread));
     this.thread     = thread ?? throw new ArgumentNullException(nameof(thread));
     continueCounter = engine.ContinueCounter;
 }
Example #14
0
 /// <summary>
 /// Gets frame info or null if none is available
 /// </summary>
 /// <param name="thread">Thread</param>
 /// <returns></returns>
 public abstract DbgDotNetEngineStepperFrameInfo TryGetFrameInfo(DbgThread thread);
Example #15
0
 /// <summary>
 /// Creates a stack walker
 /// </summary>
 /// <param name="thread">Thread created by this engine</param>
 /// <returns></returns>
 public abstract DbgEngineStackWalker CreateStackWalker(DbgThread thread);
 internal DnThread GetThread(DbgThread thread) =>
 thread?.GetData <DbgThreadData>()?.DnThread ?? throw new InvalidOperationException();
Example #17
0
 /// <summary>
 /// Creates a stepper
 /// </summary>
 /// <param name="thread">Thread to step</param>
 /// <returns></returns>
 public abstract DbgEngineStepper CreateStepper(DbgThread thread);
Example #18
0
 /// <summary>
 /// Constructor
 /// </summary>
 /// <param name="thread">Thread</param>
 /// <param name="error">Error message or null if none</param>
 public DbgStepCompleteEventArgs(DbgThread thread, string error)
 {
     Thread = thread ?? throw new ArgumentNullException(nameof(thread));
     Error  = error;
 }
Example #19
0
 /// <summary>
 /// Checks if <see cref="SetIP(DbgThread, DbgCodeLocation)"/> can be called
 /// </summary>
 /// <param name="thread">Thread</param>
 /// <param name="location">New location</param>
 /// <returns></returns>
 public abstract bool CanSetIP(DbgThread thread, DbgCodeLocation location);
Example #20
0
 internal DnThread GetThread(DbgThread thread) =>
 TryGetThreadData(thread)?.DnThread ?? throw new InvalidOperationException();
 internal ThreadMirror GetThread(DbgThread thread) =>
 TryGetThreadData(thread)?.MonoThread ?? throw new InvalidOperationException();
 public override DbgCodeBreakpointCheckResult ShouldBreak(DbgBoundCodeBreakpoint boundBreakpoint, DbgThread thread, in DbgCodeBreakpointHitCount hitCount, int currentHitCount)
Example #23
0
 public DbgEngineStepperImpl(DbgDotNetCodeRangeService dbgDotNetCodeRangeService, DbgEngineImpl engine, DbgThread thread, ThreadMirror monoThread)
 {
     this.dbgDotNetCodeRangeService = dbgDotNetCodeRangeService ?? throw new ArgumentNullException(nameof(dbgDotNetCodeRangeService));
     this.engine     = engine ?? throw new ArgumentNullException(nameof(engine));
     this.thread     = thread ?? throw new ArgumentNullException(nameof(thread));
     this.monoThread = monoThread ?? throw new ArgumentNullException(nameof(monoThread));
 }
Example #24
0
 public abstract DbgCodeBreakpointCheckResult ShouldBreak(DbgBoundCodeBreakpoint boundBreakpoint, DbgThread thread, DbgCodeBreakpointCondition condition);
 public abstract DbgCodeBreakpointCheckResult ShouldBreak(DbgBoundCodeBreakpoint boundBreakpoint, DbgThread thread, in DbgCodeBreakpointFilter filter);
Example #26
0
 /// <summary>
 /// Freezes the thread
 /// </summary>
 /// <param name="thread">Thread</param>
 public abstract void Freeze(DbgThread thread);
 public void Clear()
 {
     process = null;
     thread  = null;
 }
Example #28
0
 /// <summary>
 /// Thaws the thread
 /// </summary>
 /// <param name="thread">Thread</param>
 public abstract void Thaw(DbgThread thread);
        internal DbgDotNetValueResult FuncEvalCall_CorDebug(DbgEvaluationContext context, DbgThread thread, CorAppDomain appDomain, DmdMethodBase method, DbgDotNetValue obj, object[] arguments, bool newObj, CancellationToken cancellationToken)
        {
            debuggerThread.VerifyAccess();
            cancellationToken.ThrowIfCancellationRequested();
            var tmp = CheckFuncEval(context);

            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(new DbgDotNetValueResult(CordbgErrorHelper.InternalError));
            }

            var reflectionAppDomain = thread.AppDomain.GetReflectionAppDomain() ?? throw new InvalidOperationException();
            var methodDbgModule     = method.Module.GetDebuggerModule() ?? throw new InvalidOperationException();

            if (!TryGetDnModule(methodDbgModule, out var methodModule))
            {
                return(new DbgDotNetValueResult(CordbgErrorHelper.InternalError));
            }
            var func = methodModule.CorModule.GetFunctionFromToken((uint)method.MetadataToken) ?? throw new InvalidOperationException();

            var dnThread      = GetThread(thread);
            var createdValues = new List <CorValue>();

            try {
                using (var dnEval = dnDebugger.CreateEval(cancellationToken, suspendOtherThreads: (context.Options & DbgEvaluationContextOptions.RunAllThreads) == 0)) {
                    dnEval.SetThread(dnThread);
                    dnEval.SetTimeout(context.FuncEvalTimeout);
                    dnEval.EvalEvent += (s, e) => DnEval_EvalEvent(dnEval, context);

                    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(new DbgDotNetValueResult(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(new DbgDotNetValueResult(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
                    w = hiddenThisArg ? 1 : 0;
                    for (int i = 0; i < arguments.Length; i++)
                    {
                        var paramType = paramTypes[i];
                        var arg       = args[w];
                        if (paramType.IsValueType || paramType.IsPointer || paramType.IsFunctionPointer)
                        {
                            if (arg.IsReference)
                            {
                                if (arg.IsNull)
                                {
                                    throw new InvalidOperationException();
                                }
                                arg = arg.DereferencedValue ?? throw new InvalidOperationException();
                            }
                            if (arg.IsBox)
                            {
                                arg = arg.BoxedValue ?? throw new InvalidOperationException();
                            }
                            args[w] = arg;
                        }
                        w++;
                    }
                    if (args.Length != w)
                    {
                        throw new InvalidOperationException();
                    }

                    var res = newObj ?
                              dnEval.CallConstructor(func, typeArgs, args, out int hr) :
                              dnEval.Call(func, typeArgs, args, out hr);
                    if (res == null)
                    {
                        return(new DbgDotNetValueResult(CordbgErrorHelper.GetErrorMessage(hr)));
                    }
                    if (res.Value.WasCustomNotification)
                    {
                        return(new DbgDotNetValueResult(CordbgErrorHelper.FuncEvalRequiresAllThreadsToRun));
                    }
                    if (res.Value.WasCancelled)
                    {
                        return(new DbgDotNetValueResult(PredefinedEvaluationErrorMessages.FuncEvalTimedOut));
                    }
                    return(new DbgDotNetValueResult(CreateDotNetValue_CorDebug(res.Value.ResultOrException, reflectionAppDomain, tryCreateStrongHandle: true), valueIsException: res.Value.WasException));
                }
            }
            catch (TimeoutException) {
                return(new DbgDotNetValueResult(PredefinedEvaluationErrorMessages.FuncEvalTimedOut));
            }
            catch (Exception ex) when(ExceptionUtils.IsInternalDebuggerError(ex))
            {
                return(new DbgDotNetValueResult(CordbgErrorHelper.InternalError));
            }
            finally {
                foreach (var value in createdValues)
                {
                    dnDebugger.DisposeHandle(value);
                }
            }
        }
Example #30
0
 /// <summary>
 /// Creates a breakpoint
 /// </summary>
 /// <param name="thread">Thread or null to match any thread</param>
 /// <param name="module">Module</param>
 /// <param name="token">Method token</param>
 /// <param name="offset">IL offset</param>
 /// <returns></returns>
 public abstract DbgDotNetStepperBreakpoint CreateBreakpoint(DbgThread thread, DbgModule module, uint token, uint offset);