gdbrpc
A Python-based RPC (Remote Procedure Call) framework for GDB (GNU Debugger) that enables programmatic control and automation of debugging sessions.
Table of Contents
- gdbrpc
Overview
gdbrpc provides a client-server architecture that allows you to control GDB instances remotely through a simple Python API. It's designed to be framework-agnostic and can be used with any GDB-compatible debugger, not limited to any specific operating system or embedded platform.
Features
- Remote GDB Control: Execute GDB commands remotely via socket communication
- Bidirectional Communication: Client-server architecture with full duplex support
- Command Serialization: Uses cloudpickle for robust serialization of Python objects
- Interactive CLI: Built-in command-line interface for quick debugging sessions
- Extensible: Easy to integrate into custom debugging workflows and automation scripts
Installation
From PyPI
pip install gdbrpc
From Source
cd gdbrpc
pip install -e .
Requirements
- Python >= 3.10
- GDB with Python support
- cloudpickle >= 0.0.0
Quick Start
Starting the GDB Server
Within a GDB session, use the GDB commands (after importing gdbrpc):
(gdb) py import gdbrpc
(gdb) gdbrpc start
(gdb) gdbrpc start --port 20820 --host 0.0.0.0
(gdb) gdbrpc status
(gdb) gdbrpc stop
Using the Python Client
from gdbrpc import Client
from gdbrpc.utils import ShellExec
# Create and connect to the GDB server
client = Client(host="localhost", port=20819)
client.connect()
# Execute GDB commands
response = client.call(ShellExec("info threads"))
print(response)
# Get backtrace
bt = client.call(ShellExec("backtrace"))
print(bt)
# Evaluate expressions
result = client.call(ShellExec("print my_variable"))
print(result)
# Execute shell commands (prefix with !)
output = client.call(ShellExec("!ls -la"))
print(output)
# Close connection
client.disconnect()
Using the CLI
Load the current source checkout in GDB with the repository initializer:
source /path/to/gdbrpc/gdbinit.py
gdbrpc start --host 127.0.0.1 --port 20819
Run the module or installed gdbrpc command without an action to open the
interactive client:
python3 -m gdbrpc --host localhost --port 20819
gdbrpc --host localhost --port 20819
For automation, repeat -c to send complete GDB command units in one RPC.
Each unit may itself contain native multiline GDB syntax. A failed unit is
reported, and the remaining units still run:
gdbrpc --port 20819 -c 'help' -c 'bt' -c 'info registers'
gdbrpc --port 20819 \
-c $'define dump_state\n bt\n info registers\nend' \
-c 'dump_state'
-f accepts either a local Python file or inline Python source. An existing
file is read locally; otherwise the argument is compiled as source in GDB:
gdbrpc --port 20819 -f inspect.py
gdbrpc --port 20819 -f 'import gdb; print(gdb.newest_frame().name())'
gdbrpc --port 20819 -f $'import gdb\nprint(gdb.selected_thread())'
Add --wait when the script registers a GDB callback. The CLI remains
connected until the script calls the injected emit(value) function once:
# wait_stop.py
import gdb
def on_stop(event):
gdb.events.stop.disconnect(on_stop)
emit(str(event))
gdb.events.stop.connect(on_stop)
gdbrpc --port 20819 -f wait_stop.py --wait
A waiting script must unregister its GDB callback before calling emit.
One CLI invocation receives one emitted value; continuous event streaming is
not supported.
TODO
- make the CLI provide the same experience as the gdb CLI
- auto-completion
- command history reading
- improve network transmission
- improving security during deserialization
Architecture
Components
- Server: Runs inside GDB process, listens for incoming connections
- Client: Python client that connects to the server and sends commands
- CLI: Interactive command-line interface built on top of the client
- Protocol: Custom protocol for request/response communication using cloudpickle
Communication Flow
┌─────────────┐ Socket ┌─────────────┐
│ Client │◄──────────────────────►│ Server │
│ (Python) │ (Port 20819) │ (In GDB) │
└─────────────┘ └─────────────┘
│ │
│ Send Request │
│──────────────────────────────────────►│
│ │ Execute Command
│ │ in GDB Context
│ Response │
│◄──────────────────────────────────────│
│ │
API Reference
Client
Client(host="localhost", port=20819, logLevel=logging.INFO)
Create a new client instance.
Parameters:
host(str): Server hostname or IP address (default: "localhost")port(int): Server port number (default: 20819)logLevel(int): Logging level (default: logging.INFO)
connect() -> bool
Establish connection to the GDB server.
Returns: True if connection successful, False otherwise
call(request: Request, post_request: Optional[PostRequest] = None, timeout: float = 300) -> Any
Send a request to the GDB server and receive response.
Parameters:
request(Request): Request object to send (typicallyShellExecfor executing commands)post_request(Optional[PostRequest]): Optional callback request for async handlingtimeout(float): Request timeout in seconds (default: 300)
Returns: Response payload from the server
Example:
from gdbrpc import Client
from gdbrpc.utils import ShellExec
client = Client("localhost", 20819)
client.connect()
# Execute GDB command
result = client.call(ShellExec("info threads"))
print(result)
# Execute shell command (prefix with !)
result = client.call(ShellExec("!ls -la"))
print(result)
disconnect()
Close the connection to the server and cleanup resources.
Request Classes
ShellExec(command: str)
Request to execute a GDB command or shell command on the server.
Parameters:
command(str): Command to execute- GDB commands:
"info threads","backtrace","print variable" - Shell commands: prefix with
!orshell, e.g.,"!ls"or"shell pwd"
- GDB commands:
Example:
from gdbrpc.utils import ShellExec
# GDB command
gdb_request = ShellExec("backtrace full")
# Shell command
shell_request = ShellExec("!cat /proc/meminfo")
Request
Base class for all request types. Custom requests can be created by subclassing.
Methods:
__init__(): Initializes request with unique tag ID__call__(*args, **kwargs): Must be implemented by subclasses
PostRequest
Base class for requests with callbacks. Used for asynchronous request handling.
Methods:
__init__(): Initializes with finish event__call__(argument: Any): Must be implemented by subclassesfinish(threading.Event): Event to signal completion
Configuration
Server Configuration
The server can be configured when starting:
import logging
import gdbrpc
# Start with debug logging
gdbrpc.start_gdb_socket_server(
host="0.0.0.0", # Listen on all interfaces
port=20819,
logLevel=logging.DEBUG
)
Client Configuration
import logging
from gdbrpc import Client
from gdbrpc.utils import ShellExec
# Create client with custom log level
client = Client(
host="localhost",
port=20819,
logLevel=logging.DEBUG # Enable debug logging
)
client.connect()
# Custom timeout for specific requests
result = client.call(
ShellExec("interrupt"),
timeout=60 # Wait up to 60 seconds for this command
)
Troubleshooting
Server won't start
- Ensure GDB has Python support:
gdb --configuration | grep python - Check if port is already in use:
netstat -an | grep 20819 - Verify firewall settings allow the connection
Connection refused
- Verify server is running:
(gdb) gdbrpc status - Check host/port configuration matches between client and server
- Ensure network connectivity between client and server
Command execution fails
- Verify GDB is in correct state (e.g., program loaded, running)
- Check command syntax is correct for your GDB version
- Review server logs for detailed error messages
- Make sure python version GDB uses is same as client
Contributing
Contributions are welcome! Please feel free to submit pull requests or open issues for bugs and feature requests.
License
Licensed under the Apache License, Version 2.0. See the LICENSE file for details.
Related Projects
- GDB Python API Documentation
- pwndbg - GDB plugin for exploit development
- gdb-dashboard - Modular GDB dashboard
Support
For questions and support:
- Open an issue on the project repository
- Consult the GDB Python API documentation
- Review the examples in the
examples/directory
Metadata
Release files for gdbrpc 0.7.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| gdbrpc-0.7.0.tar.gz | 34.7 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| gdbrpc-0.7.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 70.8 kB
Release files / gdbrpc-0.7.0.tar.gz
| Download URL | gdbrpc-0.7.0.tar.gz |
|---|---|
| Size | 34.7 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
62e796e5977e9d8473c50ede7462491e5e747b8896f985686106a69a55663fd3
|
|
BLAKE2b-256 checksum How to use checksums |
47661d81ada564654b16f60a04f58e980a19e601354cf04ac5590d9d01338f02
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.14
|
Release files / gdbrpc-0.7.0-py3-none-any.whl
| Download URL | gdbrpc-0.7.0-py3-none-any.whl |
|---|---|
| Size | 36.1 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
397484cb77321c504625b4b59d9b4fc87be02c779097bcb2bd8da40f0e32588b
|
|
BLAKE2b-256 checksum How to use checksums |
912567d2cdf76aaac4aa533e1bce114313f5fa34c5e693cfeab07020fbc957bc
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.14
|