{"id":16543649,"url":"https://github.com/cs01/pygdbmi","last_synced_at":"2025-05-16T04:00:16.677Z","repository":{"id":11157420,"uuid":"68560140","full_name":"cs01/pygdbmi","owner":"cs01","description":"A library to parse gdb mi output and interact with gdb subprocesses","archived":false,"fork":false,"pushed_at":"2023-12-27T07:14:51.000Z","size":7245,"stargazers_count":232,"open_issues_count":21,"forks_count":48,"subscribers_count":12,"default_branch":"master","last_synced_at":"2025-05-14T07:58:01.346Z","etag":null,"topics":["backend","frontend","gdb","gdb-commands","gdb-mi","json-serializable","parser","parser-library","python","subprocess"],"latest_commit_sha":null,"homepage":"https://cs01.github.io/pygdbmi","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/cs01.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2016-09-19T02:00:28.000Z","updated_at":"2025-05-02T04:05:47.000Z","dependencies_parsed_at":"2024-06-18T13:54:02.266Z","dependency_job_id":"7b900d96-863e-45ba-8be6-2c8f5437d44a","html_url":"https://github.com/cs01/pygdbmi","commit_stats":{"total_commits":130,"total_committers":16,"mean_commits":8.125,"dds":0.6,"last_synced_commit":"c1582bab8358601d20826b3a4fa97d548b4f3c0f"},"previous_names":[],"tags_count":20,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cs01%2Fpygdbmi","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cs01%2Fpygdbmi/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cs01%2Fpygdbmi/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cs01%2Fpygdbmi/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/cs01","download_url":"https://codeload.github.com/cs01/pygdbmi/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254464890,"owners_count":22075570,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["backend","frontend","gdb","gdb-commands","gdb-mi","json-serializable","parser","parser-library","python","subprocess"],"created_at":"2024-10-11T19:00:37.617Z","updated_at":"2025-05-16T04:00:16.292Z","avatar_url":"https://github.com/cs01.png","language":"Python","readme":"\u003ch1 align=\"center\"\u003e\npygdbmi - Get Structured Output from GDB's Machine Interface\n\u003c/h1\u003e\n\n\u003cp align=\"center\"\u003e\n\n\u003ca href=\"https://github.com/cs01/pygdbmi/actions\"\u003e\n\u003cimg src=\"https://github.com/cs01/pygdbmi/workflows/Tests/badge.svg?branch=master\" alt=\"Test status\" /\u003e\u003c/a\u003e\n\n\u003ca href=\"https://badge.fury.io/py/pygdbmi\"\u003e\n\u003cimg src=\"https://badge.fury.io/py/pygdbmi.svg\" alt=\"PyPI version\"/\u003e\u003c/a\u003e\n\n\u003c/p\u003e\n\n**Documentation** [https://cs01.github.io/pygdbmi](https://cs01.github.io/pygdbmi)\n\n**Source Code** [https://github.com/cs01/pygdbmi](https://github.com/cs01/pygdbmi)\n\n---\n\nPython (**py**) [**gdb**](https://www.gnu.org/software/gdb/) machine interface [(**mi**)](https://sourceware.org/gdb/onlinedocs/gdb/GDB_002fMI.html)\n\n\u003e GDB/MI is a line based machine oriented text interface to GDB and is activated by specifying using the --interpreter command line option (see Mode Options). It is specifically intended to support the development of systems which use the debugger as just one small component of a larger system.\n\n## What's in the box?\n\n1.  A function to parse gdb machine interface string output and return structured data types (Python dicts) that are JSON serializable. Useful for writing the backend to a gdb frontend. For example, [gdbgui](https://github.com/cs01/gdbgui) uses pygdbmi on the backend.\n2.  A Python class to control and interact with gdb as a subprocess\n\nTo get [machine interface](https://sourceware.org/gdb/onlinedocs/gdb/GDB_002fMI.html) output from gdb, run gdb with the `--interpreter=mi2` flag like so:\n\n```\ngdb --interpreter=mi2\n```\n\n## Installation\n\n    pip install pygdbmi\n\n## Compatibility\n\n### Operating Systems\n\nCross platform support for Linux, macOS and Windows\n\n- Linux/Unix\n\n  Ubuntu 14.04 and 16.04 have been tested to work. Other versions likely work as well.\n\n- macOS\n\n  Note: the error `please check gdb is codesigned - see taskgated(8)` can be fixed by codesigning gdb with [these instructions](http://andresabino.com/2015/04/14/codesign-gdb-on-mac-os-x-yosemite-10-10-2/). If the error is not fixed, please [create an issue in github](https://github.com/cs01/pygdbmi/issues).\n\n- Windows\n\n  Windows 10 has been tested to work with MinGW and cygwin.\n\n### gdb versions\n\n- gdb 7.6+ has been tested. Older versions may work as well.\n\n## Examples\n\ngdb mi defines a syntax for its output that is suitable for machine readability and scripting: [example output](https://sourceware.org/gdb/onlinedocs/gdb/GDB_002fMI-Simple-Examples.html#GDB_002fMI-Simple-Examples):\n\n```\n-\u003e -break-insert main\n\u003c- ^done,bkpt={number=\"1\",type=\"breakpoint\",disp=\"keep\",\nenabled=\"y\",addr=\"0x08048564\",func=\"main\",file=\"myprog.c\",\nfullname=\"/home/myprog.c\",line=\"68\",thread-groups=[\"i1\"],\ntimes=\"0\"}\n\u003c- (gdb)\n```\n\nUse `pygdbmi.gdbmiparser.parse_response` to turn that string output into a JSON serializable dictionary\n\n```python\nfrom pygdbmi import gdbmiparser\nfrom pprint import pprint\nresponse = gdbmiparser.parse_response('^done,bkpt={number=\"1\",type=\"breakpoint\",disp=\"keep\", enabled=\"y\",addr=\"0x08048564\",func=\"main\",file=\"myprog.c\",fullname=\"/home/myprog.c\",line=\"68\",thread-groups=[\"i1\"],times=\"0\"')\npprint(response)\npprint(response)\n# Prints:\n# {'message': 'done',\n#  'payload': {'bkpt': {'addr': '0x08048564',\n#                       'disp': 'keep',\n#                       'enabled': 'y',\n#                       'file': 'myprog.c',\n#                       'fullname': '/home/myprog.c',\n#                       'func': 'main',\n#                       'line': '68',\n#                       'number': '1',\n#                       'thread-groups': ['i1'],\n#                       'times': '0',\n#                       'type': 'breakpoint'}},\n#  'token': None,\n#  'type': 'result'}\n```\n\n## Programmatic Control Over gdb\n\nBut how do you get the gdb output into Python in the first place? If you want, `pygdbmi` also has a class to control gdb as subprocess. You can write commands, and get structured output back:\n\n```python\nfrom pygdbmi.gdbcontroller import GdbController\nfrom pprint import pprint\n\n# Start gdb process\ngdbmi = GdbController()\nprint(gdbmi.command)  # print actual command run as subprocess\n# Load binary a.out and get structured response\nresponse = gdbmi.write('-file-exec-file a.out')\npprint(response)\n# Prints:\n# [{'message': 'thread-group-added',\n#   'payload': {'id': 'i1'},\n#   'stream': 'stdout',\n#   'token': None,\n#   'type': 'notify'},\n#  {'message': 'done',\n#   'payload': None,\n#   'stream': 'stdout',\n#   'token': None,\n#   'type': 'result'}]\n```\n\nNow do whatever you want with gdb. All gdb commands, as well as gdb [machine interface commands](\u003c(https://sourceware.org/gdb/onlinedocs/gdb/GDB_002fMI-Input-Syntax.html#GDB_002fMI-Input-Syntax)\u003e) are acceptable. gdb mi commands give better structured output that is machine readable, rather than gdb console output. mi commands begin with a `-`.\n\n```python\nresponse = gdbmi.write('-break-insert main')  # machine interface (MI) commands start with a '-'\nresponse = gdbmi.write('break main')  # normal gdb commands work too, but the return value is slightly different\nresponse = gdbmi.write('-exec-run')\nresponse = gdbmi.write('run')\nresponse = gdbmi.write('-exec-next', timeout_sec=0.1)  # the wait time can be modified from the default of 1 second\nresponse = gdbmi.write('next')\nresponse = gdbmi.write('next', raise_error_on_timeout=False)\nresponse = gdbmi.write('next', raise_error_on_timeout=True, timeout_sec=0.01)\nresponse = gdbmi.write('-exec-continue')\nresponse = gdbmi.send_signal_to_gdb('SIGKILL')  # name of signal is okay\nresponse = gdbmi.send_signal_to_gdb(2)  # value of signal is okay too\nresponse = gdbmi.interrupt_gdb()  # sends SIGINT to gdb\nresponse = gdbmi.write('continue')\nresponse = gdbmi.exit()\n```\n\n## Parsed Output Format\n\nEach parsed gdb response consists of a list of dictionaries. Each dictionary has keys `message`, `payload`, `token`, and `type`.\n\n- `message` contains a textual message from gdb, which is not always present. When missing, this is `None`.\n- `payload` contains the content of gdb's output, which can contain any of the following: `dictionary`, `list`, `string`. This too is not always present, and can be `None` depending on the response.\n- `token` If an input command was prefixed with a (optional) token then the corresponding output for that command will also be prefixed by that same token. This field is only present for pygdbmi output types `nofity` and `result`. When missing, this is `None`.\n\nThe `type` is defined based on gdb's various [mi output record types](\u003c(https://sourceware.org/gdb/onlinedocs/gdb/GDB_002fMI-Output-Records.html#GDB_002fMI-Output-Records)\u003e), and can be\n\n- `result` - the result of a gdb command, such as `done`, `running`, `error`, etc.\n- `notify` - additional async changes that have occurred, such as breakpoint modified\n- `console` - textual responses to cli commands\n- `log` - debugging messages from gdb's internals\n- `output` - output from target\n- `target` - output from remote target\n- `done` - when gdb has finished its output\n\n## Contributing\n\nDocumentation fixes, bug fixes, performance improvements, and functional improvements are welcome. You may want to create an issue before beginning work to make sure I am interested in merging it to the master branch.\n\npygdbmi uses [nox](https://github.com/theacodes/nox) for automation.\n\nSee available tasks with\n\n```\nnox -l\n```\n\nRun tests and lint with\n\n```\nnox -s tests\nnox -s lint\n```\n\nPositional arguments passed to `nox -s tests` are passed directly to `pytest`. For instance, to run only the parse tests use\n\n```\nnox -s tests -- tests/test_gdbmiparser.py\n```\n\nSee [`pytest`'s documentation](https://docs.pytest.org/) for more details on how to run tests.\n\nTo format code using the correct settings use\n\n```\nnox -s format\n```\n\nOr, to format only specified files, use\n\n```\nnox -s format -- example.py pygdbmi/IoManager.py\n```\n\n### Making a release\n\nOnly maintainers of the [pygdbmi package on PyPi](https://pypi.org/project/pygdbmi/) can make a release.\n\nIn the following steps, replace these strings with the correct values:\n\n- `\u003cREMOTE\u003e` is the name of the remote for the main pygdbmi repository (for instance, `origin`)\n- `\u003cVERSION\u003e` is the version number chosen in step 2.\n\nTo make a release:\n\n1. Checkout the `master` branch and pull from the main repository with `git pull \u003cREMOTE\u003e master`\n2. Decide the version number for the new release; we follow\n   [Semantic Versioning](https://semver.org/) but prefixing the version with `0.`: given a version\n   number _0.SECOND.THIRD.FOURTH_, increment the:\n   - _SECOND_ component when you make incompatible API changes\n   - _THIRD_ component when you add functionality in a backwards compatible manner\n   - _FOURTH_ component when you make backwards compatible bug fixes\n3. Update `CHANGELOG.md` to list the chosen version number instead of `## dev`\n4. Update `__version__` in `pygdbmi/__init__.py` to the chosen version number\n5. Create a branch, for instance using `git checkout -b before-release-\u003cVERSION\u003e`\n6. Commit your changes, for instance using `git commit -a -m 'Bump version to \u003cVERSION\u003e for release'`\n7. Check that the docs look fine by serving them locally with `nox -s serve_docs`\n8. Push the branch, for instance with `git push --set-upstream \u003cREMOTE\u003e before-release-\u003cVERSION\u003e`\n9. If tests pass on the PR you created, you can merge into `master`\n10. Go to the [new release page](https://github.com/cs01/pygdbmi/releases/new) and prepare the\n    release:\n    - Add a tag in the form `v\u003cVERSION\u003e` (for example `v0.1.2.3`)\n    - Set the title to `pygdbmi v\u003cVERSION\u003e` (for example `pygdbmi v0.1.2.3`)\n    - Copy and paste the section for the new release only from `CHANGELOG.md` excluding the line\n      with the version number\n    - Press “Publish release”\n10. Publish the release to PyPI with `nox -s publish`\n11. Publish the docs with `nox -s publish_docs`\n11. Verify that the [PyPi page for pygdbmi](https://pypi.org/project/pygdbmi/) looks correct\n12. Verify that the [published docs](https://cs01.github.io/pygdbmi/) look correct\n13. Prepare for changes for the next release by adding something like this above the previous\n    entries in `CHANGELOG.md` (where `\u003cVERSION+1\u003e` is `\u003cVERSION\u003e` with the last digit increaded\n    by 1):\n\n    ```\n    ## \u003cVERSION+1\u003e.dev0\n\n    - *Replace this line with new entries*\n    ```\n\n14. Create a branch for the changes with `git checkout -b after-release-\u003cVERSION\u003e`\n15. Commit the change with `git commit -m 'Prepare for work on the next release' CHANGELOG.md`\n16. Push the branch with `git push --set-upstream \u003cREMOTE\u003e after-release-\u003cVERSION\u003e`\n17. If tests pass, merge into `master`\n\n## Similar projects\n\n- [tsgdbmi](https://github.com/Guyutongxue/tsgdbmi) A port of pygdbmi to TypeScript\n- [danielzfranklin/gdbmi](https://github.com/danielzfranklin/gdbmi) A port of pygdbmi to Rust\n\n## Projects Using pygdbmi\n\n- [gdbgui](https://github.com/cs01/gdbgui) implements a browser-based frontend to gdb, using pygdbmi on the backend\n- [PINCE](https://github.com/korcankaraokcu/PINCE) is a gdb frontend that aims to provide a reverse engineering tool and a reusable library focused on games. It uses pygdbmi to parse gdb/mi based output for some functions\n- [avatar²](https://github.com/avatartwo/avatar2) is an orchestration framework for reversing and analysing firmware of embedded devices. It utilizes pygdbmi for internal communication to different analysis targets.\n- [UDB](https://undo.io/udb) is a proprietary time-travel debugger for C and C++ based on GDB. It uses pygdbmi in its extensive test suite to parse the debugger's output.\n- [pwndbg-gui](https://github.com/AlEscher/pwndbg-gui) is a user-friendly graphical interface for [pwndbg](https://github.com/pwndbg/pwndbg), a tool that simplifies exploit development and reverse engineering with GDB. It uses pygdbmi to interact with GDB and get structured responses.\n- Know of another project? Create a PR and add it here.\n\n## Authors\n\n- [Chad Smith](https://github.com/cs01) (main author and creator).\n- [Marco Barisione](http://www.barisione.org/) (co-maintainer).\n- [The community](https://github.com/cs01/pygdbmi/graphs/contributors). Thanks especially to @mariusmue, @bobthekingofegypt, @mouuff, and @felipesere.\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcs01%2Fpygdbmi","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcs01%2Fpygdbmi","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcs01%2Fpygdbmi/lists"}