gdbremote
Tool
tools/live/gdbremote.py(library, The running game). A small client for the GDB remote protocol: registers, memory, breakpoints, always a detach.
A library: other tools and your own scripts import it. Source on GitHub.
Its own help
This is the help text in the tool itself, as ./gameframe tool gdbremote prints it.
text
A small client for the GDB remote protocol: registers, memory, breakpoints, always a detach.
from gdbremote import Remote
with Remote.connect('localhost', 54101) as r: # leaves the program running on exit
print(r.stop) # the stop that the attach caused
regs = r.registers() # {'rip': 0x140206310, ...}
data = r.read(0x140000000, 64)
hit = r.run_to([0x140118340], timeout=10) # None when no breakpoint was hit
r.step_over_breakpoint() # before the next run_to
r.run_to([0x1401a0000], 10, kind=2, length=4) # a write watchpoint
r.libraries() # [(name, base)] when the stub sends them
Inputs: the host and port of any GDB stub: winedbg --gdb (see winegdb.py), QEMU's -gdb,
VMware Fusion's debugStub, 86Box's GDB stub. Outputs: Python values; no printing.
Leaving the `with` block, normally or on an error or Ctrl-C, stops the program if it is
running, removes every breakpoint this client set and sends a detach. When the stub refuses a
software breakpoint (Z0), the client writes an int3 byte itself and puts the original back. A breakpoint left in
the program after the client goes away stays in its code as an int3, and the program stops or
dies when it reaches it.
The register names and sizes come from the stub's target description (qXfer:features). A stub
without one gets GDB's amd64 order for a 'g' reply of 8-byte registers, else i386's.
What it does not do: writing memory or registers, non-stop mode, more than one process. Standard library only.