public void Dispose() { lock (_singletonAccessLock) { _profiledThreadInfoProvider.Dispose(); _profiledAppDomainProvider.Dispose(); UnregisterReversePInvokeCallbacks(); if (GenerateProfilesInManagedCode()) { _resolveAndExportStacksBackgroundLoop.Dispose(); } _pprofBuilder.Dispose(); StackSnapshotsBufferSegmentCollection completedStackSnapshots = GetCompletedStackSnapshots(); if (completedStackSnapshots != null) { _completedStackSnapshots = null; completedStackSnapshots.Dispose(); } if (_currentEngine == this) { _currentEngine = null; } } }
public static bool TryCreateAndStart(out ProfilerEngine runningProfilerEngine) { IProductConfiguration config = ProductConfigurationProvider.CreateDefault() // .ApplyReleaseDefaults() // .ApplyDevDefaults() .ApplyReleaseOrDevDefaults() .ApplyEnvironmentVariables() .CreateImmutableSnapshot(); return(TryCreateAndStart(config, out runningProfilerEngine)); }
private static void LogInitializationCompleted(ProfilerEngine initializedEngine) { try { AppDomain currentAppDomain = AppDomain.CurrentDomain; Thread currentThread = Thread.CurrentThread; #pragma warning disable CS0618 // GetCurrentThreadId is obsolete but we can still use it for logging purposes (see respective docs) int osThreadId = AppDomain.GetCurrentThreadId(); #pragma warning restore CS0618 // Type or member is obsolete Log.Info( Log.WithCallInfo(LogSourceMoniker), $"Initialization completed. {nameof(ProfilerEngine)} is running.", #pragma warning disable SA1117 // easier to have the mapping key/value on the same line $"{nameof(ProfilerEngine)}.Type", typeof(ProfilerEngine).FullName, $"{nameof(ProfilerEngine)}.{nameof(ProfilerEngineVersionInfo.BuildConfigurationMoniker)}", initializedEngine.VersionInfo.BuildConfigurationMoniker, $"{nameof(ProfilerEngine)}.{nameof(ProfilerEngineVersionInfo.FileVersion)}", initializedEngine.VersionInfo.FileVersion, $"{nameof(ProfilerEngine)}.{nameof(ProfilerEngineVersionInfo.InformationalVersion)}", initializedEngine.VersionInfo.InformationalVersion, $"{nameof(ProfilerEngine)}.{nameof(ProfilerEngineVersionInfo.AssemblyName)}", initializedEngine.VersionInfo.AssemblyName, $"{nameof(RuntimeEnvironmentInfo)}.{nameof(RuntimeEnvironmentInfo.RuntimeName)}", RuntimeEnvironmentInfo.SingeltonInstance.RuntimeName, $"{nameof(RuntimeEnvironmentInfo)}.{nameof(RuntimeEnvironmentInfo.RuntimeVersion)}", RuntimeEnvironmentInfo.SingeltonInstance.RuntimeVersion, $"{nameof(RuntimeEnvironmentInfo)}.{nameof(RuntimeEnvironmentInfo.ProcessArchitecture)}", RuntimeEnvironmentInfo.SingeltonInstance.ProcessArchitecture, $"{nameof(RuntimeEnvironmentInfo)}.{nameof(RuntimeEnvironmentInfo.OsPlatform)}", RuntimeEnvironmentInfo.SingeltonInstance.OsPlatform, $"{nameof(RuntimeEnvironmentInfo)}.{nameof(RuntimeEnvironmentInfo.OsArchitecture)}", RuntimeEnvironmentInfo.SingeltonInstance.OsArchitecture, $"{nameof(RuntimeEnvironmentInfo)}.{nameof(RuntimeEnvironmentInfo.OsDescription)}", RuntimeEnvironmentInfo.SingeltonInstance.OsDescription, $"{nameof(RuntimeEnvironmentInfo)}.{nameof(RuntimeEnvironmentInfo.CoreAssembyInfo.IsMscorlib)}", RuntimeEnvironmentInfo.SingeltonInstance.CoreAssembyInfo.IsMscorlib, $"{nameof(RuntimeEnvironmentInfo)}.{nameof(RuntimeEnvironmentInfo.CoreAssembyInfo.IsSysPrivCoreLib)}", RuntimeEnvironmentInfo.SingeltonInstance.CoreAssembyInfo.IsSysPrivCoreLib, $"{nameof(RuntimeEnvironmentInfo)}.{nameof(RuntimeEnvironmentInfo.CoreAssembyInfo.Name)}", RuntimeEnvironmentInfo.SingeltonInstance.CoreAssembyInfo.Name, $"{nameof(currentThread)}.{nameof(Thread.Name)}", currentThread?.Name, $"{nameof(currentThread)}.{nameof(Thread.ManagedThreadId)}", currentThread?.ManagedThreadId, $"{nameof(currentThread)}.<{nameof(osThreadId)}>", osThreadId, $"{nameof(currentThread)}.{nameof(Thread.IsThreadPoolThread)}", currentThread?.IsThreadPoolThread, $"{nameof(currentThread)}.{nameof(Thread.IsBackground)}", currentThread?.IsBackground, $"{nameof(currentAppDomain)}.{nameof(AppDomain.Id)}", currentAppDomain?.Id, $"{nameof(currentAppDomain)}.{nameof(AppDomain.FriendlyName)}", currentAppDomain?.FriendlyName, $"{nameof(currentAppDomain)}.{nameof(AppDomain.IsDefaultAppDomain)}", currentAppDomain?.IsDefaultAppDomain(), $"{nameof(currentAppDomain)}.{nameof(AppDomain.BaseDirectory)}", currentAppDomain?.BaseDirectory, $"{nameof(currentAppDomain)}.{nameof(AppDomain.DynamicDirectory)}", currentAppDomain?.DynamicDirectory, $"{nameof(currentAppDomain)}.{nameof(AppDomain.IsFullyTrusted)}", currentAppDomain?.IsFullyTrusted, $"{nameof(currentAppDomain)}.{nameof(AppDomain.IsHomogenous)}", currentAppDomain?.IsHomogenous, $"{nameof(currentAppDomain)}.{nameof(AppDomain.RelativeSearchPath)}", currentAppDomain?.RelativeSearchPath, $"{nameof(currentAppDomain)}.{nameof(AppDomain.ShadowCopyFiles)}", currentAppDomain?.ShadowCopyFiles); #pragma warning restore SA1117 // Parameters should be on same line or separate lines } catch (Exception ex) { // This probably never happens in practice. If it ever actually occurs, need to investigate and restructure the Log accordingly. Log.Error( Log.WithCallInfo(LogSourceMoniker), $"Initialization completed. {nameof(ProfilerEngine)} is running. However, an error occurred while trying to log that very fact.", ex); } }
/// <summary> /// Called internally AFTER <c>s_singletonAccessLock</c> has been taken and it was validated that no other engine is running. /// </summary> private static void CreateAndStart(IProductConfiguration config, out ProfilerEngine newProfilerEngine) { LogConfigurator.SetupLogger(config); Log.Info(Log.WithCallInfo(LogSourceMoniker), "Initializing. Will create and start the managed profiler engine."); try { ThreadUtil.EnsureSetCurrentManagedThreadNameNativeCallbackInitialized(); _currentEngine = new ProfilerEngine(config); newProfilerEngine = _currentEngine; LogInitializationCompleted(newProfilerEngine); } catch (Exception ex) { Log.Error(Log.WithCallInfo(LogSourceMoniker), "Initialization error.", ex); newProfilerEngine = null; } }
public static bool TryCreateAndStart(IProductConfiguration config, out ProfilerEngine runningProfilerEngine) { Validate.NotNull(config, nameof(config)); runningProfilerEngine = _currentEngine; if (runningProfilerEngine != null) { return(false); } lock (_singletonAccessLock) { runningProfilerEngine = _currentEngine; if (runningProfilerEngine != null) { return(false); } CreateAndStart(config, out runningProfilerEngine); return(runningProfilerEngine != null); } }