{ "info": { "author": "J\u00e9r\u00e9mie Lumbroso", "author_email": "lumbroso@cs.princeton.edu", "bugtrack_url": null, "classifiers": [ "License :: OSI Approved :: MIT License", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.7" ], "description": "# pyjdb\nPython interface with Java debugger through JDB.\n\n## Overview\n\nThe `JdbProcess` uses `pexpect` to attach to a `jdb` process and record all the information that is obtained.\n\nFor each instruction, we record a dictionary of the following format:\n```json\n{\n \"return\": 10000,\n \"thread\": \"main\",\n \"class.method\": \"IterPower.iterPower()\",\n \"method\": \"iterPower\",\n \"line\": 15,\n \"bci\": 17,\n \"instruction\": \"return result;\"\n}\n```\nFor each instruction, we can also obtain the dictionary of the current method's arguments, as well as all its local variables:\n```python\n({'base': 10, 'exp': 0}, {'result': 10000})\n```\n\n\n## Example\n\nLet's assume that we have this Java file, `IterPower.java`:\n```java\npublic class IterPower {\n public static void main(String[] args) {\n // ... parse arguments ...\n System.out.println(iterPower(base, exp));\n }\n\n public static int iterPower(int base, int exp) {\n int result = 1;\n while (exp > 0) {\n result *= base;\n exp -= 1;\n }\n return result;\n }\n}\n```\nwhich has been compiled with debugging information, `javac -g IterPower.java`. The following is a Python snippet:\n```python\nimport pyjdb\nimport itertools\n\np = pyjdb.JdbProcess(\"IterPower\")\np.spawn(\"10 4\")\n\nvariables = {}\n\nwhile True:\n\n # Try to make an additional step and retrieve local variables\n result = None\n try:\n p.step()\n result = p.locals()\n except pyjdb.EOF:\n break\n if result is None:\n continue\n\n # Store the values of each variable\n (args, locs) = result\n for (var, val) in itertools.chain(args.items(), locs.items()):\n variables[var] = variables.get(var, list())\n variables[var].append(val)\n\nvariables_unique_values = {\n var: list(set(vals)) for (var, vals) in variables.items()\n}\n\nprint(variables_unique_values)\n```\nThe snippet will output a trace of the variable values of this program through its execution:\n```json\n{\"args\": [\"instance of java.lang.String[0] (id=495)\"],\n \"base\": [10],\n \"exp\": [0, 1, 2, 3, 4],\n \"result\": [1, 10, 100, 1000, 10000]}\n```\n\n## Inspiration\n\nThis project was inspired by a [talk by Elena Glassman](https://youtu.be/Pt-DMk1YRJ4) in which she shows how to cluster [different implementations of the same solution](http://eglassman.github.io/mit-phd-thesis/thesis-slides.html#/10) according to the trace of the internal variables. Her work, which includes [OverCode](http://eglassman.github.io/overcode/) and [foobaz](https://www.youtube.com/watch?v=4X94_2XEsrE), focuses on Python programs. At my home institution, we use Java in our introductory classes. The initial goal of this project was to apply Dr. Glassman's techniques to Java assignments.\n\n## Related projects\n\nThere were several ambitious projects related to bringing a Java debugger to Python. These projects highlight how complex an undertaking it is to implement the actual JDWP protocol. This is why in this project, our approach has been to piggy-back on `jdb` so as to not need to reimplement protocol-level functionality.\n\n- [csuter/pyjdb](https://github.com/csuter/pyjdb) (abandonned): A Python implementation of the JDWP specifications.\n\n- [soulseekah/pyjdb](https://github.com/soulseekah/pyjdb) (abandonned): A `jdb` replacement with more user-friendly features.\n\n", "description_content_type": "text/markdown", "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/jlumbroso/pyjdb", "keywords": "", "license": "LGPL3", "maintainer": "", "maintainer_email": "", "name": "pyjdb", "package_url": "https://pypi.org/project/pyjdb/", "platform": "", "project_url": "https://pypi.org/project/pyjdb/", "project_urls": { "Homepage": "https://github.com/jlumbroso/pyjdb" }, "release_url": "https://pypi.org/project/pyjdb/0.0.6/", "requires_dist": [ "pexpect", "typing" ], "requires_python": "", "summary": "Python package to interface with the standard CLI Java Debugger `jdb` to extract information about the execution of Java programs.", "version": "0.0.6" }, "last_serial": 5798182, "releases": { "0.0.1": [ { "comment_text": "", "digests": { "md5": "9b8e08e6f270eb04942268ffef46e701", "sha256": "0c4aa9ed5c19d0d5742d83926b7e53225ec2413eb7d597fe0a631d5cda099559" }, "downloads": -1, "filename": "pyjdb-0.0.1-py3-none-any.whl", "has_sig": false, "md5_digest": "9b8e08e6f270eb04942268ffef46e701", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 8030, "upload_time": "2019-08-21T15:29:25", "url": "https://files.pythonhosted.org/packages/74/2a/72912d3b3fe3742fd61d15f0d8b30f10d0e19f573b51f2ccf5c770817f77/pyjdb-0.0.1-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "969abecbc811ffe11d3340f53ba604c4", "sha256": "1da2d096157ba48f00780895eb819cc017a5fbf3bb9b523afaa327eb02aca626" }, "downloads": -1, "filename": "pyjdb-0.0.1.tar.gz", "has_sig": false, "md5_digest": "969abecbc811ffe11d3340f53ba604c4", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 4463, "upload_time": "2019-08-21T15:29:28", "url": "https://files.pythonhosted.org/packages/d0/97/79628bb501b4183ad96f64fc926a27f0eff5d41fa1dfe5645847f4a0860a/pyjdb-0.0.1.tar.gz" } ], "0.0.2": [ { "comment_text": "", "digests": { "md5": "e221bc48ec7d0116677b3bbaffb4a895", "sha256": "7424b84f563d9e4e5bd2541883af5a8536e1fdd664dea42ffabf28d6a1201d71" }, "downloads": -1, "filename": "pyjdb-0.0.2-py3-none-any.whl", "has_sig": false, "md5_digest": "e221bc48ec7d0116677b3bbaffb4a895", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 10689, "upload_time": "2019-08-23T02:57:25", "url": "https://files.pythonhosted.org/packages/aa/61/4ab018e6d084c1c34e6b10421b5582a4c7036e25950b6a5da79f2e309be2/pyjdb-0.0.2-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "890779bbb44d4b311ccdda650803edfc", "sha256": "27c601b2517e57da918b19235f419fdb00b2b512fe10b7b6bb87adc186fd35cd" }, "downloads": -1, "filename": "pyjdb-0.0.2.tar.gz", "has_sig": false, "md5_digest": "890779bbb44d4b311ccdda650803edfc", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 7248, "upload_time": "2019-08-23T02:57:26", "url": "https://files.pythonhosted.org/packages/45/2c/0c507531d9dcfa776b43cc2b5d93aa498bf9ef288760a1d7de0983f17b74/pyjdb-0.0.2.tar.gz" } ], "0.0.3": [ { "comment_text": "", "digests": { "md5": "780a2dcbc55bc76ef18c7d5b357a5524", "sha256": "ad443bee9546197563e17f0a8fd34aa9a256b2c74844a293e66447e84ac31077" }, "downloads": -1, "filename": "pyjdb-0.0.3-py3-none-any.whl", "has_sig": false, "md5_digest": "780a2dcbc55bc76ef18c7d5b357a5524", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 10715, "upload_time": "2019-08-25T21:56:20", "url": "https://files.pythonhosted.org/packages/77/39/a19f727def8b9c97014507468c7c19e7c069e791e6b491a2381fd980fa12/pyjdb-0.0.3-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "0331c3fa063fb062206af5ba621e332b", "sha256": "1d87dd9d0c94c9643437d88537c1fa3db3a23f5f3fec82eedbc2bcf8fdc8d987" }, "downloads": -1, "filename": "pyjdb-0.0.3.tar.gz", "has_sig": false, "md5_digest": "0331c3fa063fb062206af5ba621e332b", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 7283, "upload_time": "2019-08-25T21:56:22", "url": "https://files.pythonhosted.org/packages/04/5d/4285feb0909e04f4dce0cf14767056e8eb39256aa7679321396d15690e5d/pyjdb-0.0.3.tar.gz" } ], "0.0.4": [ { "comment_text": "", "digests": { "md5": "7d22cc633929e958d3369e076671864b", "sha256": "88878e8c3822a8cd06167963d7c48283ca9c45affe9321b16820a30d2069b997" }, "downloads": -1, "filename": "pyjdb-0.0.4-py2-none-any.whl", "has_sig": false, "md5_digest": "7d22cc633929e958d3369e076671864b", "packagetype": "bdist_wheel", "python_version": "py2", "requires_python": null, "size": 11678, "upload_time": "2019-09-07T04:18:17", "url": "https://files.pythonhosted.org/packages/9d/09/0590d2b862c90a512b5970495950b56a1eee468579e1ef662caf32a57b0f/pyjdb-0.0.4-py2-none-any.whl" }, { "comment_text": "", "digests": { "md5": "abf4041bc13ce4c40797bc0e4fd9d87c", "sha256": "8f9b3a7340df915be40601f9b0ddc2a42ad8f9cf72cb9749d51a506c6b320b4c" }, "downloads": -1, "filename": "pyjdb-0.0.4.tar.gz", "has_sig": false, "md5_digest": "abf4041bc13ce4c40797bc0e4fd9d87c", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 8261, "upload_time": "2019-09-07T04:18:19", "url": "https://files.pythonhosted.org/packages/0e/52/eb308671cf8715f244e73d872457d33332a211b2aa03cce0482be93b45b2/pyjdb-0.0.4.tar.gz" } ], "0.0.5": [ { "comment_text": "", "digests": { "md5": "b6cf899b2cc2b8db683ceb049e75555c", "sha256": "8c0232316bb739cc3c056cca80a119647632d2555f46e58df011ca2f2d72903a" }, "downloads": -1, "filename": "pyjdb-0.0.5-py2-none-any.whl", "has_sig": false, "md5_digest": "b6cf899b2cc2b8db683ceb049e75555c", "packagetype": "bdist_wheel", "python_version": "py2", "requires_python": null, "size": 12060, "upload_time": "2019-09-08T02:06:27", "url": "https://files.pythonhosted.org/packages/d0/5b/7c5c441227388a5311878c346b4ea1af3b1e7d4b364412e2ce040f737f49/pyjdb-0.0.5-py2-none-any.whl" }, { "comment_text": "", "digests": { "md5": "a1d3972d22d7f11e7f165f0d75bdb963", "sha256": "15e4d252b283f323508ee110cb5cfead3cdc21aea800f1cc55370840d2aee63c" }, "downloads": -1, "filename": "pyjdb-0.0.5.tar.gz", "has_sig": false, "md5_digest": "a1d3972d22d7f11e7f165f0d75bdb963", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 8447, "upload_time": "2019-09-08T02:06:29", "url": "https://files.pythonhosted.org/packages/0a/ca/a8b6001de134b9d1fcd50f9fff6f3d38e53ba512a29a6c778272f207af3e/pyjdb-0.0.5.tar.gz" } ], "0.0.6": [ { "comment_text": "", "digests": { "md5": "7ef58354339af066d2c574015fa2ed8d", "sha256": "23e9d25b734a769419a88874704ad249ebcdb98e7189cc70d345deb3df0a2929" }, "downloads": -1, "filename": "pyjdb-0.0.6-py2-none-any.whl", "has_sig": false, "md5_digest": "7ef58354339af066d2c574015fa2ed8d", "packagetype": "bdist_wheel", "python_version": "py2", "requires_python": null, "size": 12375, "upload_time": "2019-09-08T03:30:38", "url": "https://files.pythonhosted.org/packages/1b/3b/c37eca31f6239fdc840b30ed8299e02fb4a6b0efbeaf72f3f1d53e81be93/pyjdb-0.0.6-py2-none-any.whl" }, { "comment_text": "", "digests": { "md5": "b56c9172d7b52af6fa7d62eaf01c708a", "sha256": "6d8e9d06a4149fe931c4b0b55901360ed5a4d6ca35dc783a757935b156d49b9f" }, "downloads": -1, "filename": "pyjdb-0.0.6.tar.gz", "has_sig": false, "md5_digest": "b56c9172d7b52af6fa7d62eaf01c708a", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 8681, "upload_time": "2019-09-08T03:30:39", "url": "https://files.pythonhosted.org/packages/7b/67/79910b261b2b8b38fb41d1906ec6e7158500cd4cfba547115314a308c827/pyjdb-0.0.6.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "7ef58354339af066d2c574015fa2ed8d", "sha256": "23e9d25b734a769419a88874704ad249ebcdb98e7189cc70d345deb3df0a2929" }, "downloads": -1, "filename": "pyjdb-0.0.6-py2-none-any.whl", "has_sig": false, "md5_digest": "7ef58354339af066d2c574015fa2ed8d", "packagetype": "bdist_wheel", "python_version": "py2", "requires_python": null, "size": 12375, "upload_time": "2019-09-08T03:30:38", "url": "https://files.pythonhosted.org/packages/1b/3b/c37eca31f6239fdc840b30ed8299e02fb4a6b0efbeaf72f3f1d53e81be93/pyjdb-0.0.6-py2-none-any.whl" }, { "comment_text": "", "digests": { "md5": "b56c9172d7b52af6fa7d62eaf01c708a", "sha256": "6d8e9d06a4149fe931c4b0b55901360ed5a4d6ca35dc783a757935b156d49b9f" }, "downloads": -1, "filename": "pyjdb-0.0.6.tar.gz", "has_sig": false, "md5_digest": "b56c9172d7b52af6fa7d62eaf01c708a", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 8681, "upload_time": "2019-09-08T03:30:39", "url": "https://files.pythonhosted.org/packages/7b/67/79910b261b2b8b38fb41d1906ec6e7158500cd4cfba547115314a308c827/pyjdb-0.0.6.tar.gz" } ] }