Esempio n. 1
0
        /// <summary>
        /// Set a profiler as the startup profiler. It is only valid to issue this command
        /// while the runtime is paused in the "reverse server" mode.
        /// </summary>
        /// <param name="profilerGuid">Guid for the profiler to be attached</param>
        /// <param name="profilerPath">Path to the profiler to be attached</param>
        public void SetStartupProfiler(Guid profilerGuid, string profilerPath)
        {
            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 = SerializePayload(profilerGuid, profilerPath);
            var    message  = new IpcMessage(DiagnosticsServerCommandSet.Profiler, (byte)ProfilerCommandId.StartupProfiler, serializedConfiguration);
            var    response = IpcClient.SendMessage(_endpoint, message);

            switch ((DiagnosticsServerResponseId)response.Header.CommandId)
            {
            case DiagnosticsServerResponseId.Error:
                uint hr = BitConverter.ToUInt32(response.Payload, 0);
                if (hr == (uint)DiagnosticsIpcError.UnknownCommand)
                {
                    throw new UnsupportedCommandException("The target runtime does not support the ProfilerStartup command.");
                }
                else if (hr == (uint)DiagnosticsIpcError.InvalidArgument)
                {
                    throw new ServerErrorException("The runtime must be suspended to issue the SetStartupProfiler command.");
                }

                throw new ServerErrorException($"Profiler startup failed (HRESULT: 0x{hr:X8})");

            case DiagnosticsServerResponseId.OK:
                return;

            default:
                throw new ServerErrorException($"Profiler startup failed - server responded with unknown command");
            }
        }
Esempio n. 2
0
        /// <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="flags">logging and crash report flags. On runtimes less than 6.0, only LoggingEnabled is supported.</param>
        /// <param name="token">The token to monitor for cancellation requests.</param>
        public async Task WriteDumpAsync(DumpType dumpType, string dumpPath, WriteDumpFlags flags, CancellationToken token)
        {
            IpcMessage request  = CreateWriteDumpMessage(DumpCommandId.GenerateCoreDump3, dumpType, dumpPath, flags);
            IpcMessage response = await IpcClient.SendMessageAsync(_endpoint, request, token).ConfigureAwait(false);

            if (!ValidateResponseMessage(response, "Write dump", ValidateResponseOptions.UnknownCommandReturnsFalse | ValidateResponseOptions.ErrorMessageReturned))
            {
                request  = CreateWriteDumpMessage(DumpCommandId.GenerateCoreDump2, dumpType, dumpPath, flags);
                response = await IpcClient.SendMessageAsync(_endpoint, request, token).ConfigureAwait(false);

                if (!ValidateResponseMessage(response, "Write dump", ValidateResponseOptions.UnknownCommandReturnsFalse))
                {
                    if ((flags & ~WriteDumpFlags.LoggingEnabled) != 0)
                    {
                        throw new ArgumentException($"Only {nameof(WriteDumpFlags.LoggingEnabled)} flag is supported by this runtime version", nameof(flags));
                    }
                    request  = CreateWriteDumpMessage(dumpType, dumpPath, logDumpGeneration: (flags & WriteDumpFlags.LoggingEnabled) != 0);
                    response = await IpcClient.SendMessageAsync(_endpoint, request, token).ConfigureAwait(false);

                    ValidateResponseMessage(response, "Write dump");
                }
            }
        }
Esempio n. 3
0
        /// <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(_endpoint, message);

            switch ((DiagnosticsServerResponseId)response.Header.CommandId)
            {
            case DiagnosticsServerResponseId.Error:
                uint hr = BitConverter.ToUInt32(response.Payload, 0);
                if (hr == (uint)DiagnosticsIpcError.UnknownCommand)
                {
                    throw new UnsupportedCommandException("The target runtime does not support profiler attach");
                }
                throw new ServerErrorException($"Profiler attach failed (HRESULT: 0x{hr:X8})");

            case DiagnosticsServerResponseId.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.
        }
Esempio n. 4
0
 private static IpcMessage Read(Stream stream)
 {
     return(IpcMessage.Parse(stream));
 }
Esempio n. 5
0
 private static void Write(Stream stream, IpcMessage message)
 {
     Write(stream, message.Serialize());
 }
Esempio n. 6
0
 private static void Write(Stream stream, IpcMessage message)
 {
     byte[] buffer = message.Serialize();
     stream.Write(buffer, 0, buffer.Length);
 }
Esempio n. 7
0
        /// <summary>
        /// Sends a single DiagnosticsIpc Message to the dotnet process associated with the <paramref name="endpoint"/>.
        /// </summary>
        /// <param name="endpoint">An endpoint that provides a diagnostics connection to a runtime instance.</param>
        /// <param name="message">The DiagnosticsIpc Message to be sent</param>
        /// <param name="cancellationToken">The token to monitor for cancellation requests.</param>
        /// <returns>An <see cref="IpcResponse"/> containing the response message and continuation stream.</returns>
        public static async Task <IpcResponse> SendMessageGetContinuationAsync(IpcEndpoint endpoint, IpcMessage message, CancellationToken cancellationToken)
        {
            Stream stream = null;

            try
            {
                stream = await endpoint.ConnectAsync(cancellationToken).ConfigureAwait(false);

                await WriteAsync(stream, message, cancellationToken).ConfigureAwait(false);

                IpcMessage response = await ReadAsync(stream, cancellationToken).ConfigureAwait(false);

                return(new IpcResponse(response, Release(ref stream)));
            }
            finally
            {
                stream?.Dispose();
            }
        }
Esempio n. 8
0
        /// <summary>
        /// Sends a single DiagnosticsIpc Message to the dotnet process associated with the <paramref name="endpoint"/>.
        /// </summary>
        /// <param name="endpoint">An endpoint that provides a diagnostics connection to a runtime instance.</param>
        /// <param name="message">The DiagnosticsIpc Message to be sent</param>
        /// <param name="cancellationToken">The token to monitor for cancellation requests.</param>
        /// <returns>An <see cref="IpcMessage"/> that is the response message.</returns>
        public static async Task <IpcMessage> SendMessageAsync(IpcEndpoint endpoint, IpcMessage message, CancellationToken cancellationToken)
        {
            using IpcResponse response = await SendMessageGetContinuationAsync(endpoint, message, cancellationToken).ConfigureAwait(false);

            return(response.Message);
        }
Esempio n. 9
0
 /// <summary>
 /// Sends a single DiagnosticsIpc Message to the dotnet process associated with the <paramref name="endpoint"/>.
 /// </summary>
 /// <param name="endpoint">An endpoint that provides a diagnostics connection to a runtime instance.</param>
 /// <param name="message">The DiagnosticsIpc Message to be sent</param>
 /// <returns>An <see cref="IpcMessage"/> that is the response message.</returns>
 public static IpcMessage SendMessage(IpcEndpoint endpoint, IpcMessage message)
 {
     using IpcResponse response = SendMessageGetContinuation(endpoint, message);
     return(response.Message);
 }
Esempio n. 10
0
 private static Task <IpcMessage> ReadAsync(Stream stream, CancellationToken cancellationToken)
 {
     return(IpcMessage.ParseAsync(stream, cancellationToken));
 }
Esempio n. 11
0
 private static Task WriteAsync(Stream stream, IpcMessage message, CancellationToken cancellationToken)
 {
     byte[] buffer = message.Serialize();
     return(stream.WriteAsync(buffer, 0, buffer.Length, cancellationToken));
 }
Esempio n. 12
0
 public IpcResponse(IpcMessage message, Stream continuation)
 {
     Message      = message;
     Continuation = continuation;
 }