From: David Mason Date: Thu, 16 May 2019 22:12:40 +0000 (-0700) Subject: add profiler attach message X-Git-Tag: submit/tizen/20190813.035844~6^2^2~23^2~2 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=272054df65c393df55fde31c7074f4bc8171848f;p=platform%2Fcore%2Fdotnet%2Fdiagnostics.git add profiler attach message --- diff --git a/src/Microsoft.Diagnostics.Tools.RuntimeClient/DiagnosticHelpers.cs b/src/Microsoft.Diagnostics.Tools.RuntimeClient/DiagnosticHelpers.cs index 1ebaeeea6..101696f28 100644 --- a/src/Microsoft.Diagnostics.Tools.RuntimeClient/DiagnosticHelpers.cs +++ b/src/Microsoft.Diagnostics.Tools.RuntimeClient/DiagnosticHelpers.cs @@ -45,12 +45,78 @@ namespace Microsoft.Diagnostics.Tools.RuntimeClient byte[] serializedConfiguration; using (var stream = new MemoryStream()) - serializedConfiguration = Serialize(header, stream, dumpName, dumpType, diagnostics); + serializedConfiguration = SerializeCoreDump(header, stream, dumpName, dumpType, diagnostics); return (int)EventPipeClient.SendCommand(processId, serializedConfiguration); } - private static byte[] Serialize(MessageHeader header, Stream stream, string dumpName, DumpType dumpType, bool diagnostics) + /// + /// Attach a profiler to the target process runtime. + /// + /// .NET Core process id + /// The timeout (in ms) to wait while attempting to attach. + /// CLSID of the profiler to load + /// Path to the profiler library on disk + /// additional data to pass to the profiler on attach + /// HRESULT + public static int AttachProfiler(int processId, uint attachTimeout, Guid profilerGuid, string profilerPath, byte[] additionalData) + { + if (profilerGuid == null || profilerGuid == Guid.Empty) + { + throw new ArgumentException($"{nameof(profilerGuid)} must be a valid Guid"); + } + + if (String.IsNullOrEmpty(profilerPath)) + { + throw new ArgumentException($"{nameof(profilerPath)} must be non-null"); + } + + var header = new MessageHeader { + RequestType = DiagnosticMessageType.AttachProfiler, + Pid = (uint)Process.GetCurrentProcess().Id, + }; + + byte[] serializedConfiguration; + using (var stream = new MemoryStream()) + { + serializedConfiguration = SerializeProfilerAttach(header, stream, attachTimeout, profilerGuid, profilerPath, additionalData); + } + + return (int)EventPipeClient.SendCommand(processId, serializedConfiguration); + + } + + private static byte[] SerializeProfilerAttach(MessageHeader header, MemoryStream stream, uint attachTimeout, Guid profilerGuid, string profilerPath, byte[] additionalData) + { + using (var bw = new BinaryWriter(stream)) + { + bw.Write((uint)header.RequestType); + bw.Write(header.Pid); + + bw.Write(attachTimeout); + bw.Write(profilerGuid.ToByteArray()); + bw.WriteString(profilerPath); + + if (additionalData == null) + { + bw.Write(0); + } + else + { + bw.Write(additionalData.Length); + bw.Write(additionalData); + } + + bw.Flush(); + stream.Position = 0; + + var bytes = new byte[stream.Length]; + stream.Read(bytes, 0, bytes.Length); + return bytes; + } + } + + private static byte[] SerializeCoreDump(MessageHeader header, Stream stream, string dumpName, DumpType dumpType, bool diagnostics) { using (var bw = new BinaryWriter(stream)) { diff --git a/src/Microsoft.Diagnostics.Tools.RuntimeClient/Eventing/DiagnosticMessageType.cs b/src/Microsoft.Diagnostics.Tools.RuntimeClient/Eventing/DiagnosticMessageType.cs index 8693f5e69..2bce8154b 100644 --- a/src/Microsoft.Diagnostics.Tools.RuntimeClient/Eventing/DiagnosticMessageType.cs +++ b/src/Microsoft.Diagnostics.Tools.RuntimeClient/Eventing/DiagnosticMessageType.cs @@ -14,6 +14,10 @@ namespace Microsoft.Diagnostics.Tools.RuntimeClient /// GenerateCoreDump = 1, /// + /// Attaches a profiler to an existing process + /// + AttachProfiler, + /// /// Starts an EventPipe session that writes events to a file when the session is stopped or the application exits. /// StartEventPipeTracing = 1024,