Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ability to request stackwalk per EventPipe session #84077

Merged
merged 37 commits into from
Oct 13, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
227992e
Ability to request stackwalk per EventPipe session
ezsilmar Mar 23, 2023
67147da
Fix build
ezsilmar Mar 29, 2023
0bfeec1
Fix build 2
ezsilmar Mar 29, 2023
f8d1ea7
Revert all the changes to start over
ezsilmar Aug 9, 2023
7a6ca27
Merge remote-tracking branch 'origin/main' into PR_eventpipe_requestS…
ezsilmar Aug 9, 2023
81f40b2
Merge branch 'main' of github.com:dotnet/runtime into PR_eventpipe_re…
ezsilmar Aug 11, 2023
5e2c5eb
Propagate disable_stacktrace parameter up to ep_enable
ezsilmar Aug 18, 2023
084c216
Refactor ds-eventpipe-protocol to use the same object for CollectTrac…
ezsilmar Aug 18, 2023
4917d6f
Parse disable_stacktrace in ds-eventpipe-protocol
ezsilmar Aug 18, 2023
999bd23
Fix a bug in ep.c enable declaration
ezsilmar Aug 18, 2023
29b7105
Introduce ep_enable_3
ezsilmar Aug 18, 2023
c7051ca
Try fix failing tests
ezsilmar Aug 21, 2023
d6a3923
Fix incorrect validation
ezsilmar Aug 21, 2023
6f4e68b
Use ep_enable_3 in IPC
ezsilmar Aug 21, 2023
d71b8e8
Allocate EventPipeSessionOptions on stack
ezsilmar Aug 25, 2023
a57ddbe
Pass EventPipeOptions by address
ezsilmar Aug 28, 2023
d18f45c
Rename IPC parameter to enable_stackwalk
ezsilmar Aug 28, 2023
e35e0af
Rename IPC parameter to stackwalk_requested
ezsilmar Aug 28, 2023
d09a83d
Include ds-types.h in ds-sources.c to fix the build issue
ezsilmar Aug 28, 2023
593381a
Fix jump bypasses variable initialization
ezsilmar Aug 28, 2023
7af4f1d
Merge branch 'main' into PR_eventpipe_requestStacks
ezsilmar Aug 28, 2023
367d108
Fix incorrect struct initialization
ezsilmar Aug 29, 2023
19d350a
Fix incorrect struct initialization 2
ezsilmar Aug 29, 2023
2e84c90
Fix incorrect struct initialization 3
ezsilmar Aug 29, 2023
6e6dbb4
Apply code format suggestions
ezsilmar Aug 31, 2023
1bf492a
Merge remote-tracking branch 'origin/main' into PR_eventpipe_requestS…
ezsilmar Oct 2, 2023
28ea623
Add ds_ipc_message_try_parse_bool
ezsilmar Oct 2, 2023
e59b228
Remove EventPipeSessionOptions from ep-types-forward
ezsilmar Oct 3, 2023
5ce6ff2
init function for ep options
ezsilmar Oct 3, 2023
19b8e5c
Use coherent if style in validation
ezsilmar Oct 3, 2023
26b4744
Fix missing inline keyword
ezsilmar Oct 3, 2023
f7b879c
Remove inline specifier
ezsilmar Oct 3, 2023
3f3535c
Merge branch 'main' into PR_eventpipe_requestStacks
ezsilmar Oct 9, 2023
84addea
Re-introduce EP_ASSERT in enable
ezsilmar Oct 10, 2023
9587b89
add ep_session_options_fini
ezsilmar Oct 10, 2023
1071117
Fix fini called without init
ezsilmar Oct 10, 2023
8b75c49
Merge branch 'main' into PR_eventpipe_requestStacks
ezsilmar Oct 10, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
215 changes: 106 additions & 109 deletions src/native/eventpipe/ds-eventpipe-protocol.c
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,13 @@ eventpipe_collect_tracing_command_try_parse_rundown_requested (
uint32_t *buffer_len,
bool *rundown_requested);

static
bool
eventpipe_collect_tracing_command_try_parse_stackwalk_requested (
uint8_t **buffer,
uint32_t *buffer_len,
bool *stackwalk_requested);

static
bool
eventpipe_collect_tracing_command_try_parse_config (
Expand All @@ -66,21 +73,21 @@ eventpipe_collect_tracing2_command_try_parse_payload (
uint16_t buffer_len);

static
bool
eventpipe_protocol_helper_stop_tracing (
DiagnosticsIpcMessage *message,
DiagnosticsIpcStream *stream);
uint8_t *
eventpipe_collect_tracing3_command_try_parse_payload (
uint8_t *buffer,
uint16_t buffer_len);

static
bool
eventpipe_protocol_helper_collect_tracing (
eventpipe_protocol_helper_stop_tracing (
DiagnosticsIpcMessage *message,
DiagnosticsIpcStream *stream);

static
bool
eventpipe_protocol_helper_collect_tracing_2 (
DiagnosticsIpcMessage *message,
eventpipe_protocol_helper_collect_tracing (
EventPipeCollectTracingCommandPayload *payload,
DiagnosticsIpcStream *stream);

static
Expand Down Expand Up @@ -140,7 +147,22 @@ eventpipe_collect_tracing_command_try_parse_rundown_requested (
EP_ASSERT (buffer_len != NULL);
EP_ASSERT (rundown_requested != NULL);

return ds_ipc_message_try_parse_value (buffer, buffer_len, (uint8_t *)rundown_requested, 1);
return ds_ipc_message_try_parse_bool (buffer, buffer_len, rundown_requested);
}

static
inline
bool
eventpipe_collect_tracing_command_try_parse_stackwalk_requested (
uint8_t **buffer,
uint32_t *buffer_len,
bool *stackwalk_requested)
{
EP_ASSERT (buffer != NULL);
EP_ASSERT (buffer_len != NULL);
EP_ASSERT (stackwalk_requested != NULL);

return ds_ipc_message_try_parse_bool (buffer, buffer_len, stackwalk_requested);
}

static
Expand Down Expand Up @@ -231,6 +253,30 @@ eventpipe_collect_tracing_command_try_parse_config (
ep_exit_error_handler ();
}

EventPipeCollectTracingCommandPayload *
ds_eventpipe_collect_tracing_command_payload_alloc (void)
{
return ep_rt_object_alloc (EventPipeCollectTracingCommandPayload);
}

void
ds_eventpipe_collect_tracing_command_payload_free (EventPipeCollectTracingCommandPayload *payload)
{
ep_return_void_if_nok (payload != NULL);
ep_rt_byte_array_free (payload->incoming_buffer);

DN_VECTOR_FOREACH_BEGIN (EventPipeProviderConfiguration, config, payload->provider_configs) {
ep_rt_utf8_string_free ((ep_char8_t *)ep_provider_config_get_provider_name (&config));
ep_rt_utf8_string_free ((ep_char8_t *)ep_provider_config_get_filter_data (&config));
} DN_VECTOR_FOREACH_END;

ep_rt_object_free (payload);
}

/*
* EventPipeCollectTracingCommandPayload
*/

static
uint8_t *
eventpipe_collect_tracing_command_try_parse_payload (
Expand All @@ -251,6 +297,8 @@ eventpipe_collect_tracing_command_try_parse_payload (
!eventpipe_collect_tracing_command_try_parse_serialization_format (&buffer_cursor, &buffer_cursor_len, &instance->serialization_format) ||
!eventpipe_collect_tracing_command_try_parse_config (&buffer_cursor, &buffer_cursor_len, &instance->provider_configs))
ep_raise_error ();
instance->rundown_requested = true;
instance->stackwalk_requested = true;

ep_on_exit:
return (uint8_t *)instance;
Expand All @@ -261,30 +309,6 @@ eventpipe_collect_tracing_command_try_parse_payload (
ep_exit_error_handler ();
}

EventPipeCollectTracingCommandPayload *
ds_eventpipe_collect_tracing_command_payload_alloc (void)
{
return ep_rt_object_alloc (EventPipeCollectTracingCommandPayload);
}

void
ds_eventpipe_collect_tracing_command_payload_free (EventPipeCollectTracingCommandPayload *payload)
{
ep_return_void_if_nok (payload != NULL);
ep_rt_byte_array_free (payload->incoming_buffer);

DN_VECTOR_FOREACH_BEGIN (EventPipeProviderConfiguration, config, payload->provider_configs) {
ep_rt_utf8_string_free ((ep_char8_t *)ep_provider_config_get_provider_name (&config));
ep_rt_utf8_string_free ((ep_char8_t *)ep_provider_config_get_filter_data (&config));
} DN_VECTOR_FOREACH_END;

ep_rt_object_free (payload);
}

/*
* EventPipeCollectTracing2CommandPayload
*/

static
uint8_t *
eventpipe_collect_tracing2_command_try_parse_payload (
Expand All @@ -296,7 +320,7 @@ eventpipe_collect_tracing2_command_try_parse_payload (
uint8_t * buffer_cursor = buffer;
uint32_t buffer_cursor_len = buffer_len;

EventPipeCollectTracing2CommandPayload *instance = ds_eventpipe_collect_tracing2_command_payload_alloc ();
EventPipeCollectTracingCommandPayload *instance = ds_eventpipe_collect_tracing_command_payload_alloc ();
ep_raise_error_if_nok (instance != NULL);

instance->incoming_buffer = buffer;
Expand All @@ -306,34 +330,47 @@ eventpipe_collect_tracing2_command_try_parse_payload (
!eventpipe_collect_tracing_command_try_parse_rundown_requested (&buffer_cursor, &buffer_cursor_len, &instance->rundown_requested) ||
!eventpipe_collect_tracing_command_try_parse_config (&buffer_cursor, &buffer_cursor_len, &instance->provider_configs))
ep_raise_error ();
instance->stackwalk_requested = true;

ep_on_exit:
return (uint8_t *)instance;

ep_on_error:
ds_eventpipe_collect_tracing2_command_payload_free (instance);
ds_eventpipe_collect_tracing_command_payload_free (instance);
instance = NULL;
ep_exit_error_handler ();
}

EventPipeCollectTracing2CommandPayload *
ds_eventpipe_collect_tracing2_command_payload_alloc (void)
static
uint8_t *
eventpipe_collect_tracing3_command_try_parse_payload (
noahfalk marked this conversation as resolved.
Show resolved Hide resolved
uint8_t *buffer,
uint16_t buffer_len)
{
return ep_rt_object_alloc (EventPipeCollectTracing2CommandPayload);
}
EP_ASSERT (buffer != NULL);

void
ds_eventpipe_collect_tracing2_command_payload_free (EventPipeCollectTracing2CommandPayload *payload)
{
ep_return_void_if_nok (payload != NULL);
ep_rt_byte_array_free (payload->incoming_buffer);
uint8_t * buffer_cursor = buffer;
uint32_t buffer_cursor_len = buffer_len;

DN_VECTOR_FOREACH_BEGIN (EventPipeProviderConfiguration, config, payload->provider_configs) {
ep_rt_utf8_string_free ((ep_char8_t *)ep_provider_config_get_provider_name (&config));
ep_rt_utf8_string_free ((ep_char8_t *)ep_provider_config_get_filter_data (&config));
} DN_VECTOR_FOREACH_END;
EventPipeCollectTracingCommandPayload *instance = ds_eventpipe_collect_tracing_command_payload_alloc ();
ep_raise_error_if_nok (instance != NULL);

ep_rt_object_free (payload);
instance->incoming_buffer = buffer;

if (!eventpipe_collect_tracing_command_try_parse_circular_buffer_size (&buffer_cursor, &buffer_cursor_len, &instance->circular_buffer_size_in_mb ) ||
!eventpipe_collect_tracing_command_try_parse_serialization_format (&buffer_cursor, &buffer_cursor_len, &instance->serialization_format) ||
!eventpipe_collect_tracing_command_try_parse_rundown_requested (&buffer_cursor, &buffer_cursor_len, &instance->rundown_requested) ||
!eventpipe_collect_tracing_command_try_parse_stackwalk_requested (&buffer_cursor, &buffer_cursor_len, &instance->stackwalk_requested) ||
!eventpipe_collect_tracing_command_try_parse_config (&buffer_cursor, &buffer_cursor_len, &instance->provider_configs))
ep_raise_error ();

ep_on_exit:
return (uint8_t *)instance;

ep_on_error:
ds_eventpipe_collect_tracing_command_payload_free (instance);
instance = NULL;
ep_exit_error_handler ();
}

/*
Expand Down Expand Up @@ -415,82 +452,34 @@ eventpipe_protocol_helper_stop_tracing (
static
bool
eventpipe_protocol_helper_collect_tracing (
DiagnosticsIpcMessage *message,
EventPipeCollectTracingCommandPayload *payload,
DiagnosticsIpcStream *stream)
{
ep_return_false_if_nok (message != NULL && stream != NULL);

bool result = false;
EventPipeCollectTracingCommandPayload *payload;
payload = (EventPipeCollectTracingCommandPayload *)ds_ipc_message_try_parse_payload (message, eventpipe_collect_tracing_command_try_parse_payload);
ep_return_false_if_nok (stream != NULL);

if (!payload) {
ds_ipc_message_send_error (stream, DS_IPC_E_BAD_ENCODING);
ep_raise_error ();
return false;
}

EventPipeSessionID session_id;
session_id = ep_enable (
EventPipeSessionOptions options;
ep_session_options_init(
&options,
NULL,
payload->circular_buffer_size_in_mb,
dn_vector_data_t (payload->provider_configs, EventPipeProviderConfiguration),
dn_vector_size (payload->provider_configs),
EP_SESSION_TYPE_IPCSTREAM,
payload->serialization_format,
true,
payload->rundown_requested,
payload->stackwalk_requested,
ds_ipc_stream_get_stream_ref (stream),
NULL,
NULL);

if (session_id == 0) {
ds_ipc_message_send_error (stream, DS_IPC_E_FAIL);
ep_raise_error ();
} else {
eventpipe_protocol_helper_send_start_tracing_success (stream, session_id);
ep_start_streaming (session_id);
}

result = true;

ep_on_exit:
ds_eventpipe_collect_tracing_command_payload_free (payload);
return result;

ep_on_error:
EP_ASSERT (!result);
ds_ipc_stream_free (stream);
ep_exit_error_handler ();
}

static
bool
eventpipe_protocol_helper_collect_tracing_2 (
DiagnosticsIpcMessage *message,
DiagnosticsIpcStream *stream)
{
ep_return_false_if_nok (message != NULL && stream != NULL);

EventPipeSessionID session_id = 0;
bool result = false;
EventPipeCollectTracing2CommandPayload *payload;
payload = (EventPipeCollectTracing2CommandPayload *)ds_ipc_message_try_parse_payload (message, eventpipe_collect_tracing2_command_try_parse_payload);

if (!payload) {
ds_ipc_message_send_error (stream, DS_IPC_E_BAD_ENCODING);
ep_raise_error ();
}

EventPipeSessionID session_id;
session_id = ep_enable (
NULL,
payload->circular_buffer_size_in_mb,
dn_vector_data_t (payload->provider_configs, EventPipeProviderConfiguration),
dn_vector_size (payload->provider_configs),
EP_SESSION_TYPE_IPCSTREAM,
payload->serialization_format,
payload->rundown_requested,
ds_ipc_stream_get_stream_ref (stream),
NULL,
NULL);
session_id = ep_enable_3(&options);

if (session_id == 0) {
ds_ipc_message_send_error (stream, DS_IPC_E_FAIL);
Expand All @@ -503,7 +492,8 @@ eventpipe_protocol_helper_collect_tracing_2 (
result = true;

ep_on_exit:
ds_eventpipe_collect_tracing2_command_payload_free (payload);
ep_session_options_fini(&options);
ds_eventpipe_collect_tracing_command_payload_free (payload);
return result;

ep_on_error:
Expand Down Expand Up @@ -539,13 +529,20 @@ ds_eventpipe_protocol_helper_handle_ipc_message (
ep_return_false_if_nok (message != NULL && stream != NULL);

bool result = false;
EventPipeCollectTracingCommandPayload* payload = NULL;

switch ((EventPipeCommandId)ds_ipc_header_get_commandid (ds_ipc_message_get_header_cref (message))) {
case EP_COMMANDID_COLLECT_TRACING:
result = eventpipe_protocol_helper_collect_tracing (message, stream);
payload = (EventPipeCollectTracingCommandPayload *)ds_ipc_message_try_parse_payload (message, eventpipe_collect_tracing_command_try_parse_payload);
result = eventpipe_protocol_helper_collect_tracing (payload, stream);
break;
case EP_COMMANDID_COLLECT_TRACING_2:
result = eventpipe_protocol_helper_collect_tracing_2 (message, stream);
payload = (EventPipeCollectTracingCommandPayload *)ds_ipc_message_try_parse_payload (message, eventpipe_collect_tracing2_command_try_parse_payload);
result = eventpipe_protocol_helper_collect_tracing (payload, stream);
break;
case EP_COMMANDID_COLLECT_TRACING_3:
payload = (EventPipeCollectTracingCommandPayload *)ds_ipc_message_try_parse_payload (message, eventpipe_collect_tracing3_command_try_parse_payload);
result = eventpipe_protocol_helper_collect_tracing (payload, stream);
break;
case EP_COMMANDID_STOP_TRACING:
result = eventpipe_protocol_helper_stop_tracing (message, stream);
Expand Down
42 changes: 4 additions & 38 deletions src/native/eventpipe/ds-eventpipe-protocol.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
*/

// Command = 0x0202
// Command = 0x0203
// Command = 0x0204
#if defined(DS_INLINE_GETTER_SETTER) || defined(DS_IMPL_EVENTPIPE_PROTOCOL_GETTER_SETTER)
struct _EventPipeCollectTracingCommandPayload {
#else
Expand All @@ -36,6 +38,8 @@ struct _EventPipeCollectTracingCommandPayload_Internal {
dn_vector_t *provider_configs;
uint32_t circular_buffer_size_in_mb;
EventPipeSerializationFormat serialization_format;
bool rundown_requested;
bool stackwalk_requested;
};

#if !defined(DS_INLINE_GETTER_SETTER) && !defined(DS_IMPL_EVENTPIPE_PROTOCOL_GETTER_SETTER)
Expand All @@ -50,44 +54,6 @@ ds_eventpipe_collect_tracing_command_payload_alloc (void);
void
ds_eventpipe_collect_tracing_command_payload_free (EventPipeCollectTracingCommandPayload *payload);

/*
* EventPipeCollectTracing2CommandPayload
*/

// Command = 0x0202
#if defined(DS_INLINE_GETTER_SETTER) || defined(DS_IMPL_EVENTPIPE_PROTOCOL_GETTER_SETTER)
struct _EventPipeCollectTracing2CommandPayload {
#else
struct _EventPipeCollectTracing2CommandPayload_Internal {
#endif
// The protocol buffer is defined as:
// X, Y, Z means encode bytes for X followed by bytes for Y followed by bytes for Z
// message = uint circularBufferMB, uint format, array<provider_config> providers
// uint = 4 little endian bytes
// wchar = 2 little endian bytes, UTF16 encoding
// array<T> = uint length, length # of Ts
// string = (array<char> where the last char must = 0) or (length = 0)
// provider_config = ulong keywords, uint logLevel, string provider_name, string filter_data

uint8_t *incoming_buffer;
dn_vector_t *provider_configs;
uint32_t circular_buffer_size_in_mb;
EventPipeSerializationFormat serialization_format;
bool rundown_requested;
};

#if !defined(DS_INLINE_GETTER_SETTER) && !defined(DS_IMPL_EVENTPIPE_PROTOCOL_GETTER_SETTER)
struct _EventPipeCollectTracing2CommandPayload {
uint8_t _internal [sizeof (struct _EventPipeCollectTracing2CommandPayload_Internal)];
};
#endif

EventPipeCollectTracing2CommandPayload *
ds_eventpipe_collect_tracing2_command_payload_alloc (void);

void
ds_eventpipe_collect_tracing2_command_payload_free (EventPipeCollectTracing2CommandPayload *payload);

/*
* EventPipeStopTracingCommandPayload
*/
Expand Down
Loading