diff options
Diffstat (limited to 'src/inc')
-rw-r--r-- | src/inc/clrconfigvalues.h | 12 | ||||
-rw-r--r-- | src/inc/eventtracebase.h | 263 |
2 files changed, 252 insertions, 23 deletions
diff --git a/src/inc/clrconfigvalues.h b/src/inc/clrconfigvalues.h index 4343ef4942..a97e53d4f8 100644 --- a/src/inc/clrconfigvalues.h +++ b/src/inc/clrconfigvalues.h @@ -249,11 +249,6 @@ CONFIG_DWORD_INFO(INTERNAL_SuppressLockViolationsOnReentryFromOS, W("SuppressLoc #endif // WIN64EXCEPTIONS /// -/// Diagnostics (unsuported general-purpose) -/// -RETAIL_CONFIG_DWORD_INFO(UNSUPORTED_LTTng, W("LTTng"), 1, "If COMPlus_LTTng is set to 0, this will prevent the LTTng library from being loaded at runtime") - -/// /// Exception Handling /// CONFIG_DWORD_INFO_DIRECT_ACCESS(INTERNAL_AssertOnFailFast, W("AssertOnFailFast"), "") @@ -726,6 +721,13 @@ RETAIL_CONFIG_DWORD_INFO(INTERNAL_EventPipeRundown, W("EventPipeRundown"), 1, "E RETAIL_CONFIG_DWORD_INFO(INTERNAL_EventPipeCircularMB, W("EventPipeCircularMB"), 1024, "The EventPipe circular buffer size in megabytes.") RETAIL_CONFIG_DWORD_INFO(INTERNAL_EventPipeProcNumbers, W("EventPipeProcNumbers"), 0, "Enable/disable capturing processor numbers in EventPipe event headers") +// +// LTTng +// +RETAIL_CONFIG_STRING_INFO(INTERNAL_LTTngConfig, W("LTTngConfig"), "Configuration for LTTng.") +RETAIL_CONFIG_DWORD_INFO(UNSUPORTED_LTTng, W("LTTng"), 1, "If COMPlus_LTTng is set to 0, this will prevent the LTTng library from being loaded at runtime") + + #ifdef FEATURE_GDBJIT /// /// GDBJIT diff --git a/src/inc/eventtracebase.h b/src/inc/eventtracebase.h index bda2262bc7..09c82fcb7b 100644 --- a/src/inc/eventtracebase.h +++ b/src/inc/eventtracebase.h @@ -103,12 +103,12 @@ enum EtwThreadFlags #define ETW_TRACING_INITIALIZED(RegHandle) (TRUE) #define ETW_EVENT_ENABLED(Context, EventDescriptor) (EventPipeHelper::IsEnabled(Context, EventDescriptor.Level, EventDescriptor.Keyword) || \ - (XplatEventLogger::IsEventLoggingEnabled())) + (XplatEventLogger::IsKeywordEnabled(Context, EventDescriptor.Level, EventDescriptor.Keyword))) #define ETW_CATEGORY_ENABLED(Context, Level, Keyword) (EventPipeHelper::IsEnabled(Context, Level, Keyword) || \ - (XplatEventLogger::IsEventLoggingEnabled()) + (XplatEventLogger::IsKeywordEnabled(Context, Level, Keyword))) #define ETW_TRACING_ENABLED(Context, EventDescriptor) (EventEnabled##EventDescriptor()) #define ETW_TRACING_CATEGORY_ENABLED(Context, Level, Keyword) (EventPipeHelper::IsEnabled(Context, Level, Keyword) || \ - (XplatEventLogger::IsEventLoggingEnabled())) + (XplatEventLogger::IsKeywordEnabled(Context, Level, Keyword))) #define ETW_PROVIDER_ENABLED(ProviderSymbol) (TRUE) #else //defined(FEATURE_PERFTRACING) #define ETW_INLINE @@ -116,11 +116,11 @@ enum EtwThreadFlags #define ETWFireEvent(EventName) #define ETW_TRACING_INITIALIZED(RegHandle) (TRUE) -#define ETW_CATEGORY_ENABLED(Context, Level, Keyword) (XplatEventLogger::IsEventLoggingEnabled()) -#define ETW_EVENT_ENABLED(Context, EventDescriptor) (XplatEventLogger::IsEventLoggingEnabled()) -#define ETW_TRACING_ENABLED(Context, EventDescriptor) (EventEnabled##EventDescriptor()) -#define ETW_TRACING_CATEGORY_ENABLED(Context, Level, Keyword) (XplatEventLogger::IsEventLoggingEnabled()) -#define ETW_PROVIDER_ENABLED(ProviderSymbol) (TRUE) +#define ETW_CATEGORY_ENABLED(Context, Level, Keyword) (XplatEventLogger::IsKeywordEnabled(Context, Level, Keyword)) +#define ETW_EVENT_ENABLED(Context, EventDescriptor) (XplatEventLogger::IsKeywordEnabled(Context, EventDescriptor.Level, EventDescriptor.KeywordsBitmask)) +#define ETW_TRACING_ENABLED(Context, EventDescriptor) (ETW_EVENT_ENABLED(Context, EventDescriptor) && EventEnabled##EventDescriptor()) +#define ETW_TRACING_CATEGORY_ENABLED(Context, Level, Keyword) (ETW_CATEGORY_ENABLED(Context, Level, Keyword)) +#define ETW_PROVIDER_ENABLED(ProviderSymbol) (XplatEventLogger::IsProviderEnabled(Context)) #endif // defined(FEATURE_PERFTRACING) #endif // !defined(FEATURE_PAL) @@ -237,23 +237,250 @@ extern UINT32 g_nClrInstanceId; #define DEF_LTTNG_KEYWORD_ENABLED 1 #include "clrproviders.h" #include "clrconfig.h" -#endif // defined(FEATURE_PAL) && (defined(FEATURE_EVENT_TRACE) || defined(FEATURE_EVENTSOURCE_XPLAT)) +class XplatEventLoggerConfiguration +{ +public: + XplatEventLoggerConfiguration() = default; -#if defined(FEATURE_EVENT_TRACE) || defined(FEATURE_EVENTSOURCE_XPLAT) + XplatEventLoggerConfiguration(XplatEventLoggerConfiguration const & other) = delete; + XplatEventLoggerConfiguration(XplatEventLoggerConfiguration && other) + { + _provider = std::move(other._provider); + _isValid = other._isValid; + _enabledKeywords = other._enabledKeywords; + _level = other._level; + } -#include "clrconfig.h" - class XplatEventLogger -{ + ~XplatEventLoggerConfiguration() + { + _provider = nullptr; + } + + void Initialize(LPWSTR configString) + { + Parse(configString); + } + + bool IsValid() const + { + return _isValid; + } + + LPCWSTR GetProviderName() const + { + return _provider; + } + + ULONGLONG GetEnabledKeywordsMask() const + { + return _enabledKeywords; + } + + UINT GetLevel() const + { + return _level; + } + +private: + struct ComponentSpan + { public: - inline static BOOL IsEventLoggingEnabled() + ComponentSpan(LPCWSTR start, LPCWSTR end) + : Start(start), End(end) + { + } + + LPCWSTR Start; + LPCWSTR End; + }; + + void Parse(LPWSTR configString) + { + if (configString == nullptr || *configString == L'\0') + { + _provider = W("*"); + _enabledKeywords = (ULONGLONG)(-1); + _level = TRACE_LEVEL_VERBOSE; + return; + } + + auto providerComponent = GetNextComponentString(configString); + _provider = ParseProviderName(providerComponent); + if (_provider == nullptr) + { + _isValid = false; + return; + } + + auto keywordsComponent = GetNextComponentString(providerComponent.End + 1); + _enabledKeywords = ParseEnabledKeywordsMask(keywordsComponent); + + auto levelComponent = GetNextComponentString(keywordsComponent.End + 1); + _level = ParseEnabledKeywordsMask(levelComponent); + _isValid = true; + } + + ComponentSpan GetNextComponentString(LPCWSTR start) const + { + static WCHAR ComponentDelimiter = W(':'); + + auto end = wcschr(start, ComponentDelimiter); + if (end == nullptr) + { + end = start + wcslen(start); + } + + return ComponentSpan(start, end); + } + + LPCWSTR ParseProviderName(ComponentSpan const & component) const + { + auto providerName = (WCHAR*)nullptr; + if ((component.End - component.Start) != 0) + { + auto const length = component.End - component.Start; + providerName = new WCHAR[length + 1]; + memset(providerName, '\0', (length + 1) * sizeof(WCHAR)); + wcsncpy(providerName, component.Start, length); + } + return providerName; + } + + ULONGLONG ParseEnabledKeywordsMask(ComponentSpan const & component) const + { + auto enabledKeywordsMask = (ULONGLONG)(-1); + if ((component.End - component.Start) != 0) + { + enabledKeywordsMask = _wcstoui64(component.Start, nullptr, 16); + } + return enabledKeywordsMask; + } + + UINT ParseLevel(ComponentSpan const & component) const + { + auto level = TRACE_LEVEL_VERBOSE; + if ((component.End - component.Start) != 0) + { + level = _wtoi(component.Start); + } + return level; + } + + LPCWSTR _provider; + ULONGLONG _enabledKeywords; + UINT _level; + bool _isValid; +}; + +class XplatEventLoggerController +{ +public: + + static void Initialize(XplatEventLoggerConfiguration const &config) + { + if (!config.IsValid()) + { + return; + } + + auto providerName = config.GetProviderName(); + auto enabledKeywordsMask = config.GetEnabledKeywordsMask(); + auto level = config.GetLevel(); + if (_wcsicmp(providerName, W("*")) == 0 && enabledKeywordsMask == (ULONGLONG)(-1) && level == TRACE_LEVEL_VERBOSE) + { + ActivateAllKeywordsOfAllProviders(); + } + else + { + auto provider = GetProvider(providerName); + if (provider == nullptr) + { + return; + } + provider->EnabledKeywordsBitmask = enabledKeywordsMask; + provider->Level = level; + provider->IsEnabled = true; + } + } + +private: + + static LTTNG_TRACE_CONTEXT * const GetProvider(LPCWSTR providerName) + { + auto length = wcslen(providerName); + for (auto provider : ALL_LTTNG_PROVIDERS_CONTEXT) + { + if (_wcsicmp(provider->Name, providerName) == 0) + { + return provider; + } + } + return nullptr; + } + + static void ActivateAllKeywordsOfAllProviders() + { + for (LTTNG_TRACE_CONTEXT * const provider : ALL_LTTNG_PROVIDERS_CONTEXT) + { + provider->EnabledKeywordsBitmask = (ULONGLONG)(-1); + provider->Level = TRACE_LEVEL_VERBOSE; + provider->IsEnabled = true; + } + } +}; + +class XplatEventLogger +{ +public: + + inline static BOOL IsEventLoggingEnabled() + { + static ConfigDWORD configEventLogging; + return configEventLogging.val(CLRConfig::EXTERNAL_EnableEventLog); + } + + inline static bool IsProviderEnabled(DOTNET_TRACE_CONTEXT providerCtx) + { + return providerCtx.LttngProvider->IsEnabled; + } + + inline static bool IsKeywordEnabled(DOTNET_TRACE_CONTEXT providerCtx, UCHAR level, ULONGLONG keyword) + { + if (!providerCtx.LttngProvider->IsEnabled) { - static ConfigDWORD configEventLogging; - return configEventLogging.val(CLRConfig::EXTERNAL_EnableEventLog); + return false; } + + if ((level <= providerCtx.LttngProvider->Level) || (providerCtx.LttngProvider->Level == 0)) + { + if ((keyword == 0) || ((keyword & providerCtx.LttngProvider->EnabledKeywordsBitmask) != 0)) + { + return true; + } + } + return false; + } + + static void InitializeLogger() + { + if (!IsEventLoggingEnabled()) + { + return; + } + + LPWSTR xplatEventConfig = NULL; + CLRConfig::GetConfigValue(CLRConfig::INTERNAL_LTTngConfig, &xplatEventConfig); + + auto configuration = XplatEventLoggerConfiguration(); + configuration.Initialize(xplatEventConfig); + + XplatEventLoggerController::Initialize(configuration); + } }; -#endif //defined(FEATURE_EVENT_TRACE) + +#endif // defined(FEATURE_PAL) && (defined(FEATURE_EVENT_TRACE) || defined(FEATURE_EVENTSOURCE_XPLAT)) #if defined(FEATURE_EVENT_TRACE) @@ -346,8 +573,8 @@ extern "C" { #endif //!DONOT_DEFINE_ETW_CALLBACK && !DACCESS_COMPILE #endif //!FEATURE_PAL - #include "clretwallmain.h" + #if defined(FEATURE_PERFTRACING) class EventPipeHelper { |