Skip to content

Commit d3fae1c

Browse files
authored
ApplyStartupHook diagnostic IPC command (#3918)
1 parent 8270ad4 commit d3fae1c

File tree

3 files changed

+70
-1
lines changed

3 files changed

+70
-1
lines changed

documentation/design-docs/ipc-protocol.md

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -380,6 +380,7 @@ enum class ProcessCommandId : uint8_t
380380
ResumeRuntime = 0x01,
381381
ProcessEnvironment = 0x02,
382382
ProcessInfo2 = 0x04,
383+
ApplyStartupHook = 0x07
383384
// future
384385
}
385386
```
@@ -845,6 +846,47 @@ struct Payload
845846
}
846847
```
847848
849+
### `ApplyStartupHook`
850+
851+
Command Code: `0x0407`
852+
853+
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.
854+
855+
In the event of an [error](#Errors), the runtime will attempt to send an error message and subsequently close the connection.
856+
857+
#### Inputs:
858+
859+
Header: `{ Magic; Size; 0x0407; 0x0000 }`
860+
861+
* `string startupHookPath`: The path to the managed assembly that contains the startup hook implementation.
862+
863+
#### Returns (as an IPC Message Payload):
864+
865+
Header: `{ Magic; size; 0xFF00; 0x0000; }`
866+
867+
`ApplyStartupHook` returns:
868+
* `int32 hresult`: The result of adding the startup hook (`0` indicates success)
869+
870+
##### Details:
871+
872+
Input:
873+
```
874+
Payload
875+
{
876+
string startupHookPath
877+
}
878+
```
879+
880+
Returns:
881+
```c++
882+
struct Payload
883+
{
884+
int32 hresult
885+
}
886+
```
887+
888+
> Available since .NET 8.0
889+
848890
## Errors
849891

850892
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.

src/Microsoft.Diagnostics.NETCore.Client/DiagnosticsClient/DiagnosticsClient.cs

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -298,6 +298,20 @@ internal async Task<Dictionary<string, string>> GetProcessEnvironmentAsync(Cance
298298
return await helper.ReadEnvironmentAsync(response.Continuation, token).ConfigureAwait(false);
299299
}
300300

301+
internal void ApplyStartupHook(string startupHookPath)
302+
{
303+
IpcMessage message = CreateApplyStartupHookMessage(startupHookPath);
304+
IpcMessage response = IpcClient.SendMessage(_endpoint, message);
305+
ValidateResponseMessage(response, nameof(ApplyStartupHook));
306+
}
307+
308+
internal async Task ApplyStartupHookAsync(string startupHookPath, CancellationToken token)
309+
{
310+
IpcMessage message = CreateApplyStartupHookMessage(startupHookPath);
311+
IpcMessage response = await IpcClient.SendMessageAsync(_endpoint, message, token).ConfigureAwait(false);
312+
ValidateResponseMessage(response, nameof(ApplyStartupHookAsync));
313+
}
314+
301315
/// <summary>
302316
/// Get all the active processes that can be attached to.
303317
/// </summary>
@@ -576,6 +590,18 @@ private static IpcMessage CreateWriteDumpMessage(DumpCommandId command, DumpType
576590
return new IpcMessage(DiagnosticsServerCommandSet.Dump, (byte)command, payload);
577591
}
578592

593+
private static IpcMessage CreateApplyStartupHookMessage(string startupHookPath)
594+
{
595+
if (string.IsNullOrEmpty(startupHookPath))
596+
{
597+
throw new ArgumentException($"{nameof(startupHookPath)} required");
598+
}
599+
600+
byte[] serializedConfiguration = SerializePayload(startupHookPath);
601+
602+
return new IpcMessage(DiagnosticsServerCommandSet.Process, (byte)ProcessCommandId.ApplyStartupHook, serializedConfiguration);
603+
}
604+
579605
private static ProcessInfo GetProcessInfoFromResponse(IpcResponse response, string operationName)
580606
{
581607
ValidateResponseMessage(response.Message, operationName);

src/Microsoft.Diagnostics.NETCore.Client/DiagnosticsIpc/IpcCommands.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ internal enum ProcessCommandId : byte
4646
ResumeRuntime = 0x01,
4747
GetProcessEnvironment = 0x02,
4848
SetEnvironmentVariable = 0x03,
49-
GetProcessInfo2 = 0x04
49+
GetProcessInfo2 = 0x04,
50+
ApplyStartupHook = 0x07
5051
}
5152
}

0 commit comments

Comments
 (0)