Source code for libdebug.data.breakpoint
#
# This file is part of libdebug Python library (https://github.com/libdebug/libdebug).
# Copyright (c) 2023-2024 Roberto Alessandro Bertolini, Gabriele Digregorio. All rights reserved.
# Licensed under the MIT license. See LICENSE file in the project root for details.
#
from __future__ import annotations
from dataclasses import dataclass, field
from typing import TYPE_CHECKING
from libdebug.debugger.internal_debugger_instance_manager import provide_internal_debugger
if TYPE_CHECKING:
from collections.abc import Callable
from libdebug.state.thread_context import ThreadContext
[docs]
@dataclass
class Breakpoint:
"""A breakpoint in the target process.
Attributes:
address (int): The address of the breakpoint in the target process.
symbol (str): The symbol, if available, of the breakpoint in the target process.
hit_count (int): The number of times this specific breakpoint has been hit.
hardware (bool): Whether the breakpoint is a hardware breakpoint or not.
condition (str): The breakpoint condition. Available values are "X", "W", "RW". Supported only for hardware breakpoints.
length (int): The length of the breakpoint area. Supported only for hardware breakpoints.
enabled (bool): Whether the breakpoint is enabled or not.
"""
address: int = 0
symbol: str = ""
hit_count: int = 0
hardware: bool = False
callback: None | Callable[[ThreadContext, Breakpoint], None] = None
condition: str = "x"
length: int = 1
enabled: bool = True
_linked_thread_ids: list[int] = field(default_factory=list)
# The thread ID that hit the breakpoint
_disabled_for_step: bool = False
_changed: bool = False
[docs]
def enable(self: Breakpoint) -> None:
"""Enable the breakpoint."""
if provide_internal_debugger(self).running:
raise RuntimeError(
"Cannot enable a breakpoint while the target process is running.",
)
self.enabled = True
self._changed = True
[docs]
def disable(self: Breakpoint) -> None:
"""Disable the breakpoint."""
if provide_internal_debugger(self).running:
raise RuntimeError(
"Cannot disable a breakpoint while the target process is running.",
)
self.enabled = False
self._changed = True
[docs]
def hit_on(self: Breakpoint, thread_context: ThreadContext) -> bool:
"""Returns whether the breakpoint has been hit on the given thread context."""
return self.enabled and thread_context.instruction_pointer == self.address
def __hash__(self: Breakpoint) -> int:
"""Hash the breakpoint by its address, so that it can be used in sets and maps correctly."""
return hash(self.address)