Skip to content

Commit

Permalink
Fix LTTng filtering for runtime providers (dotnet/coreclr#25374)
Browse files Browse the repository at this point in the history
* LTTng filtering

* Fix Windows build, make IsInitialized check faster

* Cleanup/change default to no keywords/level set

* Keep the default to be the current policy - enable everything

* more cleanup

* No need to check for initialization

* Fix Windows build


Commit migrated from dotnet/coreclr@68f6fd0
  • Loading branch information
sywhang authored Jun 26, 2019
1 parent 95d11fc commit d36cad0
Show file tree
Hide file tree
Showing 4 changed files with 306 additions and 37 deletions.
12 changes: 7 additions & 5 deletions src/coreclr/src/inc/clrconfigvalues.h
Original file line number Diff line number Diff line change
Expand Up @@ -248,11 +248,6 @@ CONFIG_DWORD_INFO_DIRECT_ACCESS(INTERNAL_SuppressChecks, W("SuppressChecks"), ""
CONFIG_DWORD_INFO(INTERNAL_SuppressLockViolationsOnReentryFromOS, W("SuppressLockViolationsOnReentryFromOS"), 0, "64 bit OOM tests re-enter the CLR via RtlVirtualUnwind. This indicates whether to suppress resulting locking violations.")
#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
///
Expand Down Expand Up @@ -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
Expand Down
263 changes: 245 additions & 18 deletions src/coreclr/src/inc/eventtracebase.h
Original file line number Diff line number Diff line change
Expand Up @@ -103,24 +103,24 @@ 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
#define ETWOnStartup(StartEventName, EndEventName)
#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)

Expand Down Expand Up @@ -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)

Expand Down Expand Up @@ -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
{
Expand Down
Loading

0 comments on commit d36cad0

Please sign in to comment.