Пример #1
0
        ICorDebugValue GetCorValue(Value objectInstance)
        {
            if (objectInstance != null)
            {
                if (!DeclaringType.IsInstanceOfType(objectInstance))
                {
                    throw new CannotGetValueException("Object is not of type " + DeclaringType.FullName);
                }
            }

            // Current frame is used to resolve context specific static values (eg. ThreadStatic)
            ICorDebugFrame curFrame = null;

            if (this.Process.IsPaused &&
                this.Process.SelectedThread != null &&
                this.Process.SelectedThread.LastFunction != null &&
                this.Process.SelectedThread.LastFunction.CorILFrame != null)
            {
                curFrame = this.Process.SelectedThread.LastFunction.CorILFrame.CastTo <ICorDebugFrame>();
            }

            try {
                if (this.IsStatic)
                {
                    return(DeclaringType.CorType.GetStaticFieldValue(MetadataToken, curFrame));
                }
                else
                {
                    return(objectInstance.CorObjectValue.GetFieldValue(DeclaringType.CorType.Class, MetadataToken));
                }
            }
            catch (System.Exception e)
            {
                throw new CannotGetValueException(e.Message);
            }
        }
Пример #2
0
        // See docs\Stepping.txt
        public void CheckExpiration()
        {
            try {
                ICorDebugChainEnum chainEnum = CorThread.EnumerateChains();
            } catch (COMException e) {
                // 0x8013132D: The state of the thread is invalid.
                // 0x8013134F: Object is in a zombie state
                // 0x80131301: Process was terminated.
                if ((uint)e.ErrorCode == 0x8013132D ||
                    (uint)e.ErrorCode == 0x8013134F ||
                    (uint)e.ErrorCode == 0x80131301)
                {
                    this.Expire();
                    return;
                }
                else
                {
                    throw;
                }
            }

            if (process.Evaluating)
            {
                return;
            }

            ICorDebugChainEnum corChainEnum = CorThread.EnumerateChains();
            int maxChainIndex = (int)corChainEnum.Count - 1;

            ICorDebugFrameEnum corFrameEnum = corChainEnum.Next().EnumerateFrames();
            // corFrameEnum.Count can return 0 in ExitThread callback
            int maxFrameIndex = (int)corFrameEnum.Count - 1;

            ICorDebugFrame lastFrame = corFrameEnum.Next();

            // Check the token of the current function - function can change if there are multiple handlers for an event
            Function function;

            if (lastFrame != null &&
                functionCache.TryGetValue(new FrameID((uint)maxChainIndex, (uint)maxFrameIndex), out function) &&
                function.Token != lastFrame.FunctionToken)
            {
                functionCache.Remove(new FrameID((uint)maxChainIndex, (uint)maxFrameIndex));
                function.OnExpired(EventArgs.Empty);
            }

            // Expire all functions behind the current maximum
            // Multiple functions can expire at once (test case: Step out of Button1Click in simple winforms application)
            List <KeyValuePair <FrameID, Function> > toBeRemoved = new List <KeyValuePair <FrameID, Function> >();

            foreach (KeyValuePair <FrameID, Function> kvp in functionCache)
            {
                if ((kvp.Key.ChainIndex > maxChainIndex) ||
                    (kvp.Key.ChainIndex == maxChainIndex && kvp.Key.FrameIndex > maxFrameIndex))
                {
                    toBeRemoved.Add(kvp);
                }
            }
            foreach (KeyValuePair <FrameID, Function> kvp in toBeRemoved)
            {
                functionCache.Remove(kvp.Key);
                kvp.Value.OnExpired(EventArgs.Empty);
            }
        }