Skip to content

Commit e8c8ab8

Browse files
ezsilmarlateralusX
andauthored
Ability to request stackwalk per EventPipe session (#84077)
* Ability to request stackwalk per EventPipe session * Fix build * Fix build 2 * Revert all the changes to start over * Propagate disable_stacktrace parameter up to ep_enable * Refactor ds-eventpipe-protocol to use the same object for CollectTracing command * Parse disable_stacktrace in ds-eventpipe-protocol * Fix a bug in ep.c enable declaration * Introduce ep_enable_3 * Try fix failing tests * Fix incorrect validation * Use ep_enable_3 in IPC * Allocate EventPipeSessionOptions on stack * Pass EventPipeOptions by address * Rename IPC parameter to enable_stackwalk * Rename IPC parameter to stackwalk_requested * Include ds-types.h in ds-sources.c to fix the build issue * Fix jump bypasses variable initialization * Fix incorrect struct initialization * Fix incorrect struct initialization 2 * Fix incorrect struct initialization 3 * Apply code format suggestions Co-authored-by: Johan Lorensson <[email protected]> * Add ds_ipc_message_try_parse_bool * Remove EventPipeSessionOptions from ep-types-forward * init function for ep options * Use coherent if style in validation * Fix missing inline keyword * Remove inline specifier * Re-introduce EP_ASSERT in enable * add ep_session_options_fini * Fix fini called without init --------- Co-authored-by: Johan Lorensson <[email protected]>
1 parent 946c524 commit e8c8ab8

File tree

10 files changed

+309
-228
lines changed

10 files changed

+309
-228
lines changed

src/native/eventpipe/ds-eventpipe-protocol.c

Lines changed: 106 additions & 109 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,13 @@ eventpipe_collect_tracing_command_try_parse_rundown_requested (
4646
uint32_t *buffer_len,
4747
bool *rundown_requested);
4848

49+
static
50+
bool
51+
eventpipe_collect_tracing_command_try_parse_stackwalk_requested (
52+
uint8_t **buffer,
53+
uint32_t *buffer_len,
54+
bool *stackwalk_requested);
55+
4956
static
5057
bool
5158
eventpipe_collect_tracing_command_try_parse_config (
@@ -66,21 +73,21 @@ eventpipe_collect_tracing2_command_try_parse_payload (
6673
uint16_t buffer_len);
6774

6875
static
69-
bool
70-
eventpipe_protocol_helper_stop_tracing (
71-
DiagnosticsIpcMessage *message,
72-
DiagnosticsIpcStream *stream);
76+
uint8_t *
77+
eventpipe_collect_tracing3_command_try_parse_payload (
78+
uint8_t *buffer,
79+
uint16_t buffer_len);
7380

7481
static
7582
bool
76-
eventpipe_protocol_helper_collect_tracing (
83+
eventpipe_protocol_helper_stop_tracing (
7784
DiagnosticsIpcMessage *message,
7885
DiagnosticsIpcStream *stream);
7986

8087
static
8188
bool
82-
eventpipe_protocol_helper_collect_tracing_2 (
83-
DiagnosticsIpcMessage *message,
89+
eventpipe_protocol_helper_collect_tracing (
90+
EventPipeCollectTracingCommandPayload *payload,
8491
DiagnosticsIpcStream *stream);
8592

8693
static
@@ -140,7 +147,22 @@ eventpipe_collect_tracing_command_try_parse_rundown_requested (
140147
EP_ASSERT (buffer_len != NULL);
141148
EP_ASSERT (rundown_requested != NULL);
142149

143-
return ds_ipc_message_try_parse_value (buffer, buffer_len, (uint8_t *)rundown_requested, 1);
150+
return ds_ipc_message_try_parse_bool (buffer, buffer_len, rundown_requested);
151+
}
152+
153+
static
154+
inline
155+
bool
156+
eventpipe_collect_tracing_command_try_parse_stackwalk_requested (
157+
uint8_t **buffer,
158+
uint32_t *buffer_len,
159+
bool *stackwalk_requested)
160+
{
161+
EP_ASSERT (buffer != NULL);
162+
EP_ASSERT (buffer_len != NULL);
163+
EP_ASSERT (stackwalk_requested != NULL);
164+
165+
return ds_ipc_message_try_parse_bool (buffer, buffer_len, stackwalk_requested);
144166
}
145167

146168
static
@@ -231,6 +253,30 @@ eventpipe_collect_tracing_command_try_parse_config (
231253
ep_exit_error_handler ();
232254
}
233255

256+
EventPipeCollectTracingCommandPayload *
257+
ds_eventpipe_collect_tracing_command_payload_alloc (void)
258+
{
259+
return ep_rt_object_alloc (EventPipeCollectTracingCommandPayload);
260+
}
261+
262+
void
263+
ds_eventpipe_collect_tracing_command_payload_free (EventPipeCollectTracingCommandPayload *payload)
264+
{
265+
ep_return_void_if_nok (payload != NULL);
266+
ep_rt_byte_array_free (payload->incoming_buffer);
267+
268+
DN_VECTOR_FOREACH_BEGIN (EventPipeProviderConfiguration, config, payload->provider_configs) {
269+
ep_rt_utf8_string_free ((ep_char8_t *)ep_provider_config_get_provider_name (&config));
270+
ep_rt_utf8_string_free ((ep_char8_t *)ep_provider_config_get_filter_data (&config));
271+
} DN_VECTOR_FOREACH_END;
272+
273+
ep_rt_object_free (payload);
274+
}
275+
276+
/*
277+
* EventPipeCollectTracingCommandPayload
278+
*/
279+
234280
static
235281
uint8_t *
236282
eventpipe_collect_tracing_command_try_parse_payload (
@@ -251,6 +297,8 @@ eventpipe_collect_tracing_command_try_parse_payload (
251297
!eventpipe_collect_tracing_command_try_parse_serialization_format (&buffer_cursor, &buffer_cursor_len, &instance->serialization_format) ||
252298
!eventpipe_collect_tracing_command_try_parse_config (&buffer_cursor, &buffer_cursor_len, &instance->provider_configs))
253299
ep_raise_error ();
300+
instance->rundown_requested = true;
301+
instance->stackwalk_requested = true;
254302

255303
ep_on_exit:
256304
return (uint8_t *)instance;
@@ -261,30 +309,6 @@ eventpipe_collect_tracing_command_try_parse_payload (
261309
ep_exit_error_handler ();
262310
}
263311

264-
EventPipeCollectTracingCommandPayload *
265-
ds_eventpipe_collect_tracing_command_payload_alloc (void)
266-
{
267-
return ep_rt_object_alloc (EventPipeCollectTracingCommandPayload);
268-
}
269-
270-
void
271-
ds_eventpipe_collect_tracing_command_payload_free (EventPipeCollectTracingCommandPayload *payload)
272-
{
273-
ep_return_void_if_nok (payload != NULL);
274-
ep_rt_byte_array_free (payload->incoming_buffer);
275-
276-
DN_VECTOR_FOREACH_BEGIN (EventPipeProviderConfiguration, config, payload->provider_configs) {
277-
ep_rt_utf8_string_free ((ep_char8_t *)ep_provider_config_get_provider_name (&config));
278-
ep_rt_utf8_string_free ((ep_char8_t *)ep_provider_config_get_filter_data (&config));
279-
} DN_VECTOR_FOREACH_END;
280-
281-
ep_rt_object_free (payload);
282-
}
283-
284-
/*
285-
* EventPipeCollectTracing2CommandPayload
286-
*/
287-
288312
static
289313
uint8_t *
290314
eventpipe_collect_tracing2_command_try_parse_payload (
@@ -296,7 +320,7 @@ eventpipe_collect_tracing2_command_try_parse_payload (
296320
uint8_t * buffer_cursor = buffer;
297321
uint32_t buffer_cursor_len = buffer_len;
298322

299-
EventPipeCollectTracing2CommandPayload *instance = ds_eventpipe_collect_tracing2_command_payload_alloc ();
323+
EventPipeCollectTracingCommandPayload *instance = ds_eventpipe_collect_tracing_command_payload_alloc ();
300324
ep_raise_error_if_nok (instance != NULL);
301325

302326
instance->incoming_buffer = buffer;
@@ -306,34 +330,47 @@ eventpipe_collect_tracing2_command_try_parse_payload (
306330
!eventpipe_collect_tracing_command_try_parse_rundown_requested (&buffer_cursor, &buffer_cursor_len, &instance->rundown_requested) ||
307331
!eventpipe_collect_tracing_command_try_parse_config (&buffer_cursor, &buffer_cursor_len, &instance->provider_configs))
308332
ep_raise_error ();
333+
instance->stackwalk_requested = true;
309334

310335
ep_on_exit:
311336
return (uint8_t *)instance;
312337

313338
ep_on_error:
314-
ds_eventpipe_collect_tracing2_command_payload_free (instance);
339+
ds_eventpipe_collect_tracing_command_payload_free (instance);
315340
instance = NULL;
316341
ep_exit_error_handler ();
317342
}
318343

319-
EventPipeCollectTracing2CommandPayload *
320-
ds_eventpipe_collect_tracing2_command_payload_alloc (void)
344+
static
345+
uint8_t *
346+
eventpipe_collect_tracing3_command_try_parse_payload (
347+
uint8_t *buffer,
348+
uint16_t buffer_len)
321349
{
322-
return ep_rt_object_alloc (EventPipeCollectTracing2CommandPayload);
323-
}
350+
EP_ASSERT (buffer != NULL);
324351

325-
void
326-
ds_eventpipe_collect_tracing2_command_payload_free (EventPipeCollectTracing2CommandPayload *payload)
327-
{
328-
ep_return_void_if_nok (payload != NULL);
329-
ep_rt_byte_array_free (payload->incoming_buffer);
352+
uint8_t * buffer_cursor = buffer;
353+
uint32_t buffer_cursor_len = buffer_len;
330354

331-
DN_VECTOR_FOREACH_BEGIN (EventPipeProviderConfiguration, config, payload->provider_configs) {
332-
ep_rt_utf8_string_free ((ep_char8_t *)ep_provider_config_get_provider_name (&config));
333-
ep_rt_utf8_string_free ((ep_char8_t *)ep_provider_config_get_filter_data (&config));
334-
} DN_VECTOR_FOREACH_END;
355+
EventPipeCollectTracingCommandPayload *instance = ds_eventpipe_collect_tracing_command_payload_alloc ();
356+
ep_raise_error_if_nok (instance != NULL);
335357

336-
ep_rt_object_free (payload);
358+
instance->incoming_buffer = buffer;
359+
360+
if (!eventpipe_collect_tracing_command_try_parse_circular_buffer_size (&buffer_cursor, &buffer_cursor_len, &instance->circular_buffer_size_in_mb ) ||
361+
!eventpipe_collect_tracing_command_try_parse_serialization_format (&buffer_cursor, &buffer_cursor_len, &instance->serialization_format) ||
362+
!eventpipe_collect_tracing_command_try_parse_rundown_requested (&buffer_cursor, &buffer_cursor_len, &instance->rundown_requested) ||
363+
!eventpipe_collect_tracing_command_try_parse_stackwalk_requested (&buffer_cursor, &buffer_cursor_len, &instance->stackwalk_requested) ||
364+
!eventpipe_collect_tracing_command_try_parse_config (&buffer_cursor, &buffer_cursor_len, &instance->provider_configs))
365+
ep_raise_error ();
366+
367+
ep_on_exit:
368+
return (uint8_t *)instance;
369+
370+
ep_on_error:
371+
ds_eventpipe_collect_tracing_command_payload_free (instance);
372+
instance = NULL;
373+
ep_exit_error_handler ();
337374
}
338375

339376
/*
@@ -415,82 +452,34 @@ eventpipe_protocol_helper_stop_tracing (
415452
static
416453
bool
417454
eventpipe_protocol_helper_collect_tracing (
418-
DiagnosticsIpcMessage *message,
455+
EventPipeCollectTracingCommandPayload *payload,
419456
DiagnosticsIpcStream *stream)
420457
{
421-
ep_return_false_if_nok (message != NULL && stream != NULL);
422-
423-
bool result = false;
424-
EventPipeCollectTracingCommandPayload *payload;
425-
payload = (EventPipeCollectTracingCommandPayload *)ds_ipc_message_try_parse_payload (message, eventpipe_collect_tracing_command_try_parse_payload);
458+
ep_return_false_if_nok (stream != NULL);
426459

427460
if (!payload) {
428461
ds_ipc_message_send_error (stream, DS_IPC_E_BAD_ENCODING);
429-
ep_raise_error ();
462+
return false;
430463
}
431464

432-
EventPipeSessionID session_id;
433-
session_id = ep_enable (
465+
EventPipeSessionOptions options;
466+
ep_session_options_init(
467+
&options,
434468
NULL,
435469
payload->circular_buffer_size_in_mb,
436470
dn_vector_data_t (payload->provider_configs, EventPipeProviderConfiguration),
437471
dn_vector_size (payload->provider_configs),
438472
EP_SESSION_TYPE_IPCSTREAM,
439473
payload->serialization_format,
440-
true,
474+
payload->rundown_requested,
475+
payload->stackwalk_requested,
441476
ds_ipc_stream_get_stream_ref (stream),
442477
NULL,
443478
NULL);
444479

445-
if (session_id == 0) {
446-
ds_ipc_message_send_error (stream, DS_IPC_E_FAIL);
447-
ep_raise_error ();
448-
} else {
449-
eventpipe_protocol_helper_send_start_tracing_success (stream, session_id);
450-
ep_start_streaming (session_id);
451-
}
452-
453-
result = true;
454-
455-
ep_on_exit:
456-
ds_eventpipe_collect_tracing_command_payload_free (payload);
457-
return result;
458-
459-
ep_on_error:
460-
EP_ASSERT (!result);
461-
ds_ipc_stream_free (stream);
462-
ep_exit_error_handler ();
463-
}
464-
465-
static
466-
bool
467-
eventpipe_protocol_helper_collect_tracing_2 (
468-
DiagnosticsIpcMessage *message,
469-
DiagnosticsIpcStream *stream)
470-
{
471-
ep_return_false_if_nok (message != NULL && stream != NULL);
472-
480+
EventPipeSessionID session_id = 0;
473481
bool result = false;
474-
EventPipeCollectTracing2CommandPayload *payload;
475-
payload = (EventPipeCollectTracing2CommandPayload *)ds_ipc_message_try_parse_payload (message, eventpipe_collect_tracing2_command_try_parse_payload);
476-
477-
if (!payload) {
478-
ds_ipc_message_send_error (stream, DS_IPC_E_BAD_ENCODING);
479-
ep_raise_error ();
480-
}
481-
482-
EventPipeSessionID session_id;
483-
session_id = ep_enable (
484-
NULL,
485-
payload->circular_buffer_size_in_mb,
486-
dn_vector_data_t (payload->provider_configs, EventPipeProviderConfiguration),
487-
dn_vector_size (payload->provider_configs),
488-
EP_SESSION_TYPE_IPCSTREAM,
489-
payload->serialization_format,
490-
payload->rundown_requested,
491-
ds_ipc_stream_get_stream_ref (stream),
492-
NULL,
493-
NULL);
482+
session_id = ep_enable_3(&options);
494483

495484
if (session_id == 0) {
496485
ds_ipc_message_send_error (stream, DS_IPC_E_FAIL);
@@ -503,7 +492,8 @@ eventpipe_protocol_helper_collect_tracing_2 (
503492
result = true;
504493

505494
ep_on_exit:
506-
ds_eventpipe_collect_tracing2_command_payload_free (payload);
495+
ep_session_options_fini(&options);
496+
ds_eventpipe_collect_tracing_command_payload_free (payload);
507497
return result;
508498

509499
ep_on_error:
@@ -539,13 +529,20 @@ ds_eventpipe_protocol_helper_handle_ipc_message (
539529
ep_return_false_if_nok (message != NULL && stream != NULL);
540530

541531
bool result = false;
532+
EventPipeCollectTracingCommandPayload* payload = NULL;
542533

543534
switch ((EventPipeCommandId)ds_ipc_header_get_commandid (ds_ipc_message_get_header_cref (message))) {
544535
case EP_COMMANDID_COLLECT_TRACING:
545-
result = eventpipe_protocol_helper_collect_tracing (message, stream);
536+
payload = (EventPipeCollectTracingCommandPayload *)ds_ipc_message_try_parse_payload (message, eventpipe_collect_tracing_command_try_parse_payload);
537+
result = eventpipe_protocol_helper_collect_tracing (payload, stream);
546538
break;
547539
case EP_COMMANDID_COLLECT_TRACING_2:
548-
result = eventpipe_protocol_helper_collect_tracing_2 (message, stream);
540+
payload = (EventPipeCollectTracingCommandPayload *)ds_ipc_message_try_parse_payload (message, eventpipe_collect_tracing2_command_try_parse_payload);
541+
result = eventpipe_protocol_helper_collect_tracing (payload, stream);
542+
break;
543+
case EP_COMMANDID_COLLECT_TRACING_3:
544+
payload = (EventPipeCollectTracingCommandPayload *)ds_ipc_message_try_parse_payload (message, eventpipe_collect_tracing3_command_try_parse_payload);
545+
result = eventpipe_protocol_helper_collect_tracing (payload, stream);
549546
break;
550547
case EP_COMMANDID_STOP_TRACING:
551548
result = eventpipe_protocol_helper_stop_tracing (message, stream);

src/native/eventpipe/ds-eventpipe-protocol.h

Lines changed: 4 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818
*/
1919

2020
// Command = 0x0202
21+
// Command = 0x0203
22+
// Command = 0x0204
2123
#if defined(DS_INLINE_GETTER_SETTER) || defined(DS_IMPL_EVENTPIPE_PROTOCOL_GETTER_SETTER)
2224
struct _EventPipeCollectTracingCommandPayload {
2325
#else
@@ -36,6 +38,8 @@ struct _EventPipeCollectTracingCommandPayload_Internal {
3638
dn_vector_t *provider_configs;
3739
uint32_t circular_buffer_size_in_mb;
3840
EventPipeSerializationFormat serialization_format;
41+
bool rundown_requested;
42+
bool stackwalk_requested;
3943
};
4044

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

53-
/*
54-
* EventPipeCollectTracing2CommandPayload
55-
*/
56-
57-
// Command = 0x0202
58-
#if defined(DS_INLINE_GETTER_SETTER) || defined(DS_IMPL_EVENTPIPE_PROTOCOL_GETTER_SETTER)
59-
struct _EventPipeCollectTracing2CommandPayload {
60-
#else
61-
struct _EventPipeCollectTracing2CommandPayload_Internal {
62-
#endif
63-
// The protocol buffer is defined as:
64-
// X, Y, Z means encode bytes for X followed by bytes for Y followed by bytes for Z
65-
// message = uint circularBufferMB, uint format, array<provider_config> providers
66-
// uint = 4 little endian bytes
67-
// wchar = 2 little endian bytes, UTF16 encoding
68-
// array<T> = uint length, length # of Ts
69-
// string = (array<char> where the last char must = 0) or (length = 0)
70-
// provider_config = ulong keywords, uint logLevel, string provider_name, string filter_data
71-
72-
uint8_t *incoming_buffer;
73-
dn_vector_t *provider_configs;
74-
uint32_t circular_buffer_size_in_mb;
75-
EventPipeSerializationFormat serialization_format;
76-
bool rundown_requested;
77-
};
78-
79-
#if !defined(DS_INLINE_GETTER_SETTER) && !defined(DS_IMPL_EVENTPIPE_PROTOCOL_GETTER_SETTER)
80-
struct _EventPipeCollectTracing2CommandPayload {
81-
uint8_t _internal [sizeof (struct _EventPipeCollectTracing2CommandPayload_Internal)];
82-
};
83-
#endif
84-
85-
EventPipeCollectTracing2CommandPayload *
86-
ds_eventpipe_collect_tracing2_command_payload_alloc (void);
87-
88-
void
89-
ds_eventpipe_collect_tracing2_command_payload_free (EventPipeCollectTracing2CommandPayload *payload);
90-
9157
/*
9258
* EventPipeStopTracingCommandPayload
9359
*/

0 commit comments

Comments
 (0)