feat(debug): add Python debug visualizer and enhance gdb integration

This commit is contained in:
mynameisdeleted
2026-07-09 16:08:01 -04:00
parent 67e9a0d488
commit 4f693f8cff
9 changed files with 17 additions and 11 deletions

View File

@@ -28,13 +28,13 @@ gdb has no way to know it's secretly interior to a `Node<int>`). 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,
)