From: Justin Anderson Date: Wed, 14 Jun 2023 03:02:38 +0000 (-0700) Subject: ApplyStartupHook diagnostic IPC command (#3918) X-Git-Tag: accepted/tizen/unified/riscv/20231226.055542~38^2^2~176 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=d3fae1c9cf49ae50e06f9a19db5ae48d3688fdea;p=platform%2Fcore%2Fdotnet%2Fdiagnostics.git ApplyStartupHook diagnostic IPC command (#3918) --- diff --git a/documentation/design-docs/ipc-protocol.md b/documentation/design-docs/ipc-protocol.md index 24fb0e5ec..3777067e0 100644 --- a/documentation/design-docs/ipc-protocol.md +++ b/documentation/design-docs/ipc-protocol.md @@ -380,6 +380,7 @@ enum class ProcessCommandId : uint8_t ResumeRuntime = 0x01, ProcessEnvironment = 0x02, ProcessInfo2 = 0x04, + ApplyStartupHook = 0x07 // future } ``` @@ -845,6 +846,47 @@ struct Payload } ``` +### `ApplyStartupHook` + +Command Code: `0x0407` + +The `ApplyStartupHook` command is used to provide a path to a managed assembly with a [startup hook](https://github.com/dotnet/runtime/blob/main/docs/design/features/host-startup-hook.md) to the runtime. During diagnostic suspension, the startup hook path will be added list of hooks that the runtime will execute once it has been resumed. + +In the event of an [error](#Errors), the runtime will attempt to send an error message and subsequently close the connection. + +#### Inputs: + +Header: `{ Magic; Size; 0x0407; 0x0000 }` + +* `string startupHookPath`: The path to the managed assembly that contains the startup hook implementation. + +#### Returns (as an IPC Message Payload): + +Header: `{ Magic; size; 0xFF00; 0x0000; }` + +`ApplyStartupHook` returns: +* `int32 hresult`: The result of adding the startup hook (`0` indicates success) + +##### Details: + +Input: +``` +Payload +{ + string startupHookPath +} +``` + +Returns: +```c++ +struct Payload +{ + int32 hresult +} +``` + +> Available since .NET 8.0 + ## Errors In the event an error occurs in the handling of an Ipc Message, the Diagnostic Server will attempt to send an Ipc Message encoding the error and subsequently close the connection. The connection will be closed **regardless** of the success of sending the error message. The Client is expected to be resilient in the event of a connection being abruptly closed. diff --git a/src/Microsoft.Diagnostics.NETCore.Client/DiagnosticsClient/DiagnosticsClient.cs b/src/Microsoft.Diagnostics.NETCore.Client/DiagnosticsClient/DiagnosticsClient.cs index 8a9886629..2a7fe61cd 100644 --- a/src/Microsoft.Diagnostics.NETCore.Client/DiagnosticsClient/DiagnosticsClient.cs +++ b/src/Microsoft.Diagnostics.NETCore.Client/DiagnosticsClient/DiagnosticsClient.cs @@ -298,6 +298,20 @@ namespace Microsoft.Diagnostics.NETCore.Client return await helper.ReadEnvironmentAsync(response.Continuation, token).ConfigureAwait(false); } + internal void ApplyStartupHook(string startupHookPath) + { + IpcMessage message = CreateApplyStartupHookMessage(startupHookPath); + IpcMessage response = IpcClient.SendMessage(_endpoint, message); + ValidateResponseMessage(response, nameof(ApplyStartupHook)); + } + + internal async Task ApplyStartupHookAsync(string startupHookPath, CancellationToken token) + { + IpcMessage message = CreateApplyStartupHookMessage(startupHookPath); + IpcMessage response = await IpcClient.SendMessageAsync(_endpoint, message, token).ConfigureAwait(false); + ValidateResponseMessage(response, nameof(ApplyStartupHookAsync)); + } + /// /// Get all the active processes that can be attached to. /// @@ -576,6 +590,18 @@ namespace Microsoft.Diagnostics.NETCore.Client return new IpcMessage(DiagnosticsServerCommandSet.Dump, (byte)command, payload); } + private static IpcMessage CreateApplyStartupHookMessage(string startupHookPath) + { + if (string.IsNullOrEmpty(startupHookPath)) + { + throw new ArgumentException($"{nameof(startupHookPath)} required"); + } + + byte[] serializedConfiguration = SerializePayload(startupHookPath); + + return new IpcMessage(DiagnosticsServerCommandSet.Process, (byte)ProcessCommandId.ApplyStartupHook, serializedConfiguration); + } + private static ProcessInfo GetProcessInfoFromResponse(IpcResponse response, string operationName) { ValidateResponseMessage(response.Message, operationName); diff --git a/src/Microsoft.Diagnostics.NETCore.Client/DiagnosticsIpc/IpcCommands.cs b/src/Microsoft.Diagnostics.NETCore.Client/DiagnosticsIpc/IpcCommands.cs index da251b775..1a7d96792 100644 --- a/src/Microsoft.Diagnostics.NETCore.Client/DiagnosticsIpc/IpcCommands.cs +++ b/src/Microsoft.Diagnostics.NETCore.Client/DiagnosticsIpc/IpcCommands.cs @@ -46,6 +46,7 @@ namespace Microsoft.Diagnostics.NETCore.Client ResumeRuntime = 0x01, GetProcessEnvironment = 0x02, SetEnvironmentVariable = 0x03, - GetProcessInfo2 = 0x04 + GetProcessInfo2 = 0x04, + ApplyStartupHook = 0x07 } }