Skip to content

Commit

Permalink
Adjust Mono EventPipe/DiagnosticServer C library to better support Co…
Browse files Browse the repository at this point in the history
…reCLR shim. (#44527)

* Adjust EventPipe/DiagnosticServer C library to support CoreCLR shim.

Adjustments done to better align with implementation of CoreCLR shim
using CoreCLR artifacts and C++ code (CoreCLR implementation done in
separate PR).

Disconnect runtime specific shim info from shared sources, all included
shim files handled through defines.

Exception safety and improved error handling, adding error checking
and error returns into shim container functions.

Walkthrough of codebase, aligning with gaps from CoreCLR + port of
sample profiler and json file serializer.

Implement core dump diagnostic command and runtime layer (needed by CoreCLR,
currently not implemented on Mono).

Implemented process env diagnostic command and runtime layer.

Implemented profiler attach diagnostic command and runtime layer (needed by
CoreCLR, currently not implemented on Mono).

Fix native EventPipe test aligning with changes.

* Fix build errors.

* Review feedback.
  • Loading branch information
lateralusX authored Nov 17, 2020
1 parent a5d6b30 commit f6bfec0
Show file tree
Hide file tree
Showing 76 changed files with 3,619 additions and 1,080 deletions.
18 changes: 16 additions & 2 deletions src/mono/mono/eventpipe/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@

set(eventpipe_sources_base
ds.c
ds-dump-protocol.c
ds-dump-protocol.h
ds-eventpipe-protocol.c
ds-eventpipe-protocol.h
ds-getter-setter.h
ds-ipc.c
ds-ipc.h
ds-ipc-posix.c
ds-ipc-posix.h
ds-process-protocol.c
ds-process-protocol.h
ds-profiler-protocol.c
Expand Down Expand Up @@ -46,6 +45,8 @@ set(eventpipe_sources_base
ep-file.c
ep-file.h
ep-getter-setter.h
ep-json-file.c
ep-json-file.h
ep-metadata-generator.c
ep-metadata-generator.h
ep-provider.c
Expand All @@ -61,13 +62,26 @@ set(eventpipe_sources_base
ep-thread.c
ep-thread.h
ep-types.h
ep-sample-profiler.c
ep-sample-profiler.h
ep-session.c
ep-session.h
ep-session-provider.c
ep-stack-contents.c
ep-stack-contents.h
ep-stream.c
ep-stream.h)

if(HOST_WIN32 OR CLR_CMAKE_TARGET_WIN32)
list(APPEND eventpipe_sources_base
ds-ipc-win32.c
ds-ipc-win32.h)
else()
list(APPEND eventpipe_sources_base
ds-ipc-posix.c
ds-ipc-posix.h)
endif()

if(ENABLE_PERFTRACING)
addprefix(eventpipe_sources ../eventpipe "${eventpipe_sources_base}")
endif()
5 changes: 5 additions & 0 deletions src/mono/mono/eventpipe/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ AM_CPPFLAGS = -I$(top_srcdir) -I$(top_srcdir)/mono $(GLIB_CFLAGS) $(SHARED_CFLAG
noinst_LTLIBRARIES = libeventpipe.la

eventpipe_sources = \
ds.c \
ds-dump-protocol.c \
ds-dump-protocol.h \
ds-eventpipe-protocol.c \
Expand Down Expand Up @@ -54,6 +55,8 @@ eventpipe_sources = \
ep-file.c \
ep-file.h \
ep-getter-setter.h \
ep-json-file.c \
ep-json-file.h \
ep-metadata-generator.c \
ep-metadata-generator.h \
ep-provider.c \
Expand All @@ -69,6 +72,8 @@ eventpipe_sources = \
ep-thread.c \
ep-thread.h \
ep-types.h \
ep-sample-profiler.c \
ep-sample-profiler.h \
ep-session.c \
ep-session.h \
ep-session-provider.c \
Expand Down
142 changes: 138 additions & 4 deletions src/mono/mono/eventpipe/ds-dump-protocol.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,18 +9,152 @@
#include "ds-dump-protocol.h"
#include "ds-rt.h"

/*
* Forward declares of all static functions.
*/
static
uint8_t *
generate_core_dump_command_try_parse_payload (
uint8_t *buffer,
uint16_t buffer_len);

static
bool
dump_protocol_helper_generate_core_dump (
DiagnosticsIpcMessage *message,
DiagnosticsIpcStream *stream);

static
bool
dump_protocol_helper_unknown_command (
DiagnosticsIpcMessage *message,
DiagnosticsIpcStream *stream);

/*
* DiagnosticsGenerateCoreDumpCommandPayload
*/

static
uint8_t *
generate_core_dump_command_try_parse_payload (
uint8_t *buffer,
uint16_t buffer_len)
{
EP_ASSERT (buffer != NULL);

uint8_t * buffer_cursor = buffer;
uint32_t buffer_cursor_len = buffer_len;

DiagnosticsGenerateCoreDumpCommandPayload *instance = ds_generate_core_dump_command_payload_alloc ();
ep_raise_error_if_nok (instance != NULL);

instance->incoming_buffer = buffer;

if (!ds_ipc_message_try_parse_string_utf16_t (&buffer_cursor, &buffer_cursor_len, &instance->dump_name ) ||
!ds_ipc_message_try_parse_uint32_t (&buffer_cursor, &buffer_cursor_len, &instance->dump_type) ||
!ds_ipc_message_try_parse_uint32_t (&buffer_cursor, &buffer_cursor_len, &instance->diagnostics))
ep_raise_error ();

ep_on_exit:
return (uint8_t *)instance;

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

DiagnosticsGenerateCoreDumpCommandPayload *
ds_generate_core_dump_command_payload_alloc (void)
{
return ep_rt_object_alloc (DiagnosticsGenerateCoreDumpCommandPayload);
}

void
ds_dump_protocol_helper_handle_ipc_message (
ds_generate_core_dump_command_payload_free (DiagnosticsGenerateCoreDumpCommandPayload *payload)
{
ep_return_void_if_nok (payload != NULL);
ep_rt_byte_array_free (payload->incoming_buffer);
ep_rt_object_free (payload);
}

/*
* DiagnosticsDumpProtocolHelper.
*/

static
bool
dump_protocol_helper_unknown_command (
DiagnosticsIpcMessage *message,
DiagnosticsIpcStream *stream)
{
DS_LOG_WARNING_1 ("Received unknown request type (%d)\n", ds_ipc_header_get_commandset (ds_ipc_message_get_header_ref (message)));
ds_ipc_message_send_error (stream, DS_IPC_E_UNKNOWN_COMMAND);
ds_ipc_stream_free (stream);
return true;
}

static
bool
dump_protocol_helper_generate_core_dump (
DiagnosticsIpcMessage *message,
DiagnosticsIpcStream *stream)
{
EP_ASSERT (message != NULL);
EP_ASSERT (stream != NULL);

// TODO: Implement.
DS_LOG_WARNING_0 ("Generate Core Dump not implemented\n");
ds_ipc_message_send_error (stream, DS_IPC_E_NOTSUPPORTED);
if (!stream)
return false;

bool result = false;
DiagnosticsGenerateCoreDumpCommandPayload *payload;
payload = (DiagnosticsGenerateCoreDumpCommandPayload *)ds_ipc_message_try_parse_payload (message, generate_core_dump_command_try_parse_payload);

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

ds_ipc_result_t ipc_result;
ipc_result = ds_rt_generate_core_dump (payload);
if (result != DS_IPC_S_OK) {
ds_ipc_message_send_error (stream, result);
ep_raise_error ();
} else {
ds_ipc_message_send_success (stream, result);
}

result = true;

ep_on_exit:
ds_generate_core_dump_command_payload_free (payload);
ds_ipc_stream_free (stream);
return result;

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

bool
ds_dump_protocol_helper_handle_ipc_message (
DiagnosticsIpcMessage *message,
DiagnosticsIpcStream *stream)
{
EP_ASSERT (message != NULL);
EP_ASSERT (stream != NULL);

bool result = false;

switch ((DiagnosticsDumpCommandId)ds_ipc_header_get_commandid (ds_ipc_message_get_header_ref (message))) {
case DS_DUMP_COMMANDID_GENERATE_CORE_DUMP:
result = dump_protocol_helper_generate_core_dump (message, stream);
break;
default:
result = dump_protocol_helper_unknown_command (message, stream);
break;
}
return result;
}

#endif /* !defined(DS_INCLUDE_SOURCE_FILES) || defined(DS_FORCE_INCLUDE_SOURCE_FILES) */
Expand Down
41 changes: 40 additions & 1 deletion src/mono/mono/eventpipe/ds-dump-protocol.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,50 @@
#endif
#include "ds-getter-setter.h"

/*
* DiagnosticsGenerateCoreDumpCommandPayload
*/

#if defined(DS_INLINE_GETTER_SETTER) || defined(DS_IMPL_DUMP_PROTOCOL_GETTER_SETTER)
struct _DiagnosticsGenerateCoreDumpCommandPayload {
#else
struct _DiagnosticsGenerateCoreDumpCommandPayload_Internal {
#endif
uint8_t * incoming_buffer;

// The protocol buffer is defined as:
// string - dumpName (UTF16)
// int - dumpType
// int - diagnostics
// returns
// ulong - status

const ep_char16_t *dump_name;
uint32_t dump_type;
uint32_t diagnostics;
};

#if !defined(DS_INLINE_GETTER_SETTER) && !defined(DS_IMPL_DUMP_PROTOCOL_GETTER_SETTER)
struct _DiagnosticsGenerateCoreDumpCommandPayload {
uint8_t _internal [sizeof (struct _DiagnosticsGenerateCoreDumpCommandPayload_Internal)];
};
#endif

DS_DEFINE_GETTER(DiagnosticsGenerateCoreDumpCommandPayload *, generate_core_dump_command_payload, const ep_char16_t *, dump_name)
DS_DEFINE_GETTER(DiagnosticsGenerateCoreDumpCommandPayload *, generate_core_dump_command_payload, uint32_t, dump_type)
DS_DEFINE_GETTER(DiagnosticsGenerateCoreDumpCommandPayload *, generate_core_dump_command_payload, uint32_t, diagnostics)

DiagnosticsGenerateCoreDumpCommandPayload *
ds_generate_core_dump_command_payload_alloc (void);

void
ds_generate_core_dump_command_payload_free (DiagnosticsGenerateCoreDumpCommandPayload *payload);

/*
* DiagnosticsDumpProtocolHelper.
*/

void
bool
ds_dump_protocol_helper_handle_ipc_message (
DiagnosticsIpcMessage *message,
DiagnosticsIpcStream *stream);
Expand Down
Loading

0 comments on commit f6bfec0

Please sign in to comment.