Source code for libdebug.utils.debugger_wrappers

#
# This file is part of libdebug Python library (https://github.com/libdebug/libdebug).
# Copyright (c) 2024 Gabriele Digregorio, Roberto Alessandro Bertolini. All rights reserved.
# Licensed under the MIT license. See LICENSE file in the project root for details.
#

from __future__ import annotations

from functools import wraps
from typing import TYPE_CHECKING

if TYPE_CHECKING:
    from libdebug.debugger.internal_debugger import InternalDebugger
    from libdebug.state.thread_context import ThreadContext


[docs] def change_state_function_process(method: callable) -> callable: """Decorator to perfom control flow checks before executing a method.""" @wraps(method) def wrapper(self: InternalDebugger, *args: ..., **kwargs: ...) -> ...: if not self.instanced: raise RuntimeError( "Process not running. Did you call run()?", ) # We have to ensure that the process is stopped before executing the method self._ensure_process_stopped() # We have to ensure that at least one thread is alive before executing the method if self.threads[0].dead: raise RuntimeError("All threads are dead.") return method(self, *args, **kwargs) return wrapper
[docs] def change_state_function_thread(method: callable) -> callable: """Decorator to perfom control flow checks before executing a method.""" @wraps(method) def wrapper( self: InternalDebugger, thread: ThreadContext, *args: ..., **kwargs: ... ) -> ...: if not self.instanced: raise RuntimeError( "Process not running. Did you call run()?", ) # We have to ensure that the process is stopped before executing the method self._ensure_process_stopped() # We have to ensure that at least one thread is alive before executing the method if thread.dead: raise RuntimeError("The threads is dead.") return method(self, thread, *args, **kwargs) return wrapper
[docs] def background_alias(alias_method: callable) -> callable: """Decorator that automatically resolves the call to a different method if coming from the background thread.""" # This is the stupidest thing I've ever seen. Why Python, why? def _background_alias(method: callable) -> callable: @wraps(method) def inner(self: InternalDebugger, *args: ..., **kwargs: ...) -> ...: if self._is_in_background(): return alias_method(self, *args, **kwargs) return method(self, *args, **kwargs) return inner return _background_alias