/// <summary> /// Attach a profiler. /// </summary> /// <param name="attachTimeout">Timeout for attaching the profiler</param> /// <param name="profilerGuid">Guid for the profiler to be attached</param> /// <param name="profilerPath">Path to the profiler to be attached</param> /// <param name="additionalData">Additional data to be passed to the profiler</param> public void AttachProfiler(TimeSpan attachTimeout, Guid profilerGuid, string profilerPath, byte[] additionalData = null) { 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"); } byte[] serializedConfiguration = SerializeProfilerAttach((uint)attachTimeout.TotalSeconds, profilerGuid, profilerPath, additionalData); var message = new IpcMessage(DiagnosticsServerCommandSet.Profiler, (byte)ProfilerCommandId.AttachProfiler, serializedConfiguration); var response = IpcClient.SendMessage(_processId, message); switch ((DiagnosticsServerCommandId)response.Header.CommandId) { case DiagnosticsServerCommandId.Error: var hr = BitConverter.ToInt32(response.Payload, 0); throw new ServerErrorException($"Profiler attach failed (HRESULT: 0x{hr:X8})"); case DiagnosticsServerCommandId.OK: return; default: throw new ServerErrorException($"Profiler attach failed - server responded with unknown command"); } // 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. }
private bool disposedValue = false; // To detect redundant calls internal EventPipeSession(int processId, IEnumerable <EventPipeProvider> providers, bool requestRundown, int circularBufferMB) { _processId = processId; _providers = providers; _requestRundown = requestRundown; _circularBufferMB = circularBufferMB; var config = new EventPipeSessionConfiguration(circularBufferMB, EventPipeSerializationFormat.NetTrace, providers, requestRundown); var message = new IpcMessage(DiagnosticsServerCommandSet.EventPipe, (byte)EventPipeCommandId.CollectTracing2, config.SerializeV2()); EventStream = IpcClient.SendMessage(processId, message, out var response); switch ((DiagnosticsServerCommandId)response.Header.CommandId) { case DiagnosticsServerCommandId.OK: _sessionId = BitConverter.ToInt64(response.Payload, 0); break; case DiagnosticsServerCommandId.Error: var hr = BitConverter.ToInt32(response.Payload, 0); throw new ServerErrorException($"EventPipe session start failed (HRESULT: 0x{hr:X8})"); default: throw new ServerErrorException($"EventPipe session start failed - Server responded with unknown command"); } }
/// <summary> /// Trigger a core dump generation. /// </summary> /// <param name="dumpType">Type of the dump to be generated</param> /// <param name="dumpPath">Full path to the dump to be generated. By default it is /tmp/coredump.{pid}</param> /// <param name="logDumpGeneration">When set to true, display the dump generation debug log to the console.</param> public void WriteDump(DumpType dumpType, string dumpPath, bool logDumpGeneration = false) { if (!(RuntimeInformation.IsOSPlatform(OSPlatform.Linux) || RuntimeInformation.IsOSPlatform(OSPlatform.Windows))) { throw new PlatformNotSupportedException($"Unsupported operating system: {RuntimeInformation.OSDescription}"); } if (string.IsNullOrEmpty(dumpPath)) { throw new ArgumentNullException($"{nameof(dumpPath)} required"); } byte[] payload = SerializeCoreDump(dumpPath, dumpType, logDumpGeneration); IpcMessage message = new IpcMessage(DiagnosticsServerCommandSet.Dump, (byte)DumpCommandId.GenerateCoreDump, payload); IpcMessage response = IpcClient.SendMessage(_processId, message); switch ((DiagnosticsServerCommandId)response.Header.CommandId) { case DiagnosticsServerCommandId.Error: uint hr = BitConverter.ToUInt32(response.Payload, 0); if (hr == (uint)DiagnosticsIpcError.UnknownCommand) { throw new PlatformNotSupportedException($"Unsupported operating system: {RuntimeInformation.OSDescription}"); } throw new ServerErrorException($"Writing dump failed (HRESULT: 0x{hr:X8})"); case DiagnosticsServerCommandId.OK: return; default: throw new ServerErrorException($"Writing dump failed - server responded with unknown command"); } }
///<summary> /// Stops the given session ///</summary> public void Stop() { Debug.Assert(_sessionId > 0); 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; case DiagnosticsServerCommandId.Error: var hr = BitConverter.ToInt32(response.Payload, 0); throw new ServerErrorException($"EventPipe session stop failed (HRESULT: 0x{hr:X8})"); default: throw new ServerErrorException($"EventPipe session stop failed - Server responded with unknown command"); } }