/* 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)); } } }