diff --git a/.gitignore b/.gitignore index 326b1f7..e9370b1 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ /target /cpp/list_example_cpp +__pycache__ diff --git a/.vscode/launch.json b/.vscode/launch.json index 5334fd9..14cf5db 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -32,7 +32,7 @@ }, { "description": "Load the generic $debug_graph(...) Debug Visualizer helper", - "text": "source ${workspaceFolder}/gdb/debug_graph.py", + "text": "source ${workspaceFolder}/debuggers/gdb_debug_graph.py", "ignoreFailures": false } ] @@ -43,6 +43,9 @@ "request": "launch", "program": "${workspaceFolder}/python/main.py", "cwd": "${workspaceFolder}/python", + "env": { + "PYTHONPATH": "${workspaceFolder}/debuggers" + }, "console": "integratedTerminal", "justMyCode": true }, @@ -77,7 +80,7 @@ }, { "description": "Load the generic $debug_graph(...) Debug Visualizer helper", - "text": "source ${workspaceFolder}/gdb/debug_graph.py", + "text": "source ${workspaceFolder}/debuggers/gdb_debug_graph.py", "ignoreFailures": false } ] diff --git a/.vscode/settings.json b/.vscode/settings.json index 61ff48d..7ae770b 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -7,7 +7,7 @@ "expressionTemplate": "$debug_graph(${expr})" }, "debugpy": { - "expressionTemplate": "__import__('debug_graph').debug_graph(${expr})" + "expressionTemplate": "__import__('py_debug_graph').debug_graph(${expr})" } } } diff --git a/gdb/debug_graph.py b/debuggers/gdb_debug_graph.py similarity index 100% rename from gdb/debug_graph.py rename to debuggers/gdb_debug_graph.py diff --git a/python/debug_graph.py b/debuggers/py_debug_graph.py similarity index 98% rename from python/debug_graph.py rename to debuggers/py_debug_graph.py index d09b776..7e40a89 100644 --- a/python/debug_graph.py +++ b/debuggers/py_debug_graph.py @@ -1,5 +1,5 @@ """Generic "reference-graph" -> Debug Visualizer JSON walker, the debugpy -analog of gdb/debug_graph.py. +analog of debuggers/gdb_debug_graph.py. Works on any plain Python object reachable from an expression, purely by walking `vars(obj)` -- no changes to the debuggee's source are required. @@ -23,7 +23,7 @@ walks and labels, as additional roots: - every other local variable visible in the caller's frame -- kind "local" - every module-level global visible from the caller's frame, skipping dunders, modules, classes and functions -- kind "global" -This mirrors gdb/debug_graph.py's auto-discovery: it's what lets +This mirrors debuggers/gdb_debug_graph.py's auto-discovery: it's what lets `debug_graph(top)` -- a bare int with no object graph of its own -- still show the whole list, because `lst` (a sibling local) gets auto-walked too. """ diff --git a/python/__pycache__/debug_graph.cpython-314.pyc b/python/__pycache__/debug_graph.cpython-314.pyc deleted file mode 100644 index 69efbe5..0000000 Binary files a/python/__pycache__/debug_graph.cpython-314.pyc and /dev/null differ diff --git a/python/__pycache__/main.cpython-314.pyc b/python/__pycache__/main.cpython-314.pyc deleted file mode 100644 index 3962214..0000000 Binary files a/python/__pycache__/main.cpython-314.pyc and /dev/null differ diff --git a/scripts/dump_debug_graph.py b/scripts/dump_debug_graph.py index 512f2a5..37188cc 100755 --- a/scripts/dump_debug_graph.py +++ b/scripts/dump_debug_graph.py @@ -28,13 +28,13 @@ gdb has no way to know it's secretly interior to a `Node`). VS Code's whatever you type in the Watch box as $debug_graph(${expr}), so typing plain `top` evaluates $debug_graph(top) -- not $debug_graph(list, ...): we replay that exact call and verify it still delves into the full list. This -relies on gdb/debug_graph.py's auto-discovery of sibling locals (here, +relies on debuggers/gdb_debug_graph.py's auto-discovery of sibling locals (here, `list`, a struct type it *can* walk) merging into the same node graph as `top`'s address, rather than requiring `top` to be passed as an explicit watched root. The Python build has no pointers -- `top` there is just a plain int, not a -value interior to any struct -- but python/debug_graph.py's own +value interior to any struct -- but debuggers/py_debug_graph.py's own auto-discovery of sibling locals (here `lst`) means evaluating debug_graph(top) still delves into the whole list for the same underlying reason: verify_top_delves_into_list_py exercises that. @@ -57,7 +57,7 @@ def run_gdb(gdb_bin, binary, break_file, break_line, expr="$debug_graph(list)"): commands = [ "-gdb-set print elements 0", "-gdb-set print characters 0", - "source %s" % (REPO / "gdb" / "debug_graph.py"), + "source %s" % (REPO / "debuggers" / "gdb_debug_graph.py"), "-break-insert %s:%d" % (break_file, break_line), "-exec-run", '-data-evaluate-expression "%s"' % expr.replace('"', '\\"'), @@ -199,9 +199,11 @@ def run_debugpy(python_bin, script_path, break_line, expr): probe.bind(("127.0.0.1", 0)) port = probe.getsockname()[1] + env = dict(os.environ, PYTHONPATH=str(REPO / "debuggers")) proc = subprocess.Popen( [python_bin, "-m", "debugpy", "--listen", "127.0.0.1:%d" % port, "--wait-for-client", str(script_path)], cwd=str(Path(script_path).parent), + env=env, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL, ) try: @@ -380,7 +382,7 @@ def dump(label, gdb_bin, binary, break_file, break_line, out_dir, expr="$debug_g def dump_python(label, python_bin, script_path, break_line, out_dir, - expr="__import__('debug_graph').debug_graph(lst)", verify=None): + expr="__import__('py_debug_graph').debug_graph(lst)", verify=None): ok = True try: raw_result = run_debugpy(python_bin, script_path, break_line, expr) @@ -423,7 +425,7 @@ def main(): ok_python = dump_python("python", python_bin, python_script, 54, out_dir) ok_python_top = dump_python( "python_top", python_bin, python_script, 54, out_dir, - expr="__import__('debug_graph').debug_graph(top)", + expr="__import__('py_debug_graph').debug_graph(top)", verify=verify_top_delves_into_list_py, ) diff --git a/vis-plugins/node-table-visualizer.js b/vis-plugins/node-table-visualizer.js index 3533165..a8295b5 100644 --- a/vis-plugins/node-table-visualizer.js +++ b/vis-plugins/node-table-visualizer.js @@ -11,7 +11,7 @@ // Registered via the "debugVisualizer.customVisualizerScriptPaths" setting; // the extension hot-reloads this file on save, no debug session restart needed. // -// Data shape produced by gdb/debug_graph.py's $debug_graph(...): +// Data shape produced by debuggers/gdb_debug_graph.py's $debug_graph(...): // nodes: [{ id: "0x...", fields: [{ name, value, isPointer? }, ...] }] // edges: [{ from: "0x...", to: "0x...", label? }] // roots: [{ name: "top", value: "0x...", kind? }] -- external pointer