/*
Copyright (C) 2014-2019 de4dot@gmail.com
This file is part of dnSpy
dnSpy is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
dnSpy is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with dnSpy. If not, see .
*/
using System;
using dnSpy.Contracts.Debugger.Breakpoints.Code;
namespace dnSpy.Contracts.Debugger.Engine {
///
/// Base class of messages created by a
///
public abstract class DbgEngineMessage {
///
/// Gets the message kind
///
public abstract DbgEngineMessageKind MessageKind { get; }
///
/// Gets the message flags
///
public DbgEngineMessageFlags MessageFlags { get; }
///
/// Constructor
///
/// Message flags
protected DbgEngineMessage(DbgEngineMessageFlags messageFlags) => MessageFlags = messageFlags;
}
///
/// event. Should be the first event sent by the
/// debug engine. If it couldn't connect, no more messages need to be sent after this message
/// is sent.
///
public sealed class DbgMessageConnected : DbgEngineMessage {
///
/// Returns
///
public override DbgEngineMessageKind MessageKind => DbgEngineMessageKind.Connected;
///
/// The error message or null if there's no error
///
public string? ErrorMessage { get; }
///
/// Gets the process id
///
public int ProcessId { get; }
///
/// Constructor
///
/// Process id
/// Message flags
public DbgMessageConnected(int processId, DbgEngineMessageFlags messageFlags) : base(messageFlags) => ProcessId = processId;
///
/// Constructor
///
/// Error message
/// Message flags
public DbgMessageConnected(string errorMessage, DbgEngineMessageFlags messageFlags)
: base(messageFlags) => ErrorMessage = errorMessage ?? throw new ArgumentNullException(nameof(errorMessage));
}
///
/// event
///
public sealed class DbgMessageDisconnected : DbgEngineMessage {
///
/// Returns
///
public override DbgEngineMessageKind MessageKind => DbgEngineMessageKind.Disconnected;
///
/// Gets the exit code
///
public int ExitCode { get; }
///
/// Constructor
///
/// Exit code
/// Message flags
public DbgMessageDisconnected(int exitCode, DbgEngineMessageFlags messageFlags) : base(messageFlags) => ExitCode = exitCode;
}
///
/// event
///
public sealed class DbgMessageBreak : DbgEngineMessage {
///
/// Returns
///
public override DbgEngineMessageKind MessageKind => DbgEngineMessageKind.Break;
///
/// The error message or null if there's no error
///
public string? ErrorMessage { get; }
///
/// Gets the thread or null if it's not known
///
public DbgThread? Thread { get; }
///
/// Constructor
///
/// Thread or null if it's not known
/// Message flags
public DbgMessageBreak(DbgThread? thread, DbgEngineMessageFlags messageFlags) : base(messageFlags) => Thread = thread;
///
/// Constructor
///
/// Error message
/// Message flags
public DbgMessageBreak(string errorMessage, DbgEngineMessageFlags messageFlags) : base(messageFlags) => ErrorMessage = errorMessage ?? throw new ArgumentNullException(nameof(errorMessage));
}
///
/// event
///
public sealed class DbgMessageEntryPointBreak : DbgEngineMessage {
///
/// Returns
///
public override DbgEngineMessageKind MessageKind => DbgEngineMessageKind.EntryPointBreak;
///
/// Gets the thread or null if it's not known
///
public DbgThread? Thread { get; }
///
/// Constructor
///
/// Thread or null if it's not known
/// Message flags
public DbgMessageEntryPointBreak(DbgThread? thread, DbgEngineMessageFlags messageFlags) : base(messageFlags) => Thread = thread;
}
///
/// event
///
public sealed class DbgMessageProgramMessage : DbgEngineMessage {
///
/// Returns
///
public override DbgEngineMessageKind MessageKind => DbgEngineMessageKind.ProgramMessage;
///
/// Gets the message
///
public string Message { get; }
///
/// Gets the thread or null if it's not known
///
public DbgThread? Thread { get; }
///
/// Constructor
///
/// Message
/// Thread or null if it's not known
/// Message flags
public DbgMessageProgramMessage(string message, DbgThread? thread, DbgEngineMessageFlags messageFlags)
: base(messageFlags) {
Message = message ?? throw new ArgumentNullException(nameof(message));
Thread = thread;
}
}
///
/// event
///
public sealed class DbgMessageBreakpoint : DbgEngineMessage {
///
/// Returns
///
public override DbgEngineMessageKind MessageKind => DbgEngineMessageKind.Breakpoint;
///
/// Gets the breakpoint
///
public DbgBoundCodeBreakpoint BoundBreakpoint { get; }
///
/// Gets the thread or null if it's not known
///
public DbgThread? Thread { get; }
///
/// Constructor
///
/// Breakpoint
/// Thread or null if it's not known
/// Message flags
public DbgMessageBreakpoint(DbgBoundCodeBreakpoint boundBreakpoint, DbgThread? thread, DbgEngineMessageFlags messageFlags)
: base(messageFlags) {
BoundBreakpoint = boundBreakpoint ?? throw new ArgumentNullException(nameof(boundBreakpoint));
Thread = thread;
}
}
///
/// event
///
public sealed class DbgMessageProgramBreak : DbgEngineMessage {
///
/// Returns
///
public override DbgEngineMessageKind MessageKind => DbgEngineMessageKind.ProgramBreak;
///
/// Gets the thread or null if it's not known
///
public DbgThread? Thread { get; }
///
/// Constructor
///
/// Thread or null if it's not known
/// Message flags
public DbgMessageProgramBreak(DbgThread? thread, DbgEngineMessageFlags messageFlags)
: base(messageFlags) => Thread = thread;
}
///
/// event
///
public sealed class DbgMessageSetIPComplete : DbgEngineMessage {
///
/// Returns
///
public override DbgEngineMessageKind MessageKind => DbgEngineMessageKind.SetIPComplete;
///
/// Gets the thread
///
public DbgThread Thread { get; }
///
/// true if all frames in the thread have been invalidated
///
public bool FramesInvalidated { get; }
///
/// Gets the error string or null if none
///
public string? Error { get; }
///
/// Constructor
///
/// Thread
/// true if all frames in the thread have been invalidated
/// Error string or null if none
/// Message flags
public DbgMessageSetIPComplete(DbgThread thread, bool framesInvalidated, string? error, DbgEngineMessageFlags messageFlags)
: base(messageFlags) {
Thread = thread ?? throw new ArgumentNullException(nameof(thread));
FramesInvalidated = framesInvalidated;
Error = error;
}
}
///
/// event
///
public sealed class DbgMessageAsyncProgramMessage : DbgEngineMessage {
///
/// Returns
///
public override DbgEngineMessageKind MessageKind => DbgEngineMessageKind.AsyncProgramMessage;
///
/// Gets the message source
///
public AsyncProgramMessageSource Source { get; }
///
/// Gets the message
///
public string Message { get; }
///
/// Constructor
///
/// Source
/// Message
public DbgMessageAsyncProgramMessage(AsyncProgramMessageSource source, string message)
: base(DbgEngineMessageFlags.None) {
Source = source;
Message = message ?? throw new ArgumentNullException(nameof(message));
}
}
}