private bool ReleaseNativeSegmentObject()
        {
            IntPtr nativeSegmentObjectPtr = Interlocked.Exchange(ref _nativeSegmentObjectPtr, IntPtr.Zero);

            if (nativeSegmentObjectPtr == IntPtr.Zero)
            {
                return(true);
            }

            try
            {
                bool isReleased = NativeInterop.TryMakeSegmentAvailableForWrite(nativeSegmentObjectPtr);
                if (!isReleased)
                {
                    _nativeSegmentObjectPtr = nativeSegmentObjectPtr;
                }

                return(isReleased);
            }
            catch (ClrShutdownException ex)
            {
                Log.Info(nameof(StackSnapshotsBufferSegment), ex.Message);
                _nativeSegmentObjectPtr = nativeSegmentObjectPtr;
                return(false);
            }
            catch (Exception ex)
            {
                Log.Error(nameof(StackSnapshotsBufferSegment), ex);
                _nativeSegmentObjectPtr = nativeSegmentObjectPtr;
                return(false);
            }
        }
        private bool TryGetAppDomainFromNativeCore(
            ulong profilerAppDomainId,
            int appDomainNameBuffSize,
            out uint actualAppDomainNameLen,
            out StringBuilder appDomainNameBuff,
            out ulong appDomainProcessId)
        {
            actualAppDomainNameLen = 0;
            appDomainNameBuff      = new StringBuilder(capacity: appDomainNameBuffSize + 1);
            appDomainProcessId     = 0;

            bool success = false;

            try
            {
                success = NativeInterop.ResolveAppDomainInfoSymbols(
                    profilerAppDomainId,
                    (uint)appDomainNameBuffSize,
                    ref actualAppDomainNameLen,
                    appDomainNameBuff,
                    ref appDomainProcessId);
            }
            catch (ClrShutdownException)
            {
                // this is expected when managed code runs AFTER the CLR shutdown
                throw;
            }
            catch (Exception ex)
            {
                Log.Error(Log.WithCallInfo(this.GetType().Name), ex);
            }

            return(success);
        }
예제 #3
0
        private void MainLoop()
        {
            int osThreadId;

            try
            {
#pragma warning disable CS0618 // GetCurrentThreadId is obsolete but we can still use it for logging purposes (see respective docs)
                // BUG: this is not an OS id: need to P/Invoke GetCurrentThreadId() on Windows
                osThreadId = AppDomain.GetCurrentThreadId();
#pragma warning restore CS0618 // Type or member is obsolete

                NativeInterop.ThreadsCpuManager_Map(osThreadId, _logComponentMoniker);
            }
            catch
            {
                osThreadId = -1;
            }

            Log.Info(
                _logComponentMoniker,
                $"Entering main loop ({_loopThread.Name} - #{_loopThread.ManagedThreadId} / {osThreadId}) at priority {_loopThread.Priority}");

            DateTimeOffset periodStart = DateTimeOffset.Now;
            while (Volatile.Read(ref _loopState) == State.Running)
            {
                try
                {
                    periodStart = DateTimeOffset.Now;
                    PerformIterationWork();
                    WaitForNextIteration(periodStart);
                }
                catch (Exception ex)
                {
                    Log.Error(_logComponentMoniker, ex, $"thread name", _loopThread.Name);
                }
            }

            Interlocked.CompareExchange(ref _loopState, State.ShutDown, State.ShutdownRequested);
        }
        private bool TryGetThreadInfoFromNativeCore(
            uint profilerThreadInfoId,
            int threadNameBuffSize,
            out ulong clrThreadId,
            out uint osThreadId,
            out IntPtr osThreadHandle,
            out StringBuilder threadNameBuff,
            out uint actualThreadNameLen)
        {
            clrThreadId         = 0;
            osThreadId          = 0;
            osThreadHandle      = IntPtr.Zero;
            threadNameBuff      = new StringBuilder(capacity: threadNameBuffSize + 1);
            actualThreadNameLen = 0;

            try
            {
                return(NativeInterop.GetThreadInfo(
                           profilerThreadInfoId,
                           ref clrThreadId,
                           ref osThreadId,
                           ref osThreadHandle,
                           threadNameBuff,
                           (uint)threadNameBuffSize,
                           ref actualThreadNameLen));
            }
            catch (ClrShutdownException)
            {
                // this is expected when managed code runs AFTER the CLR shutdown
                throw;
            }
            catch (Exception ex)
            {
                Log.Error(Log.WithCallInfo(this.GetType().Name), ex);
                return(false);
            }
        }