@@ -665,6 +665,48 @@ def exposed_stop(self):
665665 # Handle stop() call from the server.
666666 return self .stop ()
667667
668+ class FinishBreakpoint :
669+ """Mirror of ``gdb.FinishBreakpoint`` class.
670+
671+ See https://sourceware.org/gdb/onlinedocs/gdb/Finish-Breakpoints-in-Python.html
672+ for more information.
673+ """
674+
675+ def __init__ (self , conn , * args , ** kwargs ):
676+ """Do not create instances of this class directly.
677+
678+ Use ``pwnlib.gdb.Gdb.FinishBreakpoint`` instead.
679+ """
680+ # Creates a real finish breakpoint and connects it with this mirror
681+ self .conn = conn
682+ self .server_breakpoint = conn .root .set_finish_breakpoint (
683+ self , hasattr (self , 'stop' ), hasattr (self , 'out_of_scope' ),
684+ * args , ** kwargs )
685+
686+ def __getattr__ (self , item ):
687+ """Return attributes of the real breakpoint."""
688+ if item in (
689+ '____id_pack__' ,
690+ '__name__' ,
691+ '____conn__' ,
692+ 'stop' ,
693+ 'out_of_scope' ,
694+ ):
695+ # Ignore RPyC netref attributes.
696+ # Also, if stop() or out_of_scope() are not defined, hasattr() call
697+ # in our __init__() will bring us here. Don't contact the
698+ # server in this case either.
699+ raise AttributeError ()
700+ return getattr (self .server_breakpoint , item )
701+
702+ def exposed_stop (self ):
703+ # Handle stop() call from the server.
704+ return self .stop ()
705+
706+ def exposed_out_of_scope (self ):
707+ # Handle out_of_scope() call from the server.
708+ return self .out_of_scope ()
709+
668710class Gdb :
669711 """Mirror of ``gdb`` module.
670712
@@ -682,8 +724,12 @@ def __init__(self, conn):
682724 class _Breakpoint (Breakpoint ):
683725 def __init__ (self , * args , ** kwargs ):
684726 super ().__init__ (conn , * args , ** kwargs )
727+ class _FinishBreakpoint (FinishBreakpoint ):
728+ def __init__ (self , * args , ** kwargs ):
729+ super ().__init__ (conn , * args , ** kwargs )
685730
686731 self .Breakpoint = _Breakpoint
732+ self .FinishBreakpoint = _FinishBreakpoint
687733 self .stopped = Event ()
688734
689735 def stop_handler (event ):
0 commit comments