Skip to content

Commit ce67cef

Browse files
authored
[Linux][EventPipe][UserEvents] Add user events eventpipe support (#115265)
* [DiagnosticServer] Refactor and Cleanup Visual reorder of Diagnostics enum structs Fix a couple naming typos Spaces to tabs consistency * [EventPipe] Add User_events structs * [EventPipe] Add User_events eventpipe session * [DiagnosticServer] Revamp Provider Config deserialization To support the new user_events-based eventpipe session, add a more modular and flexible EventPipeProviderConfiguration deserializer. * [DiagnosticServer] Deprecate old deserializer * [DiagnosticServer] Add CollectTracing5 command parser * [DiagnosticServer] Deserialize file_descriptor from IPC Stream The user_events_data file is required to register user_events tracepoints. Require profilers to pass over the corresponding file descriptor with SCM_RIGHTS in order to initialize the user_events EventPipe session. * [EventPipe] Use Event_filter to set EventPipeEvent enabled mask * [UserEvents] Register and unregister tracepoints * [UserEvents] Write events to tracepoints * Fixup CI build failures * Cleanup missed CI build failures * Address feedback Fix parameter order Use umap_ptr_uint32 macros for EventFilter Remove tracepoint_name const qualifier Prevent buffer overflow in tracepoint_format copying Skip duplicate tracepoint config fini Null out tracepoint after transferring ownership Use dn_vector_ptr_t for provider configurations Wrap entire functions under macro checks Use int for file descriptor Fix formatting Add checks for ep_session_disable session specific logic Use dn_vector_ptr for the tracepoints sets Use switch case for event writing Scope tracepoint registration to sessions Remove ep prefix from static functions Move includes to source Define max tracepoint format length * Address Feedback const EventPipeProviderConfiguration Adhere to the standard where EventPipeProviderConfiguration is read-only. Create event filter and tracepoint config duplication helpers to give the SessionProvider its own copy. * Address feedback Add string deserializer helper * Revert provider_configs to vector of structs * Dynamically allocate tracepoint format * Fix CI Build failures * Split ProviderConfiguration structs * Reuse EventPipeSessionTypes * Constrain tracepoint_config modification to session provider * Fixup compilation error * Move metadata into extensions portion * Free default tracepoint format * Address feedback Use ep_provider_config_fini helper Add session_type deserializing helper Fix tabbing Add dn_umap_uint32_ptr macro Handle tracepoint registration failure Change ep_session_write_event order Use dn_list foreach Add size check to extension activity ids construction Add ep_rt_utf8_string_printf_alloc helper * Address feedback Refactor tracepoint writing logic Use local constants Rename provider config parser * Consistently use addresses of struct fields * Fix typo * Address feedback Make struct data ownership consistent by removing const Make external source files use getters and internal source files directly access data. Add session_provider_tracepoint_free Disallow null tracepoint_name in tracepoint_format_alloc Remove redundant checks Cleanup ep_rt_utf8_string_printf_alloc Cleanup writing to tracepoint * Address feedback Update ep_provider_config_init/fini callsites Make resource cleanup logic consistent Account for early exit memory leaks Various cleanup * Address Feedback Fix eventpipe_collect_tracing_command_free_tracepoint_sets logic Clarify len variable names Consistently use -1 as invalid file descriptor Update event_pipe to use ep_rt_utf16_to_utf8_string/free * Fix Sign mismatch build error
1 parent f4bc468 commit ce67cef

35 files changed

+1874
-221
lines changed

src/coreclr/nativeaot/Runtime/eventpipeinternal.cpp

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -67,12 +67,16 @@ EXTERN_C uint64_t QCALLTYPE EventPipeInternal_Enable(
6767

6868
if (configProviders) {
6969
for (uint32_t i = 0; i < numProviders; ++i) {
70+
ep_char8_t *providerName = ep_rt_utf16_to_utf8_string (reinterpret_cast<const ep_char16_t *>(nativeProviders[i].pProviderName));
71+
ep_char8_t *filterData = ep_rt_utf16_to_utf8_string (reinterpret_cast<const ep_char16_t *>(nativeProviders[i].pFilterData));
7072
ep_provider_config_init (
7173
&configProviders[i],
72-
ep_rt_utf16_to_utf8_string (reinterpret_cast<const ep_char16_t *>(nativeProviders[i].pProviderName)),
74+
providerName,
7375
nativeProviders[i].keywords,
7476
static_cast<EventPipeEventLevel>(nativeProviders[i].loggingLevel),
75-
ep_rt_utf16_to_utf8_string (reinterpret_cast<const ep_char16_t *>(nativeProviders[i].pFilterData)));
77+
filterData);
78+
ep_rt_utf8_string_free (providerName);
79+
ep_rt_utf8_string_free (filterData);
7680
}
7781
}
7882

@@ -95,10 +99,8 @@ EXTERN_C uint64_t QCALLTYPE EventPipeInternal_Enable(
9599
ep_start_streaming(result);
96100

97101
if (configProviders) {
98-
for (uint32_t i = 0; i < numProviders; ++i) {
99-
ep_rt_utf8_string_free ((ep_char8_t *)ep_provider_config_get_provider_name (&configProviders[i]));
100-
ep_rt_utf8_string_free ((ep_char8_t *)ep_provider_config_get_filter_data (&configProviders[i]));
101-
}
102+
for (uint32_t i = 0; i < numProviders; ++i)
103+
ep_provider_config_fini (&configProviders[i]);
102104
free(configProviders);
103105
}
104106

src/coreclr/vm/eventpipeadapter.h

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -40,12 +40,16 @@ class EventPipeProviderConfigurationAdapter final
4040
m_providerConfigsLen = providerConfigsLen;
4141
if (m_providerConfigs) {
4242
for (uint32_t i = 0; i < providerConfigsLen; ++i) {
43+
ep_char8_t *providerName = ep_rt_utf16_to_utf8_string (reinterpret_cast<const ep_char16_t *>(providerConfigs[i].providerName));
44+
ep_char8_t *filterData = ep_rt_utf16_to_utf8_string (reinterpret_cast<const ep_char16_t *>(providerConfigs[i].filterData));
4345
ep_provider_config_init (
4446
&m_providerConfigs[i],
45-
ep_rt_utf16_to_utf8_string (reinterpret_cast<const ep_char16_t *>(providerConfigs[i].providerName)),
47+
providerName,
4648
providerConfigs[i].keywords,
4749
static_cast<EventPipeEventLevel>(providerConfigs[i].loggingLevel),
48-
ep_rt_utf16_to_utf8_string (reinterpret_cast<const ep_char16_t *>(providerConfigs[i].filterData)));
50+
filterData);
51+
ep_rt_utf8_string_free (providerName);
52+
ep_rt_utf8_string_free (filterData);
4953
}
5054
}
5155
}
@@ -54,10 +58,8 @@ class EventPipeProviderConfigurationAdapter final
5458
{
5559
STATIC_CONTRACT_NOTHROW;
5660
if (m_providerConfigs) {
57-
for (uint32_t i = 0; i < m_providerConfigsLen; ++i) {
58-
ep_rt_utf8_string_free ((ep_char8_t *)ep_provider_config_get_provider_name (&m_providerConfigs[i]));
59-
ep_rt_utf8_string_free ((ep_char8_t *)ep_provider_config_get_filter_data (&m_providerConfigs[i]));
60-
}
61+
for (uint32_t i = 0; i < m_providerConfigsLen; ++i)
62+
ep_provider_config_fini(&m_providerConfigs[i]);
6163
delete [] m_providerConfigs;
6264
}
6365
}
@@ -385,7 +387,9 @@ class EventPipeAdapter final
385387
ep_provider_config_get_provider_name (&config[0]),
386388
ep_provider_config_get_keywords (&config[0]),
387389
(EventPipeEventLevel)ep_provider_config_get_logging_level (&config[0]),
388-
ep_provider_config_get_filter_data (&config[0]));
390+
ep_provider_config_get_filter_data (&config[0]),
391+
NULL,
392+
NULL);
389393
}
390394

391395
static HRESULT GetProviderName(const EventPipeProvider *provider, ULONG numNameChars, ULONG *numNameCharsOut, LPWSTR name)

src/mono/mono/component/event_pipe.c

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -151,19 +151,22 @@ event_pipe_enable (
151151
IpcStream *stream,
152152
EventPipeSessionSynchronousCallback sync_callback)
153153
{
154-
ERROR_DECL (error);
155154
EventPipeSessionID session_id = 0;
156155

157156
EventPipeProviderConfiguration *config_providers = g_new0 (EventPipeProviderConfiguration, providers_len);
158157

159158
if (config_providers) {
160159
for (guint32 i = 0; i < providers_len; ++i) {
160+
ep_char8_t *provider_name = ep_rt_utf16_to_utf8_string ((const ep_char16_t *)(providers[i].provider_name));
161+
ep_char8_t *filter_data = ep_rt_utf16_to_utf8_string ((const ep_char16_t *)(providers[i].filter_data));
161162
ep_provider_config_init (
162163
&config_providers[i],
163-
providers[i].provider_name ? mono_utf16_to_utf8 (providers[i].provider_name, g_utf16_len (providers[i].provider_name), error) : NULL,
164+
provider_name,
164165
providers [i].keywords,
165166
(EventPipeEventLevel)providers [i].logging_level,
166-
providers[i].filter_data ? mono_utf16_to_utf8 (providers[i].filter_data, g_utf16_len (providers[i].filter_data), error) : NULL);
167+
filter_data);
168+
ep_rt_utf8_string_free (provider_name);
169+
ep_rt_utf8_string_free (filter_data);
167170
}
168171
}
169172

@@ -180,11 +183,8 @@ event_pipe_enable (
180183
NULL);
181184

182185
if (config_providers) {
183-
for (guint32 i = 0; i < providers_len; ++i) {
186+
for (guint32 i = 0; i < providers_len; ++i)
184187
ep_provider_config_fini (&config_providers[i]);
185-
g_free ((ep_char8_t *)ep_provider_config_get_provider_name (&config_providers[i]));
186-
g_free ((ep_char8_t *)ep_provider_config_get_filter_data (&config_providers[i]));
187-
}
188188
}
189189

190190
return session_id;

src/mono/mono/eventpipe/test/ep-buffer-manager-tests.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,8 @@ buffer_manager_init (
103103
current_provider_config,
104104
1,
105105
NULL,
106-
NULL);
106+
NULL,
107+
0);
107108
EP_LOCK_EXIT (section1)
108109

109110
ep_raise_error_if_nok (*session != NULL);

src/mono/mono/eventpipe/test/ep-buffer-tests.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,8 @@ load_buffer_with_events_init (
9191
current_provider_config,
9292
1,
9393
NULL,
94-
NULL);
94+
NULL,
95+
0);
9596
EP_LOCK_EXIT (section1)
9697

9798
ep_raise_error_if_nok (*session != NULL);

src/mono/mono/eventpipe/test/ep-session-tests.c

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,8 @@ test_create_delete_session (void)
5151
current_provider_config,
5252
1,
5353
NULL,
54-
NULL);
54+
NULL,
55+
0);
5556
EP_LOCK_EXIT (section1)
5657

5758
ep_raise_error_if_nok (test_session != NULL);
@@ -93,7 +94,8 @@ test_add_session_providers (void)
9394
current_provider_config,
9495
1,
9596
NULL,
96-
NULL);
97+
NULL,
98+
0);
9799

98100
ep_raise_error_if_nok_holding_lock (test_session != NULL, section1);
99101

@@ -111,7 +113,7 @@ test_add_session_providers (void)
111113

112114
test_location = 3;
113115

114-
test_session_provider = ep_session_provider_alloc (TEST_PROVIDER_NAME, 1, EP_EVENT_LEVEL_LOGALWAYS, "");
116+
test_session_provider = ep_session_provider_alloc (TEST_PROVIDER_NAME, 1, EP_EVENT_LEVEL_LOGALWAYS, "", NULL, NULL);
115117
ep_raise_error_if_nok (test_session_provider != NULL);
116118

117119
test_location = 4;
@@ -176,7 +178,8 @@ test_session_special_get_set (void)
176178
current_provider_config,
177179
1,
178180
NULL,
179-
NULL);
181+
NULL,
182+
0);
180183
EP_LOCK_EXIT (section1)
181184

182185
ep_raise_error_if_nok (test_session != NULL);

src/mono/mono/eventpipe/test/ep-thread-tests.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -399,7 +399,8 @@ test_thread_session_state (void)
399399
provider_config,
400400
1,
401401
NULL,
402-
NULL);
402+
NULL,
403+
0);
403404
EP_LOCK_EXIT (section1)
404405

405406
if (!session) {

src/native/containers/dn-umap-t.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,5 +72,6 @@ DN_UMAP_T (ptr, void *, int16, int16_t)
7272
DN_UMAP_T (ptr, void *, uint16, uint16_t)
7373
DN_UMAP_T (ptr, void *, int32, int32_t)
7474
DN_UMAP_T (ptr, void *, uint32, uint32_t)
75+
DN_UMAP_T (uint32, uint32_t, ptr, void *)
7576

7677
#endif /* __DN_UMAP_T_H__ */

src/native/containers/dn-vector.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -268,6 +268,9 @@ dn_vector_custom_free (
268268
dn_vector_t *vector,
269269
dn_vector_dispose_func_t dispose_func)
270270
{
271+
if (DN_UNLIKELY(!vector))
272+
return;
273+
271274
dn_vector_custom_dispose (vector, dispose_func);
272275
dn_allocator_free (vector->_internal._allocator, vector);
273276
}

src/native/eventpipe/configure.cmake

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
include(CheckSymbolExists)
22
include(CheckIncludeFile)
3+
include(CheckIncludeFiles)
34

45
check_include_file(
56
sys/socket.h
@@ -17,6 +18,31 @@ if (CLR_CMAKE_HOST_IOS OR CLR_CMAKE_HOST_TVOS OR CLR_CMAKE_HOST_ANDROID)
1718
set(FEATURE_PERFTRACING_DISABLE_DEFAULT_LISTEN_PORT 1)
1819
endif()
1920

21+
check_include_file(
22+
linux/user_events.h
23+
HAVE_LINUX_USER_EVENTS_H
24+
)
25+
26+
check_include_file(
27+
sys/ioctl.h
28+
HAVE_SYS_IOCTL_H
29+
)
30+
31+
check_include_file(
32+
unistd.h
33+
HAVE_UNISTD_H
34+
)
35+
36+
check_include_file(
37+
"sys/uio.h"
38+
HAVE_SYS_UIO_H
39+
)
40+
41+
check_include_file(
42+
errno.h
43+
HAVE_ERRNO_H
44+
)
45+
2046
if (NOT DEFINED EP_GENERATED_HEADER_PATH)
2147
message(FATAL_ERROR "Required configuration EP_GENERATED_HEADER_PATH not set.")
2248
endif (NOT DEFINED EP_GENERATED_HEADER_PATH)

0 commit comments

Comments
 (0)