From 0b3c2c6bc3f6b6960c9c8bfd9cd75af766d6ca2f Mon Sep 17 00:00:00 2001 From: Sung Yoon Whang Date: Thu, 26 Dec 2019 12:15:43 -0800 Subject: [PATCH] Remove legacy RuntimeClient library (#722) --- diagnostics.sln | 45 +-- .../DiagnosticsHelpers.cs | 149 -------- .../DiagnosticsIpc/IpcClient.cs | 112 ------ .../DiagnosticsIpc/IpcCommands.cs | 42 -- .../DiagnosticsIpc/IpcHeader.cs | 77 ---- .../DiagnosticsIpc/IpcMessage.cs | 62 --- .../Eventing/DiagnosticsMessageType.cs | 33 -- .../Eventing/EventPipeClient.cs | 167 -------- .../Eventing/EventPipeSessionType.cs | 27 -- .../Eventing/MessageHeader.cs | 25 -- .../Eventing/Provider.cs | 75 ---- .../Eventing/SessionConfiguration.cs | 107 ------ .../Extensions.cs | 53 --- ...oft.Diagnostics.Tools.RuntimeClient.csproj | 14 - .../Assert.cs | 53 --- .../Program.cs | 359 ------------------ .../TestProvider.cs | 19 - .../TestSessionConfiguration.cs | 17 - .../Workload.cs | 57 --- .../eventpipetests.csproj | 17 - 20 files changed, 1 insertion(+), 1509 deletions(-) delete mode 100644 src/Microsoft.Diagnostics.Tools.RuntimeClient/DiagnosticsHelpers.cs delete mode 100644 src/Microsoft.Diagnostics.Tools.RuntimeClient/DiagnosticsIpc/IpcClient.cs delete mode 100644 src/Microsoft.Diagnostics.Tools.RuntimeClient/DiagnosticsIpc/IpcCommands.cs delete mode 100644 src/Microsoft.Diagnostics.Tools.RuntimeClient/DiagnosticsIpc/IpcHeader.cs delete mode 100644 src/Microsoft.Diagnostics.Tools.RuntimeClient/DiagnosticsIpc/IpcMessage.cs delete mode 100644 src/Microsoft.Diagnostics.Tools.RuntimeClient/Eventing/DiagnosticsMessageType.cs delete mode 100644 src/Microsoft.Diagnostics.Tools.RuntimeClient/Eventing/EventPipeClient.cs delete mode 100644 src/Microsoft.Diagnostics.Tools.RuntimeClient/Eventing/EventPipeSessionType.cs delete mode 100644 src/Microsoft.Diagnostics.Tools.RuntimeClient/Eventing/MessageHeader.cs delete mode 100644 src/Microsoft.Diagnostics.Tools.RuntimeClient/Eventing/Provider.cs delete mode 100644 src/Microsoft.Diagnostics.Tools.RuntimeClient/Eventing/SessionConfiguration.cs delete mode 100644 src/Microsoft.Diagnostics.Tools.RuntimeClient/Extensions.cs delete mode 100644 src/Microsoft.Diagnostics.Tools.RuntimeClient/Microsoft.Diagnostics.Tools.RuntimeClient.csproj delete mode 100644 src/tests/Microsoft.Diagnostics.Tools.RuntimeClient/Assert.cs delete mode 100644 src/tests/Microsoft.Diagnostics.Tools.RuntimeClient/Program.cs delete mode 100644 src/tests/Microsoft.Diagnostics.Tools.RuntimeClient/TestProvider.cs delete mode 100644 src/tests/Microsoft.Diagnostics.Tools.RuntimeClient/TestSessionConfiguration.cs delete mode 100644 src/tests/Microsoft.Diagnostics.Tools.RuntimeClient/Workload.cs delete mode 100644 src/tests/Microsoft.Diagnostics.Tools.RuntimeClient/eventpipetests.csproj diff --git a/diagnostics.sln b/diagnostics.sln index 1ba3fc9c4..5f400e0e9 100644 --- a/diagnostics.sln +++ b/diagnostics.sln @@ -39,8 +39,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Diagnostics.Repl" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "dotnet-counters", "src\Tools\dotnet-counters\dotnet-counters.csproj", "{2A9B5988-982F-4E26-9E44-D38AC5978C30}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Diagnostics.Tools.RuntimeClient", "src\Microsoft.Diagnostics.Tools.RuntimeClient\Microsoft.Diagnostics.Tools.RuntimeClient.csproj", "{54C240C5-7932-4421-A5FB-75205DE0B824}" -EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SOS.Package", "src\SOS\SOS.Package\SOS.Package.csproj", "{234416E9-EA5F-4018-AC34-67682C5D3E04}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Diagnostics.DebugServices", "src\Microsoft.Diagnostics.DebugServices\Microsoft.Diagnostics.DebugServices.csproj", "{A1CE682A-12C4-4FF9-B864-A9A15A8726D2}" @@ -59,7 +57,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Diagnostics.NETCo EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Diagnostics.NETCore.Client.UnitTests", "src\tests\Microsoft.Diagnostics.NETCore.Client\Microsoft.Diagnostics.NETCore.Client.UnitTests.csproj", "{6F4DD2F8-1C7B-4A87-B7E5-1BEE9F5AC128}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tracee", "src\tests\Tracee\Tracee.csproj", "{C79D6069-2C18-48CB-846E-71F7168C2F7D}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Tracee", "src\tests\Tracee\Tracee.csproj", "{C79D6069-2C18-48CB-846E-71F7168C2F7D}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EventPipe.UnitTests", "src\tests\eventpipe\EventPipe.UnitTests.csproj", "{CED9ABBA-861E-4C0A-9359-22351208EF27}" EndProject @@ -626,46 +624,6 @@ Global {2A9B5988-982F-4E26-9E44-D38AC5978C30}.RelWithDebInfo|x64.Build.0 = Release|Any CPU {2A9B5988-982F-4E26-9E44-D38AC5978C30}.RelWithDebInfo|x86.ActiveCfg = Release|Any CPU {2A9B5988-982F-4E26-9E44-D38AC5978C30}.RelWithDebInfo|x86.Build.0 = Release|Any CPU - {54C240C5-7932-4421-A5FB-75205DE0B824}.Checked|Any CPU.ActiveCfg = Debug|Any CPU - {54C240C5-7932-4421-A5FB-75205DE0B824}.Checked|Any CPU.Build.0 = Debug|Any CPU - {54C240C5-7932-4421-A5FB-75205DE0B824}.Checked|ARM.ActiveCfg = Debug|Any CPU - {54C240C5-7932-4421-A5FB-75205DE0B824}.Checked|ARM.Build.0 = Debug|Any CPU - {54C240C5-7932-4421-A5FB-75205DE0B824}.Checked|ARM64.ActiveCfg = Debug|Any CPU - {54C240C5-7932-4421-A5FB-75205DE0B824}.Checked|ARM64.Build.0 = Debug|Any CPU - {54C240C5-7932-4421-A5FB-75205DE0B824}.Checked|x64.ActiveCfg = Debug|Any CPU - {54C240C5-7932-4421-A5FB-75205DE0B824}.Checked|x64.Build.0 = Debug|Any CPU - {54C240C5-7932-4421-A5FB-75205DE0B824}.Checked|x86.ActiveCfg = Debug|Any CPU - {54C240C5-7932-4421-A5FB-75205DE0B824}.Checked|x86.Build.0 = Debug|Any CPU - {54C240C5-7932-4421-A5FB-75205DE0B824}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {54C240C5-7932-4421-A5FB-75205DE0B824}.Debug|Any CPU.Build.0 = Debug|Any CPU - {54C240C5-7932-4421-A5FB-75205DE0B824}.Debug|ARM.ActiveCfg = Debug|Any CPU - {54C240C5-7932-4421-A5FB-75205DE0B824}.Debug|ARM.Build.0 = Debug|Any CPU - {54C240C5-7932-4421-A5FB-75205DE0B824}.Debug|ARM64.ActiveCfg = Debug|Any CPU - {54C240C5-7932-4421-A5FB-75205DE0B824}.Debug|ARM64.Build.0 = Debug|Any CPU - {54C240C5-7932-4421-A5FB-75205DE0B824}.Debug|x64.ActiveCfg = Debug|Any CPU - {54C240C5-7932-4421-A5FB-75205DE0B824}.Debug|x64.Build.0 = Debug|Any CPU - {54C240C5-7932-4421-A5FB-75205DE0B824}.Debug|x86.ActiveCfg = Debug|Any CPU - {54C240C5-7932-4421-A5FB-75205DE0B824}.Debug|x86.Build.0 = Debug|Any CPU - {54C240C5-7932-4421-A5FB-75205DE0B824}.Release|Any CPU.ActiveCfg = Release|Any CPU - {54C240C5-7932-4421-A5FB-75205DE0B824}.Release|Any CPU.Build.0 = Release|Any CPU - {54C240C5-7932-4421-A5FB-75205DE0B824}.Release|ARM.ActiveCfg = Release|Any CPU - {54C240C5-7932-4421-A5FB-75205DE0B824}.Release|ARM.Build.0 = Release|Any CPU - {54C240C5-7932-4421-A5FB-75205DE0B824}.Release|ARM64.ActiveCfg = Release|Any CPU - {54C240C5-7932-4421-A5FB-75205DE0B824}.Release|ARM64.Build.0 = Release|Any CPU - {54C240C5-7932-4421-A5FB-75205DE0B824}.Release|x64.ActiveCfg = Release|Any CPU - {54C240C5-7932-4421-A5FB-75205DE0B824}.Release|x64.Build.0 = Release|Any CPU - {54C240C5-7932-4421-A5FB-75205DE0B824}.Release|x86.ActiveCfg = Release|Any CPU - {54C240C5-7932-4421-A5FB-75205DE0B824}.Release|x86.Build.0 = Release|Any CPU - {54C240C5-7932-4421-A5FB-75205DE0B824}.RelWithDebInfo|Any CPU.ActiveCfg = Release|Any CPU - {54C240C5-7932-4421-A5FB-75205DE0B824}.RelWithDebInfo|Any CPU.Build.0 = Release|Any CPU - {54C240C5-7932-4421-A5FB-75205DE0B824}.RelWithDebInfo|ARM.ActiveCfg = Release|Any CPU - {54C240C5-7932-4421-A5FB-75205DE0B824}.RelWithDebInfo|ARM.Build.0 = Release|Any CPU - {54C240C5-7932-4421-A5FB-75205DE0B824}.RelWithDebInfo|ARM64.ActiveCfg = Release|Any CPU - {54C240C5-7932-4421-A5FB-75205DE0B824}.RelWithDebInfo|ARM64.Build.0 = Release|Any CPU - {54C240C5-7932-4421-A5FB-75205DE0B824}.RelWithDebInfo|x64.ActiveCfg = Release|Any CPU - {54C240C5-7932-4421-A5FB-75205DE0B824}.RelWithDebInfo|x64.Build.0 = Release|Any CPU - {54C240C5-7932-4421-A5FB-75205DE0B824}.RelWithDebInfo|x86.ActiveCfg = Release|Any CPU - {54C240C5-7932-4421-A5FB-75205DE0B824}.RelWithDebInfo|x86.Build.0 = Release|Any CPU {234416E9-EA5F-4018-AC34-67682C5D3E04}.Checked|Any CPU.ActiveCfg = Debug|Any CPU {234416E9-EA5F-4018-AC34-67682C5D3E04}.Checked|Any CPU.Build.0 = Debug|Any CPU {234416E9-EA5F-4018-AC34-67682C5D3E04}.Checked|ARM.ActiveCfg = Debug|Any CPU @@ -1088,7 +1046,6 @@ Global {ED27F39F-DF5C-4E22-87E0-EC5B5873B503} = {41638A4C-0DAF-47ED-A774-ECBBAC0315D7} {90CF2633-58F0-44EE-943B-D70207455F20} = {19FAB78C-3351-4911-8F0C-8C6056401740} {2A9B5988-982F-4E26-9E44-D38AC5978C30} = {B62728C8-1267-4043-B46F-5537BBAEC692} - {54C240C5-7932-4421-A5FB-75205DE0B824} = {19FAB78C-3351-4911-8F0C-8C6056401740} {234416E9-EA5F-4018-AC34-67682C5D3E04} = {41638A4C-0DAF-47ED-A774-ECBBAC0315D7} {A1CE682A-12C4-4FF9-B864-A9A15A8726D2} = {19FAB78C-3351-4911-8F0C-8C6056401740} {410394E0-7F4F-42D5-B5FA-30956F44ACBC} = {41638A4C-0DAF-47ED-A774-ECBBAC0315D7} diff --git a/src/Microsoft.Diagnostics.Tools.RuntimeClient/DiagnosticsHelpers.cs b/src/Microsoft.Diagnostics.Tools.RuntimeClient/DiagnosticsHelpers.cs deleted file mode 100644 index 70c6c0187..000000000 --- a/src/Microsoft.Diagnostics.Tools.RuntimeClient/DiagnosticsHelpers.cs +++ /dev/null @@ -1,149 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using Microsoft.Diagnostics.Tools.RuntimeClient.DiagnosticsIpc; -using System; -using System.Diagnostics; -using System.IO; -using System.Runtime.InteropServices; - -namespace Microsoft.Diagnostics.Tools.RuntimeClient -{ - public static class DiagnosticsHelpers - { - /// - /// Controls the contents of the dump - /// - public enum DumpType : uint - { - Normal = 1, - WithHeap = 2, - Triage = 3, - Full = 4 - } - - /// - /// Initiate a core dump in the target process runtime. - /// - /// .NET Core process id - /// Path and file name of core dump - /// Type of dump - /// If true, log to console the dump generation diagnostics - /// DiagnosticsServerErrorCode - public static int GenerateCoreDump(int processId, string dumpName, DumpType dumpType, bool diagnostics) - { - if (!RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) - throw new PlatformNotSupportedException($"Unsupported operating system: {RuntimeInformation.OSDescription}"); - - if (string.IsNullOrEmpty(dumpName)) - throw new ArgumentNullException($"{nameof(dumpName)} required"); - - - var payload = SerializeCoreDump(dumpName, dumpType, diagnostics); - var message = new IpcMessage(DiagnosticsServerCommandSet.Dump, (byte)DumpCommandId.GenerateCoreDump, payload); - - var response = IpcClient.SendMessage(processId, message); - - var hr = 0; - switch ((DiagnosticsServerCommandId)response.Header.CommandId) - { - case DiagnosticsServerCommandId.Error: - case DiagnosticsServerCommandId.OK: - hr = BitConverter.ToInt32(response.Payload, 0); - break; - default: - return -1; - } - - return hr; - } - - /// - /// Attach a profiler to the target process runtime. - /// - /// .NET Core process id - /// The timeout (in ms) for the runtime 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 = DiagnosticsMessageType.AttachProfiler, - Pid = (uint)Process.GetCurrentProcess().Id, - }; - - byte[] serializedConfiguration = SerializeProfilerAttach(attachTimeout, profilerGuid, profilerPath, additionalData); - var message = new IpcMessage(DiagnosticsServerCommandSet.Profiler, (byte)ProfilerCommandId.AttachProfiler, serializedConfiguration); - - var response = IpcClient.SendMessage(processId, message); - - var hr = 0; - switch ((DiagnosticsServerCommandId)response.Header.CommandId) - { - case DiagnosticsServerCommandId.Error: - case DiagnosticsServerCommandId.OK: - hr = BitConverter.ToInt32(response.Payload, 0); - break; - default: - hr = -1; - break; - } - - // TODO: the call to set up the pipe and send the message operates on a different timeout than attachTimeout, which is for the runtime. - // We should eventually have a configurable timeout for the message passing, potentially either separately from the - // runtime timeout or respect attachTimeout as one total duration. - return hr; - } - - private static byte[] SerializeProfilerAttach(uint attachTimeout, Guid profilerGuid, string profilerPath, byte[] additionalData) - { - using (var stream = new MemoryStream()) - using (var writer = new BinaryWriter(stream)) - { - writer.Write(attachTimeout); - writer.Write(profilerGuid.ToByteArray()); - writer.WriteString(profilerPath); - - if (additionalData == null) - { - writer.Write(0); - } - else - { - writer.Write(additionalData.Length); - writer.Write(additionalData); - } - - writer.Flush(); - return stream.ToArray(); - } - } - - private static byte[] SerializeCoreDump(string dumpName, DumpType dumpType, bool diagnostics) - { - using (var stream = new MemoryStream()) - using (var writer = new BinaryWriter(stream)) - { - writer.WriteString(dumpName); - writer.Write((uint)dumpType); - writer.Write((uint)(diagnostics ? 1 : 0)); - - writer.Flush(); - return stream.ToArray(); - } - } - } -} diff --git a/src/Microsoft.Diagnostics.Tools.RuntimeClient/DiagnosticsIpc/IpcClient.cs b/src/Microsoft.Diagnostics.Tools.RuntimeClient/DiagnosticsIpc/IpcClient.cs deleted file mode 100644 index 7897f0539..000000000 --- a/src/Microsoft.Diagnostics.Tools.RuntimeClient/DiagnosticsIpc/IpcClient.cs +++ /dev/null @@ -1,112 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System; -using System.Collections.Generic; -using System.IO; -using System.IO.Pipes; -using System.Linq; -using System.Net.Sockets; -using System.Runtime.InteropServices; -using System.Security.Principal; -using System.Text; -using System.Text.RegularExpressions; - -namespace Microsoft.Diagnostics.Tools.RuntimeClient.DiagnosticsIpc -{ - public class IpcClient - { - private static string DiagnosticsPortPattern { get; } = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? @"^dotnet-diagnostic-(\d+)$" : @"^dotnet-diagnostic-(\d+)-(\d+)-socket$"; - - private static string IpcRootPath { get; } = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? @"\\.\pipe\" : Path.GetTempPath(); - - private static double ConnectTimeoutMilliseconds { get; } = TimeSpan.FromSeconds(3).TotalMilliseconds; - - /// - /// Get the OS Transport to be used for communicating with a dotnet process. - /// - /// The PID of the dotnet process to get the transport for - /// A System.IO.Stream wrapper around the transport - private static Stream GetTransport(int processId) - { - if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) - { - string pipeName = $"dotnet-diagnostic-{processId}"; - var namedPipe = new NamedPipeClientStream( - ".", pipeName, PipeDirection.InOut, PipeOptions.None, TokenImpersonationLevel.Impersonation); - namedPipe.Connect((int)ConnectTimeoutMilliseconds); - return namedPipe; - } - else - { - string ipcPort = Directory.GetFiles(IpcRootPath) // Try best match. - .Select(namedPipe => (new FileInfo(namedPipe)).Name) - .SingleOrDefault(input => Regex.IsMatch(input, $"^dotnet-diagnostic-{processId}-(\\d+)-socket$")); - if (ipcPort == null) - { - throw new PlatformNotSupportedException($"Process {processId} not running compatible .NET Core runtime"); - } - string path = Path.Combine(Path.GetTempPath(), ipcPort); - var remoteEP = new UnixDomainSocketEndPoint(path); - - var socket = new Socket(AddressFamily.Unix, SocketType.Stream, ProtocolType.Unspecified); - socket.Connect(remoteEP); - return new NetworkStream(socket); - } - } - - /// - /// Sends a single DiagnosticsIpc Message to the dotnet process with PID processId. - /// - /// The PID of the dotnet process - /// The DiagnosticsIpc Message to be sent - /// The response DiagnosticsIpc Message from the dotnet process - public static IpcMessage SendMessage(int processId, IpcMessage message) - { - using (var stream = GetTransport(processId)) - { - Write(stream, message); - return Read(stream); - } - } - - /// - /// Sends a single DiagnosticsIpc Message to the dotnet process with PID processId - /// and returns the Stream for reuse in Optional Continuations. - /// - /// The PID of the dotnet process - /// The DiagnosticsIpc Message to be sent - /// out var for response message - /// The response DiagnosticsIpc Message from the dotnet process - public static Stream SendMessage(int processId, IpcMessage message, out IpcMessage response) - { - var stream = GetTransport(processId); - Write(stream, message); - response = Read(stream); - return stream; - } - - private static void Write(Stream stream, byte[] buffer) - { - using (var writer = new BinaryWriter(stream, Encoding.UTF8, true)) - { - writer.Write(buffer); - } - } - - private static void Write(Stream stream, IpcMessage message) - { - using (var writer = new BinaryWriter(stream, Encoding.UTF8, true)) - { - writer.Write(message.Serialize()); - } - } - - - private static IpcMessage Read(Stream stream) - { - return IpcMessage.Parse(stream); - } - } -} diff --git a/src/Microsoft.Diagnostics.Tools.RuntimeClient/DiagnosticsIpc/IpcCommands.cs b/src/Microsoft.Diagnostics.Tools.RuntimeClient/DiagnosticsIpc/IpcCommands.cs deleted file mode 100644 index 8be8f0a3b..000000000 --- a/src/Microsoft.Diagnostics.Tools.RuntimeClient/DiagnosticsIpc/IpcCommands.cs +++ /dev/null @@ -1,42 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System; -using System.Collections.Generic; -using System.Text; - -namespace Microsoft.Diagnostics.Tools.RuntimeClient.DiagnosticsIpc -{ - public enum DiagnosticsServerCommandSet : byte - { - Dump = 0x01, - EventPipe = 0x02, - Profiler = 0x03, - - Server = 0xFF, - } - - public enum DiagnosticsServerCommandId : byte - { - OK = 0x00, - Error = 0xFF, - } - - public enum EventPipeCommandId : byte - { - StopTracing = 0x01, - CollectTracing = 0x02, - CollectTracing2 = 0x03, - } - - public enum DumpCommandId : byte - { - GenerateCoreDump = 0x01, - } - - public enum ProfilerCommandId : byte - { - AttachProfiler = 0x01, - } -} diff --git a/src/Microsoft.Diagnostics.Tools.RuntimeClient/DiagnosticsIpc/IpcHeader.cs b/src/Microsoft.Diagnostics.Tools.RuntimeClient/DiagnosticsIpc/IpcHeader.cs deleted file mode 100644 index 641c0e95d..000000000 --- a/src/Microsoft.Diagnostics.Tools.RuntimeClient/DiagnosticsIpc/IpcHeader.cs +++ /dev/null @@ -1,77 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.IO; -using System.Net.Sockets; -using System.Runtime.InteropServices; -using System.Text; - -namespace Microsoft.Diagnostics.Tools.RuntimeClient.DiagnosticsIpc -{ - public class IpcHeader - { - IpcHeader() { } - - public IpcHeader(DiagnosticsServerCommandSet commandSet, byte commandId) - { - CommandSet = (byte)commandSet; - CommandId = commandId; - } - - // the number of bytes for the DiagnosticsIpc::IpcHeader type in native code - public static readonly UInt16 HeaderSizeInBytes = 20; - private static readonly UInt16 MagicSizeInBytes = 14; - - public byte[] Magic = ASCIIEncoding.ASCII.GetBytes("DOTNET_IPC_V1" + '\0'); // byte[14] in native code - public UInt16 Size = HeaderSizeInBytes; - public byte CommandSet; - public byte CommandId; - public UInt16 Reserved = 0x0000; - - - // Helper expression to quickly get V1 magic string for comparison - // should be 14 bytes long - public static byte[] DOTNET_IPC_V1 => ASCIIEncoding.ASCII.GetBytes("DOTNET_IPC_V1" + '\0'); - - public byte[] Serialize() - { - using (var stream = new MemoryStream()) - using (var writer = new BinaryWriter(stream)) - { - writer.Write(Magic); - Debug.Assert(Magic.Length == MagicSizeInBytes); - writer.Write(Size); - writer.Write(CommandSet); - writer.Write(CommandId); - writer.Write((UInt16)0x0000); - writer.Flush(); - return stream.ToArray(); - } - } - - public static IpcHeader TryParse(BinaryReader reader) - { - IpcHeader header = new IpcHeader - { - Magic = reader.ReadBytes(14), - Size = reader.ReadUInt16(), - CommandSet = reader.ReadByte(), - CommandId = reader.ReadByte(), - Reserved = reader.ReadUInt16() - }; - - // TODO: Validate it is correct! - - return header; - } - - override public string ToString() - { - return $"{{ Magic={Magic}; Size={Size}; CommandSet={CommandSet}; CommandId={CommandId}; Reserved={Reserved} }}"; - } - } -} diff --git a/src/Microsoft.Diagnostics.Tools.RuntimeClient/DiagnosticsIpc/IpcMessage.cs b/src/Microsoft.Diagnostics.Tools.RuntimeClient/DiagnosticsIpc/IpcMessage.cs deleted file mode 100644 index dc73a5a22..000000000 --- a/src/Microsoft.Diagnostics.Tools.RuntimeClient/DiagnosticsIpc/IpcMessage.cs +++ /dev/null @@ -1,62 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System; -using System.Collections.Generic; -using System.IO; -using System.Text; - -namespace Microsoft.Diagnostics.Tools.RuntimeClient.DiagnosticsIpc -{ - public class IpcMessage - { - public IpcMessage() - { } - - public IpcMessage(IpcHeader header, byte[] payload) - { - Payload = payload; - Header = header; - } - - internal IpcMessage(DiagnosticsServerCommandSet commandSet, byte commandId, byte[] payload = null) - { - Header = new IpcHeader(commandSet, commandId); - Payload = payload; - } - - public byte[] Payload { get; private set; } = null; - public IpcHeader Header { get; private set; } = default; - - public byte[] Serialize() - { - byte[] serializedData = null; - // Verify things will fit in the size capacity - Header.Size = checked((UInt16)(IpcHeader.HeaderSizeInBytes + Payload.Length)); ; - byte[] headerBytes = Header.Serialize(); - - using (var stream = new MemoryStream()) - using (var writer = new BinaryWriter(stream)) - { - writer.Write(headerBytes); - writer.Write(Payload); - writer.Flush(); - serializedData = stream.ToArray(); - } - - return serializedData; - } - - public static IpcMessage Parse(Stream stream) - { - IpcMessage message = new IpcMessage(); - using (var reader = new BinaryReader(stream, Encoding.UTF8, true)) - { - message.Header = IpcHeader.TryParse(reader); - message.Payload = reader.ReadBytes(message.Header.Size - IpcHeader.HeaderSizeInBytes); - return message; - } - } - } -} diff --git a/src/Microsoft.Diagnostics.Tools.RuntimeClient/Eventing/DiagnosticsMessageType.cs b/src/Microsoft.Diagnostics.Tools.RuntimeClient/Eventing/DiagnosticsMessageType.cs deleted file mode 100644 index 883ea2118..000000000 --- a/src/Microsoft.Diagnostics.Tools.RuntimeClient/Eventing/DiagnosticsMessageType.cs +++ /dev/null @@ -1,33 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -namespace Microsoft.Diagnostics.Tools.RuntimeClient -{ - /// - /// Different diagnostic message types that are handled by the runtime. - /// - public enum DiagnosticsMessageType : uint - { - /// - /// Initiates core dump generation - /// - GenerateCoreDump = 1, - /// - /// Starts an EventPipe session that writes events to a file when the session is stopped or the application exits. - /// - StartEventPipeTracing = 1024, - /// - /// Stops an EventPipe session. - /// - StopEventPipeTracing, - /// - /// Starts an EventPipe session that sends events out-of-proc through IPC. - /// - CollectEventPipeTracing, - /// - /// Attaches a profiler to an existing process - /// - AttachProfiler = 2048, - } -} diff --git a/src/Microsoft.Diagnostics.Tools.RuntimeClient/Eventing/EventPipeClient.cs b/src/Microsoft.Diagnostics.Tools.RuntimeClient/Eventing/EventPipeClient.cs deleted file mode 100644 index 4c46c9bcd..000000000 --- a/src/Microsoft.Diagnostics.Tools.RuntimeClient/Eventing/EventPipeClient.cs +++ /dev/null @@ -1,167 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using Microsoft.Diagnostics.Tools.RuntimeClient.DiagnosticsIpc; -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Globalization; -using System.IO; -using System.IO.Pipes; -using System.Linq; -using System.Net.Sockets; -using System.Runtime.InteropServices; -using System.Security.Principal; -using System.Text; -using System.Text.RegularExpressions; - -namespace Microsoft.Diagnostics.Tools.RuntimeClient -{ - public enum EventPipeErrorCode : uint - { - BAD_ENCODING = 0x80131384, - UNKNOWN_COMMAND = 0x80131385, - UNKNOWN_MAGIC = 0x80131386, - UNKNOWN_ERROR = 0x80131387 - } - - public class EventPipeBadEncodingException : Exception - { - public EventPipeBadEncodingException(string msg) : base(msg) {} - } - public class EventPipeUnknownCommandException : Exception - { - public EventPipeUnknownCommandException(string msg) : base(msg) {} - } - - public class EventPipeUnknownMagicException : Exception - { - public EventPipeUnknownMagicException(string msg) : base(msg) {} - } - - public class EventPipeUnknownErrorException : Exception - { - public EventPipeUnknownErrorException(string msg) : base(msg) {} - } - - public static class EventPipeClient - { - private static string DiagnosticsPortPattern { get; } = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? @"^dotnet-diagnostic-(\d+)$" : @"^dotnet-diagnostic-(\d+)-(\d+)-socket$"; - - private static string IpcRootPath { get; } = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? @"\\.\pipe\" : Path.GetTempPath(); - - /// - /// Get the files associated with the opened IPC Ports for DotNet Core applications. - /// - /// - /// A collection of process identifiers associated with the list of opened files (IPC ports). - /// These process Ids might have expired and not properly cleaned up. - /// - public static IEnumerable ListAvailablePorts() - { - return Directory.GetFiles(IpcRootPath) - .Select(namedPipe => (new FileInfo(namedPipe)).Name) - .Where(input => Regex.IsMatch(input, DiagnosticsPortPattern)) - .Select(input => int.Parse(Regex.Match(input, DiagnosticsPortPattern).Groups[1].Value, NumberStyles.Integer)); - } - - /// - /// Start trace collection. - /// - /// Runtime process to trace - /// buffer size and provider configuration - /// session id - /// Stream - public static Stream CollectTracing(int processId, SessionConfiguration configuration, out ulong sessionId) - { - sessionId = 0; - var message = new IpcMessage(DiagnosticsServerCommandSet.EventPipe, (byte)EventPipeCommandId.CollectTracing, configuration.Serialize()); - var stream = IpcClient.SendMessage(processId, message, out var response); - - switch ((DiagnosticsServerCommandId)response.Header.CommandId) - { - case DiagnosticsServerCommandId.OK: - sessionId = BitConverter.ToUInt64(response.Payload, 0); - break; - case DiagnosticsServerCommandId.Error: - // bad... - var hr = BitConverter.ToInt32(response.Payload, 0); - throw new Exception($"Session start FAILED 0x{hr:X8}"); - default: - break; - } - - return stream; - } - - public static Stream CollectTracing2(int processId, SessionConfigurationV2 configuration, out ulong sessionId) - { - sessionId = 0; - var message = new IpcMessage(DiagnosticsServerCommandSet.EventPipe, (byte)EventPipeCommandId.CollectTracing2, configuration.Serialize()); - var stream = IpcClient.SendMessage(processId, message, out var response); - - switch ((DiagnosticsServerCommandId)response.Header.CommandId) - { - case DiagnosticsServerCommandId.OK: - sessionId = BitConverter.ToUInt64(response.Payload, 0); - break; - case DiagnosticsServerCommandId.Error: - // bad... - uint hr = BitConverter.ToUInt32(response.Payload, 0); - Exception ex = ConvertHRToException(hr, $"Session start FAILED 0x{hr:X8}"); - throw ex; - default: - break; - } - - return stream; - } - - /// - /// Turn off EventPipe logging session for the specified process Id. - /// - /// Process Id to turn off logging session. - /// EventPipe session Id to turn off. - /// It returns sessionId if success, otherwise 0. - public static ulong StopTracing(int processId, ulong sessionId) - { - if (sessionId == 0) - return sessionId; // TODO: Throw here instead? - - byte[] payload = BitConverter.GetBytes(sessionId); - - var response = IpcClient.SendMessage(processId, new IpcMessage(DiagnosticsServerCommandSet.EventPipe, (byte)EventPipeCommandId.StopTracing, payload)); - - switch ((DiagnosticsServerCommandId)response.Header.CommandId) - { - case DiagnosticsServerCommandId.OK: - return BitConverter.ToUInt64(response.Payload, 0); - case DiagnosticsServerCommandId.Error: - return 0; - default: - return 0; - } - } - - private static Exception ConvertHRToException(uint hr, string msg) - { - if (hr == (uint)EventPipeErrorCode.BAD_ENCODING) - { - return new EventPipeBadEncodingException(msg); - } - else if (hr == (uint)EventPipeErrorCode.UNKNOWN_COMMAND) - { - return new EventPipeUnknownCommandException(msg); - } - else if (hr == (uint)EventPipeErrorCode.UNKNOWN_MAGIC) - { - return new EventPipeUnknownMagicException(msg); - } - else - { - return new EventPipeUnknownErrorException(msg); - } - } - } -} diff --git a/src/Microsoft.Diagnostics.Tools.RuntimeClient/Eventing/EventPipeSessionType.cs b/src/Microsoft.Diagnostics.Tools.RuntimeClient/Eventing/EventPipeSessionType.cs deleted file mode 100644 index 453408a34..000000000 --- a/src/Microsoft.Diagnostics.Tools.RuntimeClient/Eventing/EventPipeSessionType.cs +++ /dev/null @@ -1,27 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -namespace Microsoft.Diagnostics.Tools.RuntimeClient -{ - /// - /// Defines constants for EventPipe logging sessions. - /// - public enum EventPipeSessionType : uint - { - /// - /// The events will be written to file at the end of the session. - /// - TraceToFile, - - /// - /// Events will be passed to the EventListener. - /// - CallbackListener, - - /// - /// Events will be sent out-of-proc by writing them to the underlying IPC stream implementation. - /// - TraceToStream - } -} diff --git a/src/Microsoft.Diagnostics.Tools.RuntimeClient/Eventing/MessageHeader.cs b/src/Microsoft.Diagnostics.Tools.RuntimeClient/Eventing/MessageHeader.cs deleted file mode 100644 index 49b931cab..000000000 --- a/src/Microsoft.Diagnostics.Tools.RuntimeClient/Eventing/MessageHeader.cs +++ /dev/null @@ -1,25 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System.Runtime.InteropServices; - -namespace Microsoft.Diagnostics.Tools.RuntimeClient -{ - /// - /// Message header used to send commands to the .NET Core runtime through IPC. - /// - [StructLayout(LayoutKind.Sequential)] - public struct MessageHeader - { - /// - /// Request type. - /// - public DiagnosticsMessageType RequestType; - - /// - /// Remote process Id. - /// - public uint Pid; - } -} diff --git a/src/Microsoft.Diagnostics.Tools.RuntimeClient/Eventing/Provider.cs b/src/Microsoft.Diagnostics.Tools.RuntimeClient/Eventing/Provider.cs deleted file mode 100644 index 16f3ead9c..000000000 --- a/src/Microsoft.Diagnostics.Tools.RuntimeClient/Eventing/Provider.cs +++ /dev/null @@ -1,75 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System; -using System.Diagnostics.Tracing; -using System.Text.RegularExpressions; - -namespace Microsoft.Diagnostics.Tools.RuntimeClient -{ - public struct Provider - { - public Provider( - string name, - ulong keywords = ulong.MaxValue, - EventLevel eventLevel = EventLevel.Verbose, - string filterData = null) - { - if (string.IsNullOrWhiteSpace(name)) - throw new ArgumentNullException(nameof(name)); - Name = name; - Keywords = keywords; - EventLevel = eventLevel; - FilterData = string.IsNullOrWhiteSpace(filterData) ? null : Regex.Unescape(filterData); - } - - public ulong Keywords { get; } - - public EventLevel EventLevel { get; } - - public string Name { get; } - - public string FilterData { get; } - - public override string ToString() => - $"{Name}:0x{Keywords:X16}:{(uint)EventLevel}{(FilterData == null ? "" : $":{FilterData}")}"; - - public string ToDisplayString() => - String.Format("{0, -40}", Name) + String.Format("0x{0, -18}", $"{Keywords:X16}") + String.Format("{0, -8}", EventLevel.ToString() + $"({(int)EventLevel})"); - - public static bool operator ==(Provider left, Provider right) - { - return left.Name == right.Name && - left.Keywords == right.Keywords && - left.EventLevel == right.EventLevel && - left.FilterData == right.FilterData; - } - - public static bool operator !=(Provider left, Provider right) - { - return !(left == right); - } - - public override bool Equals(object obj) - { - - if (obj == null || GetType() != obj.GetType()) - { - return false; - } - - return this == (Provider)obj; - } - - public override int GetHashCode() - { - int hash = 0; - hash ^= this.Name.GetHashCode(); - hash ^= this.Keywords.GetHashCode(); - hash ^= this.EventLevel.GetHashCode(); - hash ^= this.FilterData.GetHashCode(); - return hash; - } - } -} diff --git a/src/Microsoft.Diagnostics.Tools.RuntimeClient/Eventing/SessionConfiguration.cs b/src/Microsoft.Diagnostics.Tools.RuntimeClient/Eventing/SessionConfiguration.cs deleted file mode 100644 index 1fcf12a9d..000000000 --- a/src/Microsoft.Diagnostics.Tools.RuntimeClient/Eventing/SessionConfiguration.cs +++ /dev/null @@ -1,107 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; - -namespace Microsoft.Diagnostics.Tools.RuntimeClient -{ - public enum EventPipeSerializationFormat - { - NetPerf, - NetTrace - } - - public class SessionConfiguration - { - public SessionConfiguration(uint circularBufferSizeMB, EventPipeSerializationFormat format, IReadOnlyCollection providers) - { - if (circularBufferSizeMB == 0) - throw new ArgumentException($"Buffer size cannot be zero."); - if (format != EventPipeSerializationFormat.NetPerf && format != EventPipeSerializationFormat.NetTrace) - throw new ArgumentException("Unrecognized format"); - if (providers == null) - throw new ArgumentNullException(nameof(providers)); - if (providers.Count() <= 0) - throw new ArgumentException($"Specified providers collection is empty."); - - CircularBufferSizeInMB = circularBufferSizeMB; - Format = format; - string extension = format == EventPipeSerializationFormat.NetPerf ? ".netperf" : ".nettrace"; - _providers = new List(providers); - } - - public uint CircularBufferSizeInMB { get; } - public EventPipeSerializationFormat Format { get; } - - public IReadOnlyCollection Providers => _providers.AsReadOnly(); - - private readonly List _providers; - - public virtual byte[] Serialize() - { - byte[] serializedData = null; - using (var stream = new MemoryStream()) - using (var writer = new BinaryWriter(stream)) - { - writer.Write(CircularBufferSizeInMB); - writer.Write((uint)Format); - - writer.Write(Providers.Count()); - foreach (var provider in Providers) - { - writer.Write(provider.Keywords); - writer.Write((uint)provider.EventLevel); - - writer.WriteString(provider.Name); - writer.WriteString(provider.FilterData); - } - - writer.Flush(); - serializedData = stream.ToArray(); - } - - return serializedData; - } - } - - public class SessionConfigurationV2 : SessionConfiguration - { - public SessionConfigurationV2(uint circularBufferSizeMB, EventPipeSerializationFormat format, bool requestRundown, IReadOnlyCollection providers) : base(circularBufferSizeMB, format, providers) - { - RequestRundown = requestRundown; - } - - public bool RequestRundown { get; } - - public override byte[] Serialize() - { - byte[] serializedData = null; - using (var stream = new MemoryStream()) - using (var writer = new BinaryWriter(stream)) - { - writer.Write(CircularBufferSizeInMB); - writer.Write((uint)Format); - writer.Write(RequestRundown); - - writer.Write(Providers.Count()); - foreach (var provider in Providers) - { - writer.Write(provider.Keywords); - writer.Write((uint)provider.EventLevel); - - writer.WriteString(provider.Name); - writer.WriteString(provider.FilterData); - } - - writer.Flush(); - serializedData = stream.ToArray(); - } - - return serializedData; - } - } -} diff --git a/src/Microsoft.Diagnostics.Tools.RuntimeClient/Extensions.cs b/src/Microsoft.Diagnostics.Tools.RuntimeClient/Extensions.cs deleted file mode 100644 index 7de46bd5b..000000000 --- a/src/Microsoft.Diagnostics.Tools.RuntimeClient/Extensions.cs +++ /dev/null @@ -1,53 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System; -using System.IO; -using System.Runtime.InteropServices; -using System.Text; - -namespace Microsoft.Diagnostics.Tools.RuntimeClient -{ - public static class Extensions - { - public static void WriteString(this BinaryWriter @this, string value) - { - if (@this == null) - throw new ArgumentNullException(nameof(@this)); - - @this.Write(value != null ? (value.Length + 1) : 0); - if (value != null) - @this.Write(Encoding.Unicode.GetBytes(value + '\0')); - } - -#if DEBUG - private static int GetByteCount(this string @this) - { - if (@this == null) - throw new ArgumentNullException(nameof(@this)); - - var strLength = @this == null ? 0 : Encoding.Unicode.GetByteCount(@this + '\0'); - return Marshal.SizeOf(typeof(int)) + strLength; - } - - public static int GetByteCount(this SessionConfiguration @this) - { - int size = 0; - - size += Marshal.SizeOf(@this.CircularBufferSizeInMB.GetType()); - size += Marshal.SizeOf(typeof(int)); - - foreach (var provider in @this.Providers) - { - size += Marshal.SizeOf(provider.Keywords.GetType()); - size += Marshal.SizeOf(typeof(uint)); // provider.EventLevel.GetType() - size += provider.Name.GetByteCount(); - size += provider.FilterData.GetByteCount(); - } - - return size; - } -#endif // DEBUG - } -} diff --git a/src/Microsoft.Diagnostics.Tools.RuntimeClient/Microsoft.Diagnostics.Tools.RuntimeClient.csproj b/src/Microsoft.Diagnostics.Tools.RuntimeClient/Microsoft.Diagnostics.Tools.RuntimeClient.csproj deleted file mode 100644 index 0294b5336..000000000 --- a/src/Microsoft.Diagnostics.Tools.RuntimeClient/Microsoft.Diagnostics.Tools.RuntimeClient.csproj +++ /dev/null @@ -1,14 +0,0 @@ - - - Library - netcoreapp2.1 - Microsoft.Diagnostics.Tools.RuntimeClient - .NET Core Diagnostics Runtime Client - true - Diagnostic - $(Description) - true - true - true - - diff --git a/src/tests/Microsoft.Diagnostics.Tools.RuntimeClient/Assert.cs b/src/tests/Microsoft.Diagnostics.Tools.RuntimeClient/Assert.cs deleted file mode 100644 index 2bd5a2c9a..000000000 --- a/src/tests/Microsoft.Diagnostics.Tools.RuntimeClient/Assert.cs +++ /dev/null @@ -1,53 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System; - -namespace Tracing.Tests.Common -{ - public static class Assert - { - public static void True(string name, bool condition) - { - if (!condition) - { - throw new Exception( - string.Format("Condition '{0}' is not true", name)); - } - } - - public static void Equal(string name, T left, T right) where T : IEquatable - { - if (left == null && right != null) - { - throw new Exception( - string.Format("Values for '{0}' are not equal! Left=NULL Right='{1}'", name, right)); - } - else if (left != null && right == null) - { - throw new Exception( - string.Format("Values for '{0}' are not equal! Left='{1}' Right=NULL", name, left)); - } - else if (!left.Equals(right)) - { - throw new Exception( - string.Format("Values for '{0}' are not equal! Left='{1}' Right='{2}'", name, left, right)); - } - } - - public static void NotEqual(string name, T left, T right) where T : IEquatable - { - if (left == null && right == null) - { - throw new Exception( - string.Format("Values for '{0}' are equal! Left=NULL Right=NULL", name)); - } - else if (left != null && left.Equals(right)) - { - throw new Exception( - string.Format("Values for '{0}' are equal! Left='{1}' Right='{2}'", name, left, right)); - } - } - } -} diff --git a/src/tests/Microsoft.Diagnostics.Tools.RuntimeClient/Program.cs b/src/tests/Microsoft.Diagnostics.Tools.RuntimeClient/Program.cs deleted file mode 100644 index 492f1441d..000000000 --- a/src/tests/Microsoft.Diagnostics.Tools.RuntimeClient/Program.cs +++ /dev/null @@ -1,359 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using Microsoft.Diagnostics.Tracing; -using Microsoft.Diagnostics.Tracing.Etlx; -using System; -using System.Diagnostics; -using System.IO; -using System.Linq; -using System.Threading.Tasks; -using Tracing.Tests.Common; - -namespace Microsoft.Diagnostics.Tools.RuntimeClient.Tests -{ - class Program - { - static int Main(string[] args) - { - SendSmallerHeaderCommand(); - SendInvalidDiagnosticsMessageTypeCommand(); - SendInvalidInputData(); - TestCollectEventPipeTracing(); - return 100; - } - - private static Process ThisProcess { get; } = Process.GetCurrentProcess(); - - private static void SendSmallerHeaderCommand() - { - Console.WriteLine("Send a small payload as header."); - - ulong sessionId = 0; - - try - { - byte[] bytes; - using (var stream = new MemoryStream()) - { - using (var bw = new BinaryWriter(stream)) - { - bw.Write((uint)DiagnosticsMessageType.StartEventPipeTracing); - bw.Flush(); - stream.Position = 0; - - bytes = new byte[stream.Length]; - stream.Read(bytes, 0, bytes.Length); - } - } - - sessionId = EventPipeClient.SendCommand(ThisProcess.Id, bytes); - } - catch (EndOfStreamException) - { - Assert.Equal("EventPipe Session Id", sessionId, (ulong)0); - } - catch - { - Assert.True("Send command threw unexpected exception", false); - } - } - - private static void SendInvalidDiagnosticsMessageTypeCommand() - { - Console.WriteLine("Send a wrong message type as the diagnostic header header."); - ulong sessionId = 0; - - try - { - byte[] bytes; - using (var stream = new MemoryStream()) - { - using (var bw = new BinaryWriter(stream)) - { - bw.Write(uint.MaxValue); - bw.Write(ThisProcess.Id); - bw.Flush(); - stream.Position = 0; - - bytes = new byte[stream.Length]; - stream.Read(bytes, 0, bytes.Length); - } - } - - sessionId = EventPipeClient.SendCommand(ThisProcess.Id, bytes); - } - catch (EndOfStreamException) - { - Assert.Equal("EventPipe Session Id", sessionId, (ulong)0); - } - catch - { - Assert.True("Send command threw unexpected exception", false); - } - } - - private static byte[] Serialize(MessageHeader header, TestSessionConfiguration configuration, Stream stream) - { - using (var bw = new BinaryWriter(stream)) - { - bw.Write((uint)header.RequestType); - bw.Write(header.Pid); - - bw.Write(configuration.CircularBufferSizeInMB); - - bw.WriteString(null); - - if (configuration.Providers == null) - { - bw.Write(0); - } - else - { - bw.Write(configuration.Providers.Count()); - foreach (var provider in configuration.Providers) - { - bw.Write(provider.Keywords); - bw.Write((uint)provider.EventLevel); - - bw.WriteString(provider.Name); - bw.WriteString(provider.FilterData); - } - } - - bw.Flush(); - stream.Position = 0; - - var bytes = new byte[stream.Length]; - stream.Read(bytes, 0, bytes.Length); - return bytes; - } - - } - - private static void SendInvalidInputData() - { - var configs = new TestSessionConfiguration[] { - new TestSessionConfiguration { - CircularBufferSizeInMB = 0, - TestName = "0 size circular buffer", - Providers = new TestProvider[] { - new TestProvider{ - Name = "Microsoft-Windows-DotNETRuntime" - }, - }, - }, - new TestSessionConfiguration { - CircularBufferSizeInMB = 64, - TestName = "null providers", - Providers = null, - }, - new TestSessionConfiguration { - CircularBufferSizeInMB = 64, - TestName = "no providers", - Providers = new TestProvider[]{ }, - }, - new TestSessionConfiguration { - CircularBufferSizeInMB = 64, - TestName = "null provider name", - Providers = new TestProvider[]{ new TestProvider { Name = null, }, }, - }, - new TestSessionConfiguration { - CircularBufferSizeInMB = 64, - TestName = "empty provider name", - Providers = new TestProvider[]{ new TestProvider { Name = string.Empty, }, }, - }, - new TestSessionConfiguration { - CircularBufferSizeInMB = 64, - TestName = "white space provider name", - Providers = new TestProvider[]{ new TestProvider { Name = " ", }, }, - }, - }; - - foreach (var config in configs) - { - ulong sessionId = 0; - - try - { - var header = new MessageHeader { - RequestType = DiagnosticsMessageType.CollectEventPipeTracing, - Pid = (uint)Process.GetCurrentProcess().Id, - }; - - byte[] bytes; - using (var stream = new MemoryStream()) - bytes = Serialize(header, config, stream); - - Console.WriteLine($"Test: {config.TestName}"); - sessionId = EventPipeClient.SendCommand(ThisProcess.Id, bytes); - - // Check that a session was created. - Assert.Equal("EventPipe Session Id", sessionId, (ulong)0); - } - catch (EndOfStreamException) - { - Assert.Equal("EventPipe Session Id", sessionId, (ulong)0); - } - catch - { - Assert.True("Send command threw unexpected exception", false); - } - } - } - - private static void SendInvalidPayloadToCollectCommand() - { - Console.WriteLine("Send Invalid Payload To Collect Command."); - - ulong sessionId = 0; - - try - { - uint circularBufferSizeMB = 64; - var filePath = Path.Combine( - Directory.GetCurrentDirectory(), - $"dotnetcore-eventpipe-{ThisProcess.Id}.nettrace"); - var providers = new[] { - new Provider(name: "Microsoft-Windows-DotNETRuntime"), - }; - - var configuration = new SessionConfiguration(circularBufferSizeMB, filePath, providers); - - // Start session #1. - sessionId = EventPipeClient.StartTracingToFile( - processId: ThisProcess.Id, - configuration: configuration); - - // Check that a session was created. - Assert.Equal("EventPipe Session Id", sessionId, (ulong)0); - } - finally - { - if (sessionId != 0) - EventPipeClient.StopTracing(ThisProcess.Id, sessionId); - } - } - - private static void TestCollectEventPipeTracing() - { - ulong sessionId = 0; - - try - { - uint circularBufferSizeMB = 64; - var filePath = Path.Combine( - Directory.GetCurrentDirectory(), - $"dotnetcore-eventpipe-{ThisProcess.Id}.nettrace"); - var providers = new[] { - new Provider(name: "Microsoft-Windows-DotNETRuntime"), - }; - - var configuration = new SessionConfiguration(circularBufferSizeMB, filePath, providers); - - Console.WriteLine("Start collecting."); - using (Stream stream = EventPipeClient.CollectTracing( - processId: ThisProcess.Id, - configuration: configuration, - sessionId: out sessionId)) - { - // Check that a session was created. - Assert.NotEqual("EventPipe Session Id", sessionId, (ulong)0); - - var collectingTask = new Task(() => { - using (var fs = new FileStream(filePath, FileMode.Create, FileAccess.Write)) - { - while (true) - { - var buffer = new byte[16 * 1024]; - int nBytesRead = stream.Read(buffer, 0, buffer.Length); - if (nBytesRead <= 0) - break; - fs.Write(buffer, 0, nBytesRead); - } - } - }); - collectingTask.Start(); - - { // Attempt to create another session, and verify that is not possible. - Console.WriteLine("Attempt to create another session."); - - ulong sessionId2 = 0; - try - { - using (var stream2 = EventPipeClient.CollectTracing( - processId: ThisProcess.Id, - configuration: configuration, - sessionId: out sessionId2)) - { - var buffer = new byte[16 * 1024]; - int nBytesRead = stream.Read(buffer, 0, buffer.Length); - } - } - catch (EndOfStreamException) - { - } - catch - { - Assert.True("EventPipeClient.CollectTracing threw unexpected exception", false); - } - - Assert.Equal("EventPipe Session Id", sessionId2, (ulong)0); - } - - Console.WriteLine("Doing some work."); - Workload.DoWork(10); - - var ret = EventPipeClient.StopTracing(ThisProcess.Id, sessionId); - Assert.Equal("Expect return value to be the disabled session Id", sessionId, ret); - collectingTask.Wait(); - - sessionId = 0; // Reset session Id, we do not need to disable it later. - - Assert.Equal("EventPipe output file", File.Exists(filePath), true); - - // Check file is valid. - Console.WriteLine("Validating nettrace file."); - ValidateNetTrace(filePath); - } - } - finally - { - if (sessionId != 0) - EventPipeClient.StopTracing(ThisProcess.Id, sessionId); - } - } - - private static void ValidateNetTrace(string filePath) - { - var nEventPipeResults = 0; - using (var trace = new TraceLog(TraceLog.CreateFromEventPipeDataFile(filePath)).Events.GetSource()) - { - trace.Dynamic.All += (TraceEvent data) => { - ++nEventPipeResults; - }; - trace.Process(); - } - - // Assert there were events in the file. - Assert.NotEqual("Found events in trace file", nEventPipeResults, 0); - } - - [Conditional("DEBUG")] - private static void DumpNetTrace(string filePath) - { - using (var trace = new TraceLog(TraceLog.CreateFromEventPipeDataFile(filePath)).Events.GetSource()) - { - trace.Dynamic.All += (TraceEvent e) => { - if (!string.IsNullOrWhiteSpace(e.ProviderName) && !string.IsNullOrWhiteSpace(e.EventName)) - { - Debug.WriteLine($"Event Provider: {e.ProviderName}"); - Debug.WriteLine($" Event Name: {e.EventName}"); - } - }; - trace.Process(); - } - } - } -} diff --git a/src/tests/Microsoft.Diagnostics.Tools.RuntimeClient/TestProvider.cs b/src/tests/Microsoft.Diagnostics.Tools.RuntimeClient/TestProvider.cs deleted file mode 100644 index 992a32b32..000000000 --- a/src/tests/Microsoft.Diagnostics.Tools.RuntimeClient/TestProvider.cs +++ /dev/null @@ -1,19 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System.Diagnostics.Tracing; - -namespace Microsoft.Diagnostics.Tools.RuntimeClient.Tests -{ - internal sealed class TestProvider - { - public ulong Keywords { get; set; } - - public EventLevel EventLevel { get; set; } - - public string Name { get; set; } - - public string FilterData { get; set; } - } -} diff --git a/src/tests/Microsoft.Diagnostics.Tools.RuntimeClient/TestSessionConfiguration.cs b/src/tests/Microsoft.Diagnostics.Tools.RuntimeClient/TestSessionConfiguration.cs deleted file mode 100644 index 016937e5a..000000000 --- a/src/tests/Microsoft.Diagnostics.Tools.RuntimeClient/TestSessionConfiguration.cs +++ /dev/null @@ -1,17 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System.Collections.Generic; - -namespace Microsoft.Diagnostics.Tools.RuntimeClient.Tests -{ - internal sealed class TestSessionConfiguration - { - public uint CircularBufferSizeInMB { get; set; } - - public string TestName { get; set; } - - public IEnumerable Providers { get; set; } - } -} diff --git a/src/tests/Microsoft.Diagnostics.Tools.RuntimeClient/Workload.cs b/src/tests/Microsoft.Diagnostics.Tools.RuntimeClient/Workload.cs deleted file mode 100644 index a44095c30..000000000 --- a/src/tests/Microsoft.Diagnostics.Tools.RuntimeClient/Workload.cs +++ /dev/null @@ -1,57 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Runtime.CompilerServices; - -namespace Microsoft.Diagnostics.Tools.RuntimeClient.Tests -{ - internal static class Workload - { - [MethodImpl(MethodImplOptions.NoInlining)] - public static void DoWork(int nIterations) - { - for (int i = 0; i < nIterations; ++i) - { - MemoryAccessPerformance(); - BranchPredictionPerformance(seed: i); - } - } - - [MethodImpl(MethodImplOptions.NoInlining)] - private static double MemoryAccessPerformance() - { - var doubles = new double[8 * 1024 * 1024]; - for (int i = 0; i < doubles.Length; i += 100) - doubles[i] = 2.0; - for (int i = 0; i < doubles.Length; i += 200) - doubles[i] *= 3.0; - for (int i = 0; i < doubles.Length; i += 400) - doubles[i] *= 5.0; - for (int i = 0; i < doubles.Length; i += 800) - doubles[i] *= 7.0; - for (int i = 0; i < doubles.Length; i += 1600) - doubles[i] *= 11.0; - return doubles.Average(); - } - - [MethodImpl(MethodImplOptions.NoInlining)] - private static IEnumerable BranchPredictionPerformance(int seed) - { - const int nCards = 52; - var deck = new List(Enumerable.Range(0, nCards)); - var rnd = new Random((int)DateTime.Now.Ticks + seed); - - for (int i = 0; i < deck.Count(); ++i) - { - var pos = rnd.Next(nCards); - if (pos % 3 != 0) - pos = rnd.Next(nCards); - var temp = deck[i]; - deck[i] = deck[pos]; - deck[pos] = temp; - } - - return deck; - } - } -} diff --git a/src/tests/Microsoft.Diagnostics.Tools.RuntimeClient/eventpipetests.csproj b/src/tests/Microsoft.Diagnostics.Tools.RuntimeClient/eventpipetests.csproj deleted file mode 100644 index 058b4977d..000000000 --- a/src/tests/Microsoft.Diagnostics.Tools.RuntimeClient/eventpipetests.csproj +++ /dev/null @@ -1,17 +0,0 @@ - - - Exe - netcoreapp3.0 - Microsoft.Diagnostics.Tools.RuntimeClient.Tests - false - - - - false - false - - - - - - -- 2.34.1