/*
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 System.Collections.ObjectModel;
using dnSpy.Contracts.Debugger.Code;
namespace dnSpy.Contracts.Debugger.Breakpoints.Code {
///
/// Code breakpoint
///
public abstract class DbgCodeBreakpoint : DbgObject {
///
/// Gets the unique code breakpoint id
///
public abstract int Id { get; }
///
/// Can be used by code to add custom hit test conditions
///
public abstract event EventHandler? HitCheck;
///
/// Raised when the breakpoint is hit and the process will be paused
///
public abstract event EventHandler? Hit;
///
/// Gets the breakpoint options
///
public abstract DbgCodeBreakpointOptions Options { get; }
///
/// true if it's a temporary breakpoint that gets removed when all debugged processes have exited
///
public bool IsTemporary => (Options & DbgCodeBreakpointOptions.Temporary) != 0;
///
/// true if it's a hidden breakpoint. It's not shown in the UI (eg. breakpoints window, call stack window, glyph margin, text view)
///
public bool IsHidden => (Options & DbgCodeBreakpointOptions.Hidden) != 0;
///
/// true if it's a one-shot breakpoint. When the breakpoint is hit, the process is paused and the breakpoint is removed
///
public bool IsOneShot => (Options & DbgCodeBreakpointOptions.OneShot) != 0;
///
/// Gets/sets the current settings
///
public abstract DbgCodeBreakpointSettings Settings { get; set; }
///
/// true if the breakpoint is enabled
///
public abstract bool IsEnabled { get; set; }
///
/// Condition
///
public abstract DbgCodeBreakpointCondition? Condition { get; set; }
///
/// Hit count
///
public abstract DbgCodeBreakpointHitCount? HitCount { get; set; }
///
/// Filter
///
public abstract DbgCodeBreakpointFilter? Filter { get; set; }
///
/// Trace message
///
public abstract DbgCodeBreakpointTrace? Trace { get; set; }
///
/// Labels
///
public abstract ReadOnlyCollection Labels { get; set; }
///
/// Gets the breakpoint location
///
public abstract DbgCodeLocation Location { get; }
///
/// Gets all bound breakpoints
///
public abstract DbgBoundCodeBreakpoint[] BoundBreakpoints { get; }
///
/// Raised when is changed
///
public abstract event EventHandler>? BoundBreakpointsChanged;
///
/// Gets the bound breakpoints warning/error message
///
public abstract DbgBoundCodeBreakpointMessage BoundBreakpointsMessage { get; }
///
/// Raised when is changed
///
public abstract event EventHandler? BoundBreakpointsMessageChanged;
///
/// Removes the breakpoint
///
public abstract void Remove();
}
///
/// Breakpoint hit check event args
///
public sealed class DbgBreakpointHitCheckEventArgs : EventArgs {
///
/// If false, it doesn't count as a hit and the process is not paused.
/// If true, the normal BP settings decide if the process gets paused.
/// The default value is true.
///
public bool Pause {
get => pause;
set => pause = value;
}
bool pause;
///
/// Gets the bound breakpoint
///
public DbgBoundCodeBreakpoint BoundBreakpoint { get; }
///
/// Gets the thread
///
public DbgThread Thread { get; }
///
/// Constructor
///
/// Bound breakpoint
/// Thread
public DbgBreakpointHitCheckEventArgs(DbgBoundCodeBreakpoint boundBreakpoint, DbgThread thread) {
pause = true;
BoundBreakpoint = boundBreakpoint ?? throw new ArgumentNullException(nameof(boundBreakpoint));
Thread = thread ?? throw new ArgumentNullException(nameof(thread));
}
}
///
/// Breakpoint hit event args
///
public sealed class DbgBreakpointHitEventArgs : EventArgs {
///
/// Gets the bound breakpoint
///
public DbgBoundCodeBreakpoint BoundBreakpoint { get; }
///
/// Gets the thread
///
public DbgThread Thread { get; }
///
/// Constructor
///
/// Bound breakpoint
/// Thread
public DbgBreakpointHitEventArgs(DbgBoundCodeBreakpoint boundBreakpoint, DbgThread thread) {
BoundBreakpoint = boundBreakpoint ?? throw new ArgumentNullException(nameof(boundBreakpoint));
Thread = thread ?? throw new ArgumentNullException(nameof(thread));
}
}
}