Пример #1
0
        public StackFrameHelper(Thread target)
        {
            targetThread         = target;
            rgMethodBase         = null;
            rgMethodHandle       = null;
            rgiMethodToken       = null;
            rgiOffset            = null;
            rgiILOffset          = null;
            rgAssemblyPath       = null;
            rgLoadedPeAddress    = null;
            rgiLoadedPeSize      = null;
            rgInMemoryPdbAddress = null;
            rgiInMemoryPdbSize   = null;
            dynamicMethods       = null;
            rgFilename           = null;
            rgiLineNumber        = null;
            rgiColumnNumber      = null;
            getSourceLineInfo    = null;

#if FEATURE_EXCEPTIONDISPATCHINFO
            rgiLastFrameFromForeignExceptionStackTrace = null;
#endif // FEATURE_EXCEPTIONDISPATCHINFO

            // 0 means capture all frames.  For StackTraces from an Exception, the EE always
            // captures all frames.  For other uses of StackTraces, we can abort stack walking after
            // some limit if we want to by setting this to a non-zero value.  In Whidbey this was
            // hard-coded to 512, but some customers complained.  There shouldn't be any need to limit
            // this as memory/CPU is no longer allocated up front.  If there is some reason to provide a
            // limit in the future, then we should expose it in the managed API so applications can
            // override it.
            iFrameCount = 0;
        }
Пример #2
0
        //
        // Initializes the stack trace helper. If fNeedFileInfo is true, initializes rgFilename,
        // rgiLineNumber and rgiColumnNumber fields using the portable PDB reader if not already
        // done by GetStackFramesInternal (on Windows for old PDB format).
        //
        internal void InitializeSourceInfo(int iSkip, bool fNeedFileInfo, Exception exception)
        {
            StackTrace.GetStackFramesInternal(this, iSkip, fNeedFileInfo, exception);

            if (!fNeedFileInfo)
            {
                return;
            }

            // Check if this function is being reentered because of an exception in the code below
            if (t_reentrancy > 0)
            {
                return;
            }

            t_reentrancy++;
            try
            {
                if (s_symbolsMethodInfo == null)
                {
                    s_symbolsType = Type.GetType("System.Diagnostics.StackTraceSymbols, System.Diagnostics.StackTrace, Version=1.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", throwOnError: false);
                    if (s_symbolsType == null)
                    {
                        return;
                    }

                    s_symbolsMethodInfo = s_symbolsType.GetMethod("GetSourceLineInfo");
                    if (s_symbolsMethodInfo == null)
                    {
                        return;
                    }
                }

                if (getSourceLineInfo == null)
                {
                    // Create an instance of System.Diagnostics.Stacktrace.Symbols
                    object target = Activator.CreateInstance(s_symbolsType);

                    // Create an instance delegate for the GetSourceLineInfo method
                    getSourceLineInfo = (GetSourceLineInfoDelegate)s_symbolsMethodInfo.CreateDelegate(typeof(GetSourceLineInfoDelegate), target);
                }

                for (int index = 0; index < iFrameCount; index++)
                {
                    // If there was some reason not to try get get the symbols from the portable PDB reader like the module was
                    // ENC or the source/line info was already retrieved, the method token is 0.
                    if (rgiMethodToken[index] != 0)
                    {
                        getSourceLineInfo(rgAssemblyPath[index], rgLoadedPeAddress[index], rgiLoadedPeSize[index],
                                          rgInMemoryPdbAddress[index], rgiInMemoryPdbSize[index], rgiMethodToken[index],
                                          rgiILOffset[index], out rgFilename[index], out rgiLineNumber[index], out rgiColumnNumber[index]);
                    }
                }
            }
            finally
            {
                t_reentrancy--;
            }
        }
Пример #3
0
        //
        // Initializes the stack trace helper. If fNeedFileInfo is true, initializes rgFilename,
        // rgiLineNumber and rgiColumnNumber fields using the portable PDB reader if not already
        // done by GetStackFramesInternal (on Windows for old PDB format).
        //

        internal void InitializeSourceInfo(int iSkip, bool fNeedFileInfo, Exception?exception)
        {
            StackTrace.GetStackFramesInternal(this, iSkip, fNeedFileInfo, exception);

            if (!fNeedFileInfo)
            {
                return;
            }

            // Check if this function is being reentered because of an exception in the code below
            if (t_reentrancy > 0)
            {
                return;
            }

            t_reentrancy++;
            try
            {
                if (s_getSourceLineInfo == null)
                {
                    Type?symbolsType = Type.GetType(
                        "System.Diagnostics.StackTraceSymbols, System.Diagnostics.StackTrace, Version=4.0.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a",
                        throwOnError: false);

                    if (symbolsType == null)
                    {
                        return;
                    }

                    Type[] parameterTypes = new Type[]
                    {
                        typeof(Assembly), typeof(string), typeof(IntPtr), typeof(int), typeof(bool), typeof(IntPtr),
                        typeof(int), typeof(int), typeof(int),
                        typeof(string).MakeByRefType(), typeof(int).MakeByRefType(), typeof(int).MakeByRefType()
                    };
                    MethodInfo?symbolsMethodInfo = symbolsType.GetMethod("GetSourceLineInfo", BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance, null, parameterTypes, null);
                    if (symbolsMethodInfo == null)
                    {
                        return;
                    }

                    // Create an instance of System.Diagnostics.Stacktrace.Symbols
                    object?target = Activator.CreateInstance(symbolsType);

                    // Create an instance delegate for the GetSourceLineInfo method
                    GetSourceLineInfoDelegate getSourceLineInfo = symbolsMethodInfo.CreateDelegate <GetSourceLineInfoDelegate>(target);

                    // We could race with another thread. It doesn't matter if we win or lose, the losing instance will be GC'ed and all threads including this one will
                    // use the winning instance
                    Interlocked.CompareExchange(ref s_getSourceLineInfo, getSourceLineInfo, null);
                }

                for (int index = 0; index < iFrameCount; index++)
                {
                    // If there was some reason not to try get the symbols from the portable PDB reader like the module was
                    // ENC or the source/line info was already retrieved, the method token is 0.
                    if (rgiMethodToken ![index] != 0)
Пример #4
0
        public StackFrameHelper(Thread target)
        {
            targetThread = target;
            rgMethodBase = null;
            rgMethodHandle = null;
            rgiMethodToken = null;
            rgiOffset = null;
            rgiILOffset = null;
            rgAssemblyPath = null;
            rgLoadedPeAddress = null;
            rgiLoadedPeSize = null;
            rgInMemoryPdbAddress = null;
            rgiInMemoryPdbSize = null;
            dynamicMethods = null;
            rgFilename = null;
            rgiLineNumber = null;
            rgiColumnNumber = null;
            getSourceLineInfo = null;

#if FEATURE_EXCEPTIONDISPATCHINFO
            rgiLastFrameFromForeignExceptionStackTrace = null;
#endif // FEATURE_EXCEPTIONDISPATCHINFO

            // 0 means capture all frames.  For StackTraces from an Exception, the EE always
            // captures all frames.  For other uses of StackTraces, we can abort stack walking after
            // some limit if we want to by setting this to a non-zero value.  In Whidbey this was 
            // hard-coded to 512, but some customers complained.  There shouldn't be any need to limit
            // this as memory/CPU is no longer allocated up front.  If there is some reason to provide a
            // limit in the future, then we should expose it in the managed API so applications can 
            // override it.
            iFrameCount = 0;
        }
Пример #5
0
        //
        // Initializes the stack trace helper. If fNeedFileInfo is true, initializes rgFilename, 
        // rgiLineNumber and rgiColumnNumber fields using the portable PDB reader if not already
        // done by GetStackFramesInternal (on Windows for old PDB format).
        //
        internal void InitializeSourceInfo(int iSkip, bool fNeedFileInfo, Exception exception)
        {
            StackTrace.GetStackFramesInternal(this, iSkip, fNeedFileInfo, exception);

            if (!fNeedFileInfo)
                return;

            // Check if this function is being reentered because of an exception in the code below
            if (t_reentrancy > 0)
                return;

            t_reentrancy++;
            try
            {
                if (s_symbolsMethodInfo == null)
                {
                    s_symbolsType = Type.GetType(
                        "System.Diagnostics.StackTraceSymbols, System.Diagnostics.StackTrace, Version=1.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a",
                        throwOnError: false);

                    if (s_symbolsType == null)
                        return;

                    s_symbolsMethodInfo = s_symbolsType.GetMethod("GetSourceLineInfo");
                    if (s_symbolsMethodInfo == null)
                        return;
                }

                if (getSourceLineInfo == null)
                {
                    // Create an instance of System.Diagnostics.Stacktrace.Symbols
                    object target = Activator.CreateInstance(s_symbolsType);

                    // Create an instance delegate for the GetSourceLineInfo method
                    getSourceLineInfo = (GetSourceLineInfoDelegate)s_symbolsMethodInfo.CreateDelegate(typeof(GetSourceLineInfoDelegate), target);
                }

                for (int index = 0; index < iFrameCount; index++)
                {
                    // If there was some reason not to try get get the symbols from the portable PDB reader like the module was
                    // ENC or the source/line info was already retrieved, the method token is 0.
                    if (rgiMethodToken[index] != 0)
                    {
                        getSourceLineInfo(rgAssemblyPath[index], rgLoadedPeAddress[index], rgiLoadedPeSize[index],
                            rgInMemoryPdbAddress[index], rgiInMemoryPdbSize[index], rgiMethodToken[index],
                            rgiILOffset[index], out rgFilename[index], out rgiLineNumber[index], out rgiColumnNumber[index]);
                    }
                }
            }
            catch
            {
            }
            finally
            {
                t_reentrancy--;
            }
        }
Пример #6
0
        //
        // Initializes the stack trace helper. If fNeedFileInfo is true, initializes rgFilename,
        // rgiLineNumber and rgiColumnNumber fields using the portable PDB reader if not already
        // done by GetStackFramesInternal (on Windows for old PDB format).
        //
        internal void InitializeSourceInfo(int iSkip, bool fNeedFileInfo, Exception exception)
        {
            StackTrace.GetStackFramesInternal(this, iSkip, fNeedFileInfo, exception);

            if (!fNeedFileInfo)
            {
                return;
            }

            // Check if this function is being reentered because of an exception in the code below
            if (t_reentrancy > 0)
            {
                return;
            }

            t_reentrancy++;
            try
            {
                if (s_getSourceLineInfo == null)
                {
                    Type symbolsType = Type.GetType(
                        "System.Diagnostics.StackTraceSymbols, System.Diagnostics.StackTrace, Version=4.0.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a",
                        throwOnError: false);

                    if (symbolsType == null)
                    {
                        return;
                    }

                    MethodInfo symbolsMethodInfo = symbolsType.GetMethod("GetSourceLineInfo", BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance);
                    if (symbolsMethodInfo == null)
                    {
                        return;
                    }

                    // Create an instance of System.Diagnostics.Stacktrace.Symbols
                    object target = Activator.CreateInstance(symbolsType);

                    // Create an instance delegate for the GetSourceLineInfo method
                    GetSourceLineInfoDelegate getSourceLineInfo = (GetSourceLineInfoDelegate)symbolsMethodInfo.CreateDelegate(typeof(GetSourceLineInfoDelegate), target);

                    // We could race with another thread. It doesn't matter if we win or lose, the losing instance will be GC'ed and all threads including this one will
                    // use the winning instance
                    Interlocked.CompareExchange(ref s_getSourceLineInfo, getSourceLineInfo, null);
                }

                for (int index = 0; index < iFrameCount; index++)
                {
                    // If there was some reason not to try get the symbols from the portable PDB reader like the module was
                    // ENC or the source/line info was already retrieved, the method token is 0.
                    if (rgiMethodToken[index] != 0)
                    {
                        s_getSourceLineInfo(rgAssemblyPath[index], rgLoadedPeAddress[index], rgiLoadedPeSize[index],
                                            rgInMemoryPdbAddress[index], rgiInMemoryPdbSize[index], rgiMethodToken[index],
                                            rgiILOffset[index], out rgFilename[index], out rgiLineNumber[index], out rgiColumnNumber[index]);
                    }
                }
            }
            catch
            {
            }
            finally
            {
                t_reentrancy--;
            }
        }
Пример #7
0
        internal void InitializeSourceInfo(int iSkip, bool fNeedFileInfo, Exception exception)
        {
            StackTrace.GetStackFramesInternal(this, iSkip, fNeedFileInfo, exception);
            if (!fNeedFileInfo)
            {
                return;
            }

            // For back compat we opt-out of using Portable PDBs before 4.7.2. See the comments in
            // RuntimeFeature for more details.
            //
            // Even if our compat policy for enabling the feature changes, make sure that
            // RuntimeFeature.IsSupported accurately encapsulates that policy. Our API contract with
            // tools is that we will accurately tell them whether or not Portable PDB is supported.
            if (!RuntimeFeature.IsSupported(RuntimeFeature.PortablePdb))
            {
                return;
            }

            // Check if this function is being reentered because of an exception in the code below
            if (t_reentrancy > 0)
            {
                return;
            }

            t_reentrancy++;
            try
            {
                // need private reflection below + unmanaged code for the portable PDB access itself
                // PERF: these demands are somewhat expensive so do the quick check first. We are aiming for
                // ~50k traces/s at 5 frames/trace on decent 2017 era hardware to maintain rough performance
                // parity with 4.7 implementation that didn't have Portable PDB support
                if (!CodeAccessSecurityEngine.QuickCheckForAllDemands())
                {
                    new ReflectionPermission(ReflectionPermissionFlag.MemberAccess).Assert();
                    new SecurityPermission(SecurityPermissionFlag.UnmanagedCode).Assert();
                }

                if (s_getSourceLineInfo == null)
                {
                    Type symbolsType = Type.GetType(
                        "System.Diagnostics.StackTraceSymbols, System.Core, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089",
                        throwOnError: false);

                    if (symbolsType == null)
                    {
                        return;
                    }

                    MethodInfo symbolsMethodInfo = symbolsType.GetMethod("GetSourceLineInfoWithoutCasAssert",
                                                                         new Type[] { typeof(string),
                                                                                      typeof(IntPtr),
                                                                                      typeof(int),
                                                                                      typeof(IntPtr),
                                                                                      typeof(int),
                                                                                      typeof(int),
                                                                                      typeof(int),
                                                                                      typeof(string).MakeByRefType(),
                                                                                      typeof(int).MakeByRefType(),
                                                                                      typeof(int).MakeByRefType() });

                    // We can't take a servicing dependency that System.Core.dll has been upgraded. If for whatever
                    // wacky reason we still have the old version of System.Core.dll fallback to the original less
                    // performant implementation of the method.
                    if (symbolsMethodInfo == null)
                    {
                        symbolsMethodInfo = symbolsType.GetMethod("GetSourceLineInfo",
                                                                  new Type[] { typeof(string),
                                                                               typeof(IntPtr),
                                                                               typeof(int),
                                                                               typeof(IntPtr),
                                                                               typeof(int),
                                                                               typeof(int),
                                                                               typeof(int),
                                                                               typeof(string).MakeByRefType(),
                                                                               typeof(int).MakeByRefType(),
                                                                               typeof(int).MakeByRefType() });
                    }

                    if (symbolsMethodInfo == null)
                    {
                        return;
                    }

                    // Create an instance of System.Diagnostics.Stacktrace.Symbols
                    object target = Activator.CreateInstance(symbolsType);

                    // Create an instance delegate for the GetSourceLineInfo method
                    GetSourceLineInfoDelegate getSourceLineInfo = (GetSourceLineInfoDelegate)symbolsMethodInfo.CreateDelegate(typeof(GetSourceLineInfoDelegate), target);

                    // We could ---- with another thread. It doesn't matter if we win or lose, the losing instance will be GC'ed and all threads including this one will
                    // use the winning instance
                    Interlocked.CompareExchange(ref s_getSourceLineInfo, getSourceLineInfo, null);
                }

                for (int index = 0; index < iFrameCount; index++)
                {
                    // If there was some reason not to try get get the symbols from the portable PDB reader like the module was
                    // ENC or the source/line info was already retrieved, the method token is 0.
                    if (rgiMethodToken[index] != 0)
                    {
                        s_getSourceLineInfo(rgAssemblyPath[index], rgLoadedPeAddress[index], rgiLoadedPeSize[index],
                                            rgInMemoryPdbAddress[index], rgiInMemoryPdbSize[index], rgiMethodToken[index],
                                            rgiILOffset[index], out rgFilename[index], out rgiLineNumber[index], out rgiColumnNumber[index]);
                    }
                }
            }
            catch
            {
            }
            finally
            {
                t_reentrancy--;
            }
        }