예제 #1
0
        public static DynamicStackFrame[] GetDynamicStackFrames(Exception e, bool filter)
        {
            List <DynamicStackFrame> frames = e.Data[typeof(DynamicStackFrame)] as List <DynamicStackFrame>;

            if (frames == null)
            {
                // we may have missed a dynamic catch, and our host is looking
                // for the exception...
                frames = ExceptionHelpers.AssociateDynamicStackFrames(e);
                ExceptionHelpers.DynamicStackFrames = null;
            }

            if (frames == null)
            {
                return(new DynamicStackFrame[0]);
            }

            if (!filter)
            {
                return(frames.ToArray());
            }

#if !SILVERLIGHT
            frames = new List <DynamicStackFrame>(frames);
            List <DynamicStackFrame> res = new List <DynamicStackFrame>();

            // the list of _stackFrames we build up in ScriptingRuntimeHelpers can have
            // too many frames if exceptions are thrown from script code and
            // caught outside w/o calling GetDynamicStackFrames.  Therefore we
            // filter down to only script frames which we know are associated
            // w/ the exception here.
            try {
                StackTrace         outermostTrace = new StackTrace(e);
                IList <StackTrace> otherTraces    = ExceptionHelpers.GetExceptionStackTraces(e) ?? new List <StackTrace>();
                List <StackFrame>  clrFrames      = new List <StackFrame>();
                foreach (StackTrace trace in otherTraces)
                {
                    clrFrames.AddRange(trace.GetFrames() ?? new StackFrame[0]);      // rare, sometimes GetFrames returns null
                }
                clrFrames.AddRange(outermostTrace.GetFrames() ?? new StackFrame[0]); // rare, sometimes GetFrames returns null

                int lastFound = 0;
                foreach (StackFrame clrFrame in InterpretedFrame.GroupStackFrames(clrFrames))
                {
                    MethodBase method = clrFrame.GetMethod();

                    for (int j = lastFound; j < frames.Count; j++)
                    {
                        MethodBase other = frames[j].GetMethod();
                        // method info's don't always compare equal, check based
                        // upon name/module/declaring type which will always be a correct
                        // check for dynamic methods.
                        if (method.Module == other.Module &&
                            method.DeclaringType == other.DeclaringType &&
                            method.Name == other.Name)
                        {
                            res.Add(frames[j]);
                            frames.RemoveAt(j);
                            lastFound = j;
                            break;
                        }
                    }
                }
            } catch (MemberAccessException) {
                // can't access new StackTrace(e) due to security
            }
            return(res.ToArray());
#else
            return(frames.ToArray());
#endif
        }