{"id":26131934,"url":"https://github.com/trepan-debuggers/trepan-xpy","last_synced_at":"2025-07-06T21:32:32.716Z","repository":{"id":66224987,"uuid":"263662925","full_name":"Trepan-Debuggers/trepan-xpy","owner":"Trepan-Debuggers","description":"Debugger in the Trepan family for x-python","archived":false,"fork":false,"pushed_at":"2025-06-20T15:47:06.000Z","size":4488,"stargazers_count":17,"open_issues_count":0,"forks_count":2,"subscribers_count":5,"default_branch":"master","last_synced_at":"2025-06-20T16:47:19.941Z","etag":null,"topics":["debugger","python3"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Trepan-Debuggers.png","metadata":{"files":{"readme":"README.md","changelog":"ChangeLog","contributing":null,"funding":null,"license":null,"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,"zenodo":null}},"created_at":"2020-05-13T15:03:13.000Z","updated_at":"2025-06-20T15:47:09.000Z","dependencies_parsed_at":"2024-05-06T17:47:18.370Z","dependency_job_id":"5941f5af-8864-4c28-b521-97923d6ef243","html_url":"https://github.com/Trepan-Debuggers/trepan-xpy","commit_stats":null,"previous_names":["trepan-debuggers/trepan-xpy"],"tags_count":7,"template":false,"template_full_name":null,"purl":"pkg:github/Trepan-Debuggers/trepan-xpy","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Trepan-Debuggers%2Ftrepan-xpy","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Trepan-Debuggers%2Ftrepan-xpy/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Trepan-Debuggers%2Ftrepan-xpy/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Trepan-Debuggers%2Ftrepan-xpy/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Trepan-Debuggers","download_url":"https://codeload.github.com/Trepan-Debuggers/trepan-xpy/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Trepan-Debuggers%2Ftrepan-xpy/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":263975344,"owners_count":23538308,"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":["debugger","python3"],"created_at":"2025-03-10T22:21:23.130Z","updated_at":"2025-07-06T21:32:32.676Z","avatar_url":"https://github.com/Trepan-Debuggers.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"Abstract\n========\n\nThis is a gdb-like debugger focusing on Python bytecode. So far as I know, this is the *only* debugger available specifically for Python bytecode.\n\nHowever to do this, you need to use underneath [x-python](https://pypi.org/project/x-python): a Python Interpreter written in Python.\n\nThis project builds off of a previous Python 3 debugger called [trepan3k](https://pypi.org/project/trepan3k/).\n\nExample\n=======\n\n![demo](https://github.com/rocky/trepan-xpy/blob/master/screenshots/trepan-xpy-demo1.gif)\n\nBelow we'll try to break down what's going on above.\n\nWe'll invoke the a Greatest Common Divisors program `gcd.py` using our debugger. The source is found in\n[test/example/gcd.py](https://github.com/rocky/trepan-xpy/blob/master/test/example/gcd.py).\n\nIn this section we'll these some interesting debugger commands that are not common in Python debuggers:\n\n- `stepi` to step a bytecode instruction\n- `set loglevel` to show a the x-python log \"info\"-level log  tracing.\n- `info stack` to show the current stack frame evaluation stack\n\n\u003cpre\u003e$ \u003cb\u003etrepan-xpy test/example/gcd.py 3 5\u003c/b\u003e\n Running x-python test/example/gcd.py with ('3', '5')\n (test/example/gcd.py:10): \u0026lt;module\u0026gt;\n -\u0026gt; 2 \u0026quot;\u0026quot;\u0026quot;\n (trepan-xpy)\n \u003c/pre\u003e\n\nAbove we are stopped before we have even run the first instruction. The `-\u003e` icon before `2` means we are stopped calling a new frame.\n\n\u003cpre\u003e(trepan-xpy) \u003cb\u003estep\u003c/b\u003e\n(test/example/gcd.py:2): \u0026lt;module\u0026gt;\n-- 2 \u003cfont color=\"#C4A000\"\u003e\u0026quot;\u0026quot;\u0026quot;Greatest Common Divisor\u0026quot;\u0026quot;\u0026quot;\u003c/font\u003e\u003cbr\u003e @  0: \u003cfont color=\"#4E9A06\"\u003eLOAD_CONST\u003c/font\u003e \u003cfont color=\"#C4A000\"\u003e\u0026apos;Greatest Common Divisor\u0026apos;\u003c/font\u003e\n\u003c/pre\u003e\n\nOk, now we are stopped before the first instruction `LOAD_CONST` which will load a constant onto the evaluation stack. The icon changed from `-\u003e 2` to `-- 2` which indicates we are on a line-number boundary at line 2.\n\nThe Python construct we are about to perform is setting the program's docstring. Let's see how that is implemented.\n\nFirst we see that the variable `__doc__` which will eventually hold the docstring isn't set:\n\nWe see here that the first part is loading this constant onto an\nevaluation stack.\n\nAt this point, to better see the execution progress we'll issue the command `set loglevel` which will show the instructions as we step along.\n\nLike *trepan3k*, *trepan-xpy* has extensive nicely formatted help right in the debugger. Let's get the help for the `set loglevel` command:\n\n\u003cpre\u003e(trepan-xpy) \u003cb\u003ehelp set loglevel\u003c/b\u003e\n\u003cb\u003eset loglevel\u003c/b\u003e [ \u003cb\u003eon\u003c/b\u003e | \u003cb\u003eoff\u003c/b\u003e | \u003cb\u003edebug\u003c/b\u003e | \u003cb\u003einfo\u003c/b\u003e ]\n\nShow loglevel PyVM logger messages. Initially logtracing is off.\n\nHowever running set loglevel will turn it on and set the log level to debug.\nSo it's the same thing as set loglevel debug.\n\nIf you want the less verbose messages, use info. And to turn off, (except\ncritical errors), use off.\n\nExamples:\n\n     set loglevel         # turns x-python on info logging messages\n     set loglevel info    # same as above\n     set loglevel debug   # turn on info and debug logging messages\n     set loglevel off     # turn off all logging messages except critical ones\n\n\n\u003c/pre\u003e\n\nSo now lets's set that:\n\n\u003cpre\u003e(trepan-xpy) \u003cb\u003eset loglevel\u003c/b\u003e\n(trepan-xpy)\u003c/pre\u003e\n\nA rather unique command that you won\\'t find in most Python debuggers\nbut is in low-level debuggers is `stepi` which steps and instruction.\nLet's use that:\n\n\u003cpre\u003e(trepan-xpy) \u003cb\u003estepi\u003c/b\u003e\n(test/example/gcd.py:2 @2): \u0026lt;module\u0026gt;\n.. 2 \u0026quot;\u0026quot;\u0026quot;Greatest Common Divisor\u0026quot;\u0026quot;\u0026quot;\u003cbr/\u003e       @  2: STORE_NAME \u0026apos;Greatest Common Divisor\u0026apos;) \u003ci\u003e__doc__\u003c/i\u003e\n\u003c/pre\u003e\n\nThe `..` at the beginning indicates that we are on an instruction which\nis in between lines.\n\nWe\\'ve now loaded the docstring onto the evaluation stack with\n`LOAD_CONST` Let\\'s see the evaluation stack with `info stack`:\n\n\u003cpre\u003e(trepan-xpy) \u003cb\u003einfo stack\u003c/b\u003e\u003cbr/\u003e  0: \u0026lt;class \u0026apos;str\u0026apos;\u0026gt; \u0026apos;Greatest Common Divisor\u0026apos;\n\u003c/pre\u003e\n\nHere we have pushed the docstring for the program but haven\\'t yet\nstored that in `__doc__`. To see this, can use the auto-eval feature of\n`trepan-xpy`: it will automatically evaluate strings it doesn\\'t\nrecognize as a debugger command:\n\n\u003cpre\u003e(trepan-xpy) \u003cb\u003e__doc__ is None\u003c/b\u003e\nTrue\n\u003c/pre\u003e\n\nLet's step the remaining instruction, `STORE_NAME` to complete the\ninstructions making up line 1.\n\n\u003cpre\u003etrepan-xpy) \u003cb\u003estepi\u003c/b\u003e\nINFO:xpython.vm:L. 10  @  4: LOAD_CONST 0\n(test/example/gcd.py:10 @4): \u0026lt;module\u0026gt;\n-- 10 import \u003cu\u003esys\u003c/u\u003e\u003cbr/\u003e   @  4: LOAD_CONST 0\n\u003c/pre\u003e\n\nThe leading `--` before `10 import`... indicates we are on a line\nboundary now. Let\\'s see the stack now that we have run `STORE_NAME`:\n\n\u003cpre\u003e(trepan-xpy) \u003cb\u003einfo stack\u003c/b\u003e\n\u003ci\u003eEvaluation stack is empty\u003c/i\u003e\n\u003c/pre\u003e\n\nAnd to see that we\\'ve stored this in `__doc__` we can run `eval` to see\nits value:\n\n\u003cpre\u003e(trepan-xpy) \u003cb\u003eeval __doc__\u003c/b\u003e\n\"Greatest Common Divisor\"\n\u003c/pre\u003e\n\n(Entering just `_doc_` is the same thing as `eval __doc__` when\nauto-evaluation is on.\n\nNow let\\'s step a statement (not instructions), to see how a module\nbecomes visable.\n\n\u003cpre\u003e(trepan-xpy) \u003cb\u003estep\u003c/b\u003e\nINFO:xpython.vm:       @  6: LOAD_CONST None\nINFO:xpython.vm:       @  8: IMPORT_NAME (0, None) \u003ci\u003esys\u003c/i\u003e\nINFO:xpython.vm:       @ 10: STORE_NAME (\u0026lt;module \u0026apos;sys\u0026apos; (built-in)\u0026gt;)\nINFO:xpython.vm:L. 12  @ 12: LOAD_CONST \u0026lt;code object check_args at 0x7f2a0a286f60, file \u0026quot;test/example/gcd.py\u0026quot;, line 12\u0026gt;\n(test/example/gcd.py:12 @12): \u0026lt;module\u0026gt;\n-- 12 \u003cb\u003edef\u003c/b\u003e \u003ci\u003echeck_args\u003c/i\u003e():\u003c/br\u003e   @ 12: LOAD_CONST \u0026lt;code object check_args at 0...est/example/gcd.py\u0026quot;, line 12\u0026gt;\n\u003c/pre\u003e\n\nThe `INFO` are initiated by the VM interpreter. As a result of the `set loglevel` the interpreters `logger` log level was increased. This in turn causes a callback is made to a formatting routine provided by the debugger to nicly colorize the information. And that is why parts of this are colorized in a terminal session. In `x-python` you can get the same information, just not colorized.\n\nOne thing to note is the value after the operand and in parenthesis, like after `STORE NAME`. Compare that line with what you\\'ll see from a static disassembly like Python\\'s `dis` or `xdis` version of that:\n\n    10 STORE_NAME                1 (sys)\n\nIn a static disassembler, the \\\"1\\\" indicates the name index in the code object. The value in parenthesis is what that name, here at index 1 is, namely `sys`.\n\nIn `trepan-xpy` and `x-python` however we omit the name index, 1, since that isn't of much interest. Instead we show that dynamic stack entries or operands that `STORE_NAME` is going to work on. In particular the object that is going to be stored in variable `sys` is the built-in module `sys`.\n\nNow let's step another statement to see how a function becomes available:\n\n\u003cpre\u003etrepan-xpy) step\nINFO:xpython.vm:       @ 14: LOAD_CONST \u0026apos;check_args\u0026apos;\u003c/font\u003e\nINFO:xpython.vm:       @ 16: MAKE_FUNCTION (check_args) Neither defaults, keyword-only args, annotations, nor closures\nINFO:xpython.vm:       @ 18: STORE_NAME (\u0026lt;Function check_args at 0x7fdb1d4d49f0\u0026gt;) \u003cu\u003echeck_args\u003c/u\u003e\nINFO:xpython.vm:L. 25  @ 20: LOAD_CONST \u0026lt;code object gcd at 0x7fdb1d55fed0, file \u0026quot;test/example/gcd.py\u0026quot;, line 25\u0026gt;\n(test/example/gcd.py:25 @20): \u0026lt;module\u0026gt;\n-- 25 \u003cb\u003edef\u003c/b\u003e gcd(a,b):\u003c/br\u003e       @ 20: LOAD_CONST \u0026lt;code object gcd at 0x7fdb1d...est/example/gcd.py\u0026quot;, line 25\u0026gt;\n\u003c/pre\u003e\n\nA difference between a dynamic language like Python and a statically compiled language like C, or Java is that there is no linking step in the complation; modules and functions are *imported* or created and linked as part of the execution of the code.\n\nNotice again what's in the parenthesis after the opcode and how that differs from a static disassembly. For comparison here is what 2nd and 3rd instruction look like from `pydisasm`:\n\n    16 MAKE_FUNCTION             0 (Neither defaults, keyword-only args, annotations, nor closures)\n    18 STORE_NAME                2 (check_args)\n\nAgain, indices into a name table are dropped and in their place are the evaluation stack items. For `MAKE_FUNCTION` the name of the function that is created is shown; while for `STORE_NAME`, as before, the item that gets stored (a function object) is shown.\n\nThe rest of the screencast shows that in addition to the `step` (step into) and `stepi` (step instruction) debugger commands there is a `next` or step over debugger command, and a slightly buggy `finish` (step out) command\n\nI don't have breakpoints hooked in yet.\n\nBut in contrast to any other Python debugger I know about, we can cause an immediate return with a value and that is shown in the screencast.\n\nWe've only show a few of the many debugger features.\n\nBytecode-specific commands\n==========================\n\nHere are some interesting commands not typically found in Python debuggers, like `pdb`\n\n- `info blocks` lets you see the block stack\n- `set pc \u003coffset\u003e` lets you set the Program counter within the frame\n- `set autopc` runs `info pc` to show the debugged program's program counter before each time the debugger's command-loop REPL is run.\n- `set autostack` runs `info stack` to show the debugged program's evaluation stack before each time the debugger's command-loop REPL is run.\n- `vmstack {peek | push, pop}` - inspects or modifies evaluation stack\n\nSee Also\n========\n\n- [xpython](https://pypi.org/project/x-python/) : CPython written in Python\n- [trepan3k](https://pypi.org/project/trepan3k/) : trepan debugger for  Python 3.x and its extensive  [documentation](https://python3-trepan.readthedocs.io/en/latest/).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftrepan-debuggers%2Ftrepan-xpy","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftrepan-debuggers%2Ftrepan-xpy","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftrepan-debuggers%2Ftrepan-xpy/lists"}