textual-debugger 0.2.14__tar.gz → 0.2.16__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {textual_debugger-0.2.14 → textual_debugger-0.2.16}/PKG-INFO +213 -50
- {textual_debugger-0.2.14/src/tdb → textual_debugger-0.2.16}/README.md +209 -48
- {textual_debugger-0.2.14 → textual_debugger-0.2.16}/pyproject.toml +20 -4
- {textual_debugger-0.2.14 → textual_debugger-0.2.16/src/tdb}/README.md +209 -48
- {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/__init__.py +1 -1
- textual_debugger-0.2.16/src/tdb/adapters/bash/arith_for.py +326 -0
- {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/adapters/bash/session.py +34 -1
- {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/adapters/bash/tdb_harness.sh +29 -3
- textual_debugger-0.2.16/src/tdb/adapters/native/gdb_stl_printers.py +740 -0
- {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/adapters/perl/padwalker.py +53 -1
- {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/adapters/tcsh/inspect.py +27 -11
- {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/app.py +55 -27
- {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/app_handlers/dap_events.py +18 -3
- {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/breakpoint_hook.py +55 -10
- {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/cli.py +86 -7
- textual_debugger-0.2.16/src/tdb/examples/C/breakpoint_hook_demo.c +26 -0
- textual_debugger-0.2.16/src/tdb/examples/C/pi_digits.c +102 -0
- textual_debugger-0.2.16/src/tdb/examples/C++/breakpoint_hook_demo.cpp +26 -0
- textual_debugger-0.2.16/src/tdb/examples/C++/pi_digits.cpp +77 -0
- textual_debugger-0.2.16/src/tdb/examples/Fortran/breakpoint_hook_demo.f90 +38 -0
- textual_debugger-0.2.16/src/tdb/examples/Fortran/pi_digits.f90 +165 -0
- textual_debugger-0.2.16/src/tdb/examples/Go/breakpoint_hook_demo/go.mod +7 -0
- textual_debugger-0.2.16/src/tdb/examples/Go/breakpoint_hook_demo/main.go +32 -0
- textual_debugger-0.2.16/src/tdb/examples/Go/pi_digits.go +77 -0
- textual_debugger-0.2.16/src/tdb/examples/OCaml/breakpoint_hook_demo.ml +26 -0
- textual_debugger-0.2.16/src/tdb/examples/OCaml/pi_digits.ml +66 -0
- textual_debugger-0.2.16/src/tdb/examples/Perl/breakpoint_hook_demo.pl +20 -0
- textual_debugger-0.2.16/src/tdb/examples/Perl/pi_digits.pl +42 -0
- textual_debugger-0.2.16/src/tdb/examples/PowerShell/pi_digits.ps1 +50 -0
- textual_debugger-0.2.16/src/tdb/examples/Python/pi_digits.py +138 -0
- textual_debugger-0.2.16/src/tdb/examples/Ruby/breakpoint_hook_demo.rb +17 -0
- textual_debugger-0.2.16/src/tdb/examples/Ruby/pi_digits.rb +61 -0
- textual_debugger-0.2.16/src/tdb/examples/Rust/breakpoint_hook_demo/Cargo.toml +9 -0
- textual_debugger-0.2.16/src/tdb/examples/Rust/breakpoint_hook_demo/src/main.rs +22 -0
- textual_debugger-0.2.16/src/tdb/examples/Rust/pi_digits.rs +69 -0
- textual_debugger-0.2.16/src/tdb/examples/bash/pi_digits.sh +60 -0
- textual_debugger-0.2.16/src/tdb/examples/tcsh/pi_digits.tcsh +95 -0
- {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/info.py +83 -2
- {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/languages/base.py +7 -0
- {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/languages/cpp.py +32 -5
- {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/languages/native_tools.py +36 -0
- {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/languages/python.py +12 -0
- {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/languages/rust.py +2 -14
- textual_debugger-0.2.16/src/tdb/mcp/__init__.py +45 -0
- textual_debugger-0.2.16/src/tdb/mcp/__main__.py +6 -0
- {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/persist.py +31 -0
- {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/post_mortem.py +42 -10
- {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/run_mode.py +19 -2
- {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/widgets/console_view.py +3 -0
- {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/widgets/evaluate_console.py +7 -1
- {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/widgets/variable_view.py +29 -23
- {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/textual_debugger.egg-info/PKG-INFO +213 -50
- {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/textual_debugger.egg-info/SOURCES.txt +24 -0
- {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/textual_debugger.egg-info/entry_points.txt +1 -1
- {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/textual_debugger.egg-info/requires.txt +4 -1
- textual_debugger-0.2.14/src/tdb/mcp/__init__.py +0 -10
- textual_debugger-0.2.14/src/tdb/mcp/__main__.py +0 -6
- {textual_debugger-0.2.14 → textual_debugger-0.2.16}/LICENSE +0 -0
- {textual_debugger-0.2.14 → textual_debugger-0.2.16}/setup.cfg +0 -0
- {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/__main__.py +0 -0
- {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/_timeouts.py +0 -0
- {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/adapters/__init__.py +0 -0
- {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/adapters/bash/__init__.py +0 -0
- {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/adapters/bash/__main__.py +0 -0
- {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/adapters/bash/declares.py +0 -0
- {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/adapters/bash/server.py +0 -0
- {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/adapters/native/__init__.py +0 -0
- {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/adapters/native/tdb.h +0 -0
- {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/adapters/ocaml/__init__.py +0 -0
- {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/adapters/ocaml/lldb_formatters.py +0 -0
- {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/adapters/perl/Devel/TdbCompile.pm +0 -0
- {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/adapters/perl/Devel/TdbRemote.pm +0 -0
- {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/adapters/perl/__init__.py +0 -0
- {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/adapters/perl/__main__.py +0 -0
- {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/adapters/perl/helpers.pl +0 -0
- {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/adapters/perl/padwalker_src/Makefile.PL +0 -0
- {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/adapters/perl/padwalker_src/PadWalker.pm +0 -0
- {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/adapters/perl/padwalker_src/PadWalker.xs +0 -0
- {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/adapters/perl/protocol.py +0 -0
- {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/adapters/perl/refs.py +0 -0
- {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/adapters/perl/server.py +0 -0
- {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/adapters/perl/session.py +0 -0
- {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/adapters/powershell/__init__.py +0 -0
- {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/adapters/powershell/__main__.py +0 -0
- {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/adapters/powershell/locate.py +0 -0
- {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/adapters/powershell/output.py +0 -0
- {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/adapters/powershell/server.py +0 -0
- {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/adapters/powershell/tdb_launch.ps1 +0 -0
- {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/adapters/ruby/__init__.py +0 -0
- {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/adapters/ruby/__main__.py +0 -0
- {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/adapters/ruby/server.py +0 -0
- {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/adapters/ruby/tdb.rb +0 -0
- {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/adapters/seqs.py +0 -0
- {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/adapters/tcsh/__init__.py +0 -0
- {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/adapters/tcsh/__main__.py +0 -0
- {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/adapters/tcsh/breakpoints.py +0 -0
- {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/adapters/tcsh/cli.py +0 -0
- {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/adapters/tcsh/guardian.py +0 -0
- {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/adapters/tcsh/instrumenter.py +0 -0
- {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/adapters/tcsh/models.py +0 -0
- {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/adapters/tcsh/protocol.py +0 -0
- {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/adapters/tcsh/runtime.py +0 -0
- {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/adapters/tcsh/scanner.py +0 -0
- {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/adapters/tcsh/server.py +0 -0
- {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/adapters/tcsh/session.py +0 -0
- {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/adapters/tcsh/transport.py +0 -0
- {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/app_handlers/__init__.py +0 -0
- {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/app_handlers/inspection.py +0 -0
- {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/app_handlers/routing.py +0 -0
- {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/app_handlers/ui_panels.py +0 -0
- {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/app_helpers.py +0 -0
- {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/dap/__init__.py +0 -0
- {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/dap/client.py +0 -0
- {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/dap/messages.py +0 -0
- {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/dap/protocol.py +0 -0
- {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/dap/reverse.py +0 -0
- {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/dap/types.py +0 -0
- {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/eval_mode.py +0 -0
- {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/examine.py +0 -0
- {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/go_concurrency/__init__.py +0 -0
- {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/go_concurrency/analyzer.py +0 -0
- {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/go_concurrency/classifier.py +0 -0
- {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/go_concurrency/collector.py +0 -0
- {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/go_concurrency/models.py +0 -0
- {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/inspection.py +0 -0
- {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/inspection_full.py +0 -0
- {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/keybindings/__init__.py +0 -0
- {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/languages/__init__.py +0 -0
- {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/languages/bash.py +0 -0
- {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/languages/errors.py +0 -0
- {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/languages/go.py +0 -0
- {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/languages/ocaml.py +0 -0
- {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/languages/perl.py +0 -0
- {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/languages/powershell.py +0 -0
- {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/languages/registry.py +0 -0
- {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/languages/ruby.py +0 -0
- {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/languages/tcsh.py +0 -0
- {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/mcp/server.py +0 -0
- {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/mcp/session.py +0 -0
- {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/processes_cache.py +0 -0
- {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/replay.py +0 -0
- {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/replay_tui.py +0 -0
- {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/rust_concurrency/__init__.py +0 -0
- {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/rust_concurrency/analyzer.py +0 -0
- {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/rust_concurrency/classifier.py +0 -0
- {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/rust_concurrency/collector.py +0 -0
- {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/rust_concurrency/models.py +0 -0
- {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/rust_concurrency/probes/__init__.py +0 -0
- {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/rust_concurrency/probes/base.py +0 -0
- {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/rust_concurrency/probes/gdb.py +0 -0
- {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/rust_concurrency/probes/gdb_script.py +0 -0
- {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/rust_concurrency/probes/lldb.py +0 -0
- {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/rust_concurrency/probes/lldb_script.py +0 -0
- {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/server/__init__.py +0 -0
- {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/server/app.py +0 -0
- {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/server/event_handler.py +0 -0
- {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/server/handlers.py +0 -0
- {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/server/rpc_types.py +0 -0
- {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/server/runner.py +0 -0
- {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/session/__init__.py +0 -0
- {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/session/breakpoint_sync.py +0 -0
- {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/session/child_processes.py +0 -0
- {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/session/controller.py +0 -0
- {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/session/errors.py +0 -0
- {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/session/event_bus.py +0 -0
- {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/session/inspect_service.py +0 -0
- {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/session/messages.py +0 -0
- {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/session/post_mortem_loader.py +0 -0
- {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/session/recorder.py +0 -0
- {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/session/state.py +0 -0
- {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/session/statement_stepper.py +0 -0
- {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/session/terminal.py +0 -0
- {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/session/textual_handler.py +0 -0
- {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/source_analysis.py +0 -0
- {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/source_edit.py +0 -0
- {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/widgets/__init__.py +0 -0
- {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/widgets/_inspection_modal.py +0 -0
- {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/widgets/async_tasks_modal.py +0 -0
- {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/widgets/breakpoint_view.py +0 -0
- {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/widgets/code_editor.py +0 -0
- {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/widgets/code_view.py +0 -0
- {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/widgets/full_contents_modal.py +0 -0
- {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/widgets/goroutines_modal.py +0 -0
- {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/widgets/menu_bar.py +0 -0
- {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/widgets/modals.py +0 -0
- {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/widgets/processes_modal.py +0 -0
- {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/widgets/rust_concurrency_modal.py +0 -0
- {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/widgets/stack_view.py +0 -0
- {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/widgets/status_bar.py +0 -0
- {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/widgets/threads_modal.py +0 -0
- {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/textual_debugger.egg-info/dependency_links.txt +0 -0
- {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/textual_debugger.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: textual-debugger
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.16
|
|
4
4
|
Summary: A TUI debugger for Python, Perl, and other languages. Based on textual.
|
|
5
5
|
Author-email: Al Danial <al.danial@gmail.com>
|
|
6
6
|
License: textual-debugger is licensed to you under the MIT/X Consortium license:
|
|
@@ -53,10 +53,12 @@ Requires-Dist: debugpy>=1.8.12
|
|
|
53
53
|
Requires-Dist: pygments>=2.17.0
|
|
54
54
|
Requires-Dist: fastapi>=0.115.0
|
|
55
55
|
Requires-Dist: uvicorn>=0.30.0
|
|
56
|
-
Requires-Dist: mcp<3.0.0,>=2.0.0
|
|
57
56
|
Provides-Extra: edit
|
|
58
57
|
Requires-Dist: textual[syntax]>=8.0.0; extra == "edit"
|
|
58
|
+
Provides-Extra: mcp
|
|
59
|
+
Requires-Dist: mcp<3.0.0,>=2.0.0; extra == "mcp"
|
|
59
60
|
Provides-Extra: dev
|
|
61
|
+
Requires-Dist: textual-debugger[mcp]; extra == "dev"
|
|
60
62
|
Requires-Dist: pytest; extra == "dev"
|
|
61
63
|
Requires-Dist: pytest-cov; extra == "dev"
|
|
62
64
|
Requires-Dist: pytest-asyncio; extra == "dev"
|
|
@@ -74,7 +76,7 @@ Dynamic: license-file
|
|
|
74
76
|
a full-featured terminal-based debugger for Python and other languages
|
|
75
77
|
with a Debug Adapter Protocol (DAP) implementation. In addition to Python,
|
|
76
78
|
`tdb` comes with built-in support for
|
|
77
|
-
- C
|
|
79
|
+
- C, C++, Fortran (via `gdb` or `lldb-dap`)
|
|
78
80
|
- Rust (via `gdb` or `lldb-dap`, selected explicitly)
|
|
79
81
|
- Perl (via `perl -d`)
|
|
80
82
|
- Bash (via bash's own `DEBUG` trap; bash ≥ 4.4)
|
|
@@ -100,12 +102,12 @@ MIT License. Copyright 2026 by Al Danial.
|
|
|
100
102
|
`tdb`:
|
|
101
103
|
|
|
102
104
|
- debugs multiple languages through the Debug Adapter Protocol: Python (via `debugpy`,
|
|
103
|
-
the richest feature set)
|
|
104
|
-
`lldb-dap`)
|
|
105
|
-
Bash (via bash's own `DEBUG` trap)
|
|
106
|
-
stock `tcsh`)
|
|
107
|
-
`lldb-dap`/`gdb`, bytecode via ocamlearlybird)
|
|
108
|
-
dap`)
|
|
105
|
+
the richest feature set); C/C++ and Fortran (via `gdb -i dap` or `lldb-dap`); Rust (via `gdb` or
|
|
106
|
+
`lldb-dap`); Perl (via `perl -d`);
|
|
107
|
+
Bash (via bash's own `DEBUG` trap); Tcsh (via source instrumentation of a
|
|
108
|
+
stock `tcsh`); Ruby (via the debug gem's `rdbg`); OCaml (native via
|
|
109
|
+
`lldb-dap`/`gdb`, bytecode via ocamlearlybird); Go (via Delve's `dlv
|
|
110
|
+
dap`); and PowerShell 7 (via PowerShell Editor Services). Most languages are
|
|
109
111
|
auto-detected from the target; Rust intentionally requires `--lang rust`
|
|
110
112
|
(ref. [Multi-Language Debugging](#multi-language-debugging)).
|
|
111
113
|
|
|
@@ -128,7 +130,7 @@ built with `textual`, `prompt-toolkit`, `urwid`, `curses`, `rich`, and so on
|
|
|
128
130
|
to have `tdb` pop open automatically at the first uncaught exception, and a live
|
|
129
131
|
breakpoint hook (`tdb.breakpoint()` in Python, `Devel::TdbRemote::breakpoint()`
|
|
130
132
|
in Perl, `Tdb.breakpoint` in Ruby, `tdb.Breakpoint()` in Go, `tdb_breakpoint()`
|
|
131
|
-
in C/C
|
|
133
|
+
in C/C++ and Fortran, `tdb::breakpoint()` in Rust, `Tdb.breakpoint ()` in OCaml) that opens
|
|
132
134
|
`tdb` paused at a line of your choosing
|
|
133
135
|
|
|
134
136
|
- can be entirely keyboard-driven
|
|
@@ -167,6 +169,14 @@ or run it without installing:
|
|
|
167
169
|
uvx --from textual-debugger tdb my_program.py
|
|
168
170
|
```
|
|
169
171
|
|
|
172
|
+
The MCP server (`tdb-mcp`, `tdb --mcp`) is an optional extra because its
|
|
173
|
+
`mcp` dependency requires the `cryptography` package, which cannot be
|
|
174
|
+
installed on every platform. Add it with:
|
|
175
|
+
|
|
176
|
+
```bash
|
|
177
|
+
pip install "textual-debugger[mcp]"
|
|
178
|
+
```
|
|
179
|
+
|
|
170
180
|
|
|
171
181
|
## Quick Start
|
|
172
182
|
|
|
@@ -177,9 +187,21 @@ tdb --doc
|
|
|
177
187
|
# show the Help > About text, where tdb and its config, breakpoints and
|
|
178
188
|
# log files live, and the path + version of each interpreter and native
|
|
179
189
|
# debugger it would use (python, gdb, lldb-dap, perl, ruby, dlv,
|
|
180
|
-
# ocamlearlybird, bash, tcsh, pwsh)
|
|
190
|
+
# ocamlearlybird, bash, tcsh, pwsh), whether gdb has its DAP interpreter
|
|
191
|
+
# (`gdb -i dap`), whether perl has ExtUtils::MakeMaker (needed to
|
|
192
|
+
# build the bundled PadWalker), and the `examples dir` holding the
|
|
193
|
+
# per-language examples (C, C++, Fortran, Go, OCaml, Perl, PowerShell,
|
|
194
|
+
# Python, Ruby, Rust, bash, tcsh) installed with the package
|
|
181
195
|
tdb --info
|
|
182
196
|
|
|
197
|
+
# reset config.json to defaults (the old file is kept as
|
|
198
|
+
# config.json-YYYY-mm-DD-HH:MM:SS; HH.MM.SS on Windows)
|
|
199
|
+
tdb --config write-default
|
|
200
|
+
|
|
201
|
+
# build and cache the bundled PadWalker Perl module now rather than
|
|
202
|
+
# on the first Perl launch
|
|
203
|
+
tdb --config install-padwalker
|
|
204
|
+
|
|
183
205
|
# debug a Python program (stops at first line by default)
|
|
184
206
|
tdb my_program.py
|
|
185
207
|
|
|
@@ -258,7 +280,7 @@ languages are supported out of the box:
|
|
|
258
280
|
| Language | Adapter(s) | Dependencies | Feature level |
|
|
259
281
|
|----------|------------|------------------------|---------------|
|
|
260
282
|
| Python | `debugpy` (default) | Python ≥ 3.11 | everything in this README |
|
|
261
|
-
| C / C++ (any native binary) | `gdb` (default), `lldb-dap` (alternate) | `gdb -i dap` requires GDB ≥ 14 built with Python (RHEL 8/9: `dnf install gcc-toolset-14-gdb`, see [C/C
|
|
283
|
+
| C / C++ / Fortran (any native binary) | `gdb` (default), `lldb-dap` (alternate) | `gdb -i dap` requires GDB ≥ 14 built with Python (RHEL 8/9: `dnf install gcc-toolset-14-gdb`, see [C/C++/Fortran tips](#cc-tips)); `lldb-dap` ships with LLVM ≥ 17 (e.g. `apt install lldb`) | core debugging: breakpoints, stepping, stack, variables, evaluate console + remote attach (gdbserver/lldb-server, local symbol-bearing executable required) |
|
|
262
284
|
| Rust (explicit `--lang rust`) | `gdb` (Linux default), `lldb-dap` (macOS default) | any rustc building with debug info; GDB ≥ 14 or LLVM `lldb-dap` ≥ 17 (concurrency ownership evidence additionally requires stable Rust 1.98) | core debugging + best-effort Rust concurrency inspection + remote attach |
|
|
263
285
|
| Perl | perl-tdb (bundled) | perl ≥ 5.18 on PATH | core debugging + remote attach |
|
|
264
286
|
| Bash | bash-tdb (bundled) | bash ≥ 4.4 on PATH | core debugging (no remote attach) |
|
|
@@ -279,7 +301,7 @@ The language is auto-detected from the debug target:
|
|
|
279
301
|
`.sh` / `.bash` → Bash; `.csh` / `.tcsh` → Tcsh; `.rb` → Ruby; `.ps1` /
|
|
280
302
|
`.psm1` → PowerShell. (`.ml` / `.mli` do *not* auto-select OCaml, see
|
|
281
303
|
point 6.)
|
|
282
|
-
3. Native executables (ELF, Mach-O, PE magic bytes) → C/C
|
|
304
|
+
3. Native executables (ELF, Mach-O, PE magic bytes) → C/C++/Fortran, unless
|
|
283
305
|
byte-checking finds an OCaml marker (a native binary's
|
|
284
306
|
`caml_program`/`caml_startup` runtime symbols, a bytecode file's
|
|
285
307
|
trailing `Caml1999` marker, or a `#!...ocamlrun` shebang) → OCaml
|
|
@@ -287,13 +309,13 @@ The language is auto-detected from the debug target:
|
|
|
287
309
|
`go version` itself locates, scanned in the first 16MB of the file) →
|
|
288
310
|
Go. A stripped native OCaml binary, or a Go binary whose buildinfo
|
|
289
311
|
blob sits beyond the 16MB scan window, that byte-checking can't
|
|
290
|
-
identify falls back to C/C
|
|
312
|
+
identify falls back to C/C++/Fortran; force it with `--lang ocaml` or `--lang
|
|
291
313
|
go` respectively. Rust is never inferred from an executable; select it
|
|
292
314
|
explicitly with `--lang rust`.
|
|
293
315
|
4. A `#!...python`, `#!...perl`, `#!...bash`, `#!...csh`/`#!...tcsh`,
|
|
294
316
|
`#!...ruby`, or `#!...pwsh` shebang → Python / Perl / Bash / Tcsh / Ruby /
|
|
295
317
|
PowerShell respectively.
|
|
296
|
-
5. C/C++/Rust *source* files (`.c`, `.cpp`, `.rs`, …) produce an error with a
|
|
318
|
+
5. C/C++/Fortran/Rust *source* files (`.c`, `.cpp`, `.rs`, …) produce an error with a
|
|
297
319
|
hint: compile with debug info (`g++ -g -O0`) and debug the binary.
|
|
298
320
|
6. `.ml` / `.mli` (OCaml source) produce an error too: build the project
|
|
299
321
|
first (dune's dev profile keeps debug info) and pass the **built
|
|
@@ -320,7 +342,7 @@ message naming its path and version; when that `gdb` came from `PATH`
|
|
|
320
342
|
(not from `--adapter` or `config.json`), `tdb` first looks for a newer one
|
|
321
343
|
installed by Red Hat's Software Collections
|
|
322
344
|
(`/opt/rh/gcc-toolset-*/root/usr/bin/gdb`, `/opt/rh/devtoolset-*/...`) and
|
|
323
|
-
uses the newest that qualifies. See [C/C
|
|
345
|
+
uses the newest that qualifies. See [C/C++/Fortran tips](#cc-tips) for RHEL 8.
|
|
324
346
|
|
|
325
347
|
> **Migration note:** extensionless Python scripts without a `python` shebang
|
|
326
348
|
> were previously assumed to be Python; they now require `--lang python`.
|
|
@@ -358,16 +380,16 @@ programs by nature). Remote attach (`-r`) also works for Perl (see
|
|
|
358
380
|
[Perl](#perl), `Devel::TdbRemote` in place of `debugpy.listen()`), Ruby
|
|
359
381
|
(see [Ruby](#ruby), `rdbg --open` in place of `debugpy.listen()`), Go (see
|
|
360
382
|
[Go](#go), `dlv dap --listen` in place of `debugpy.listen()`), and for
|
|
361
|
-
Rust and C/C
|
|
383
|
+
Rust and C/C++/Fortran native binaries (against a gdbserver/lldb-server stub, with
|
|
362
384
|
a local symbol-bearing executable; see [Rust](#rust) — the same flags work
|
|
363
|
-
for a C/C
|
|
385
|
+
for a C/C++/Fortran target without `--lang`), but not for Bash, Tcsh, OCaml, or
|
|
364
386
|
PowerShell. `--terminal` works for every launch-mode
|
|
365
|
-
language — Python, Perl, Bash, Tcsh, Ruby, and C/C
|
|
387
|
+
language — Python, Perl, Bash, Tcsh, Ruby, and C/C++/Fortran, OCaml native, or Rust
|
|
366
388
|
sessions via `--adapter lldb-dap` — see
|
|
367
389
|
[External Terminal Support](#external-terminal-support). Go and PowerShell do
|
|
368
390
|
not support `--terminal` yet (`dlv dap` and PSES have no terminal-routing
|
|
369
391
|
mode). Typing into the Console view to feed the program's stdin works for
|
|
370
|
-
Python, Perl, Bash, Tcsh, Ruby, and PowerShell, but not for C/C
|
|
392
|
+
Python, Perl, Bash, Tcsh, Ruby, and PowerShell, but not for C/C++/Fortran, Rust,
|
|
371
393
|
OCaml, or Go, whose adapters spawn the debuggee themselves — see
|
|
372
394
|
[Console Output and Input](#console-output-and-input).
|
|
373
395
|
|
|
@@ -458,14 +480,14 @@ picture:
|
|
|
458
480
|
multiprocessing child attach.
|
|
459
481
|
- Detection of a Go binary via buildinfo check scans only the first
|
|
460
482
|
16MB of the file; a huge binary whose buildinfo blob sits beyond that
|
|
461
|
-
falls back to C/C
|
|
483
|
+
falls back to C/C++/Fortran — force it with `--lang go`.
|
|
462
484
|
- `-a`/`--attach`'s language auto-detection (reading the target pid's
|
|
463
485
|
buildinfo from `/proc/PID/exe`) is Linux-only; on macOS/Windows pass
|
|
464
486
|
`--lang go` alongside `-a`.
|
|
465
487
|
|
|
466
488
|
See [Go](#go) below for launch details.
|
|
467
489
|
|
|
468
|
-
### C/C
|
|
490
|
+
### C/C++/Fortran tips
|
|
469
491
|
|
|
470
492
|
- Compile with `-g` (ideally `-g -O0` or `-g3 -O0`).
|
|
471
493
|
If no breakpoint in a file can be
|
|
@@ -485,6 +507,29 @@ See [Go](#go) below for launch details.
|
|
|
485
507
|
- GDB (the default adapter) has the most complete libstdc++
|
|
486
508
|
pretty-printing. `lldb-dap` (via `--adapter lldb-dap`) also debugs
|
|
487
509
|
GCC-built binaries fine. DWARF is compiler-neutral.
|
|
510
|
+
- **STL containers in the Variables view.** A distro `gdb` shows
|
|
511
|
+
`std::vector<Result>` as `std::vector of length 2, capacity 2` with
|
|
512
|
+
`[0]`, `[1]` children because gcc installs libstdc++'s pretty-printers
|
|
513
|
+
next to it and `gdb` auto-loads them. A `gdb` built from source into
|
|
514
|
+
its own prefix never finds that auto-load script and shows the same
|
|
515
|
+
variable as `_M_impl` / `_M_start` pointer soup. `tdb` sources a small
|
|
516
|
+
helper into every `gdb` session that, on the first `std::` value it
|
|
517
|
+
sees, looks for gcc's printers (the distro auto-load script for the
|
|
518
|
+
loaded `libstdc++.so`, `share/gcc*/python` near that library or near
|
|
519
|
+
gdb's data directory, then the usual distro, Red Hat toolset, Homebrew
|
|
520
|
+
and MacPorts locations) and uses them; when none are installed it
|
|
521
|
+
falls back to its own bundled printers for `std::string`, `vector`,
|
|
522
|
+
`deque`, `list`, `map`/`set` (and multi-), `unordered_map`/`set`,
|
|
523
|
+
`unique_ptr`, `shared_ptr`/`weak_ptr` and `optional`. Printers gdb
|
|
524
|
+
auto-loads itself or that your `.gdbinit` registers still take
|
|
525
|
+
precedence. The helper also shields gdb's DAP layer from gcc 15's map
|
|
526
|
+
and set printers, whose child count is broken there (expanding a
|
|
527
|
+
`std::map` fails with "name 'self' is not defined" on an unpatched
|
|
528
|
+
distro gdb). `TDB_GDB_STL_PRINTERS` tunes it: `off` registers nothing,
|
|
529
|
+
`bundled` forces the bundled printers (and drops gdb's auto-loaded
|
|
530
|
+
ones), a directory holding `libstdcxx/` names gcc's printers
|
|
531
|
+
explicitly. Type `tdb-stl-printers` in the evaluate console to see
|
|
532
|
+
which printers are in use.
|
|
488
533
|
- **GDB evaluate-console quirk:** GDB's DAP treats REPL input as CLI
|
|
489
534
|
commands, so evaluate expressions with an explicit `print`, e.g.
|
|
490
535
|
`print x` rather than bare `x` (bare `x` collides with GDB's
|
|
@@ -501,7 +546,8 @@ See [Go](#go) below for launch details.
|
|
|
501
546
|
from the evaluate console without you having typed `list`.
|
|
502
547
|
- **RHEL 8 (and 9) gdb is too old for DAP:** the stock `/usr/bin/gdb` is
|
|
503
548
|
8.2 on RHEL 8 (10.2 on RHEL 9) and answers `gdb -i dap` with
|
|
504
|
-
``Interpreter `dap' unrecognized``. Install a newer one
|
|
549
|
+
``Interpreter `dap' unrecognized``. Install a newer one
|
|
550
|
+
(minimum GCC Toolset version is 14) from the
|
|
505
551
|
GCC Toolset, which leaves `/usr/bin/gdb` alone:
|
|
506
552
|
|
|
507
553
|
```bash
|
|
@@ -517,19 +563,22 @@ See [Go](#go) below for launch details.
|
|
|
517
563
|
wrote the file). Either delete the entry or point it at the toolset
|
|
518
564
|
gdb. A GDB ≥ 14 that was built without Python support gives the same
|
|
519
565
|
``Interpreter `dap' unrecognized`` error (`gdb --configuration` shows
|
|
520
|
-
`--without-python`);
|
|
566
|
+
`--without-python`); `tdb --info` probes for this and reports
|
|
567
|
+
`GDB LACKS DAP CAPABILITY AND CANNOT BE USED` in its `DAP interpreter`
|
|
568
|
+
row when the gdb it found rejects `-i dap`. Use `--adapter lldb-dap`
|
|
569
|
+
or a gdb built with
|
|
521
570
|
Python.
|
|
522
571
|
|
|
523
572
|
**Attach to a running process:** `tdb -a PID` attaches gdb (or `--adapter
|
|
524
573
|
lldb-dap`) to a live native process and stops it. On Linux tdb reads
|
|
525
574
|
`/proc/PID/exe` to identify the language (Go, OCaml, Rust, otherwise
|
|
526
|
-
C/C
|
|
575
|
+
C/C++/Fortran) and to load symbols; pass the executable path as well to use a
|
|
527
576
|
different symbol file, and pass `--lang` off Linux. `--no-pause-on-attach`
|
|
528
577
|
leaves the process running, for a program about to stop itself. An
|
|
529
|
-
interpreter process (python3, perl, ruby, bash) is attached as C/C
|
|
578
|
+
interpreter process (python3, perl, ruby, bash) is attached as C/C++/Fortran; for
|
|
530
579
|
Python, Perl, and Ruby programs use `--remote-attach` instead.
|
|
531
580
|
|
|
532
|
-
**Live breakpoint hook:** the C/C
|
|
581
|
+
**Live breakpoint hook:** the C/C++/Fortran counterpart of Python's
|
|
533
582
|
[`tdb.breakpoint()`](#live-breakpoint-hook). Include `tdb.h` (its directory
|
|
534
583
|
is the `tdb.h dir` row of `tdb --info`) and call `tdb_breakpoint()`:
|
|
535
584
|
|
|
@@ -567,6 +616,29 @@ header-only. Linux only: the hook grants ptrace access to tdb's debugger
|
|
|
567
616
|
with `PR_SET_PTRACER`; elsewhere it warns once and returns. See
|
|
568
617
|
`examples/C/breakpoint_hook_demo.c` and `examples/C++/breakpoint_hook_demo.cpp`.
|
|
569
618
|
|
|
619
|
+
Fortran (or any language that can call C) uses the same header: compile
|
|
620
|
+
`tdb.h` as C into an object that defines `tdb_breakpoint()`, declare it with
|
|
621
|
+
`bind(C)`, and link the object in:
|
|
622
|
+
|
|
623
|
+
```fortran
|
|
624
|
+
interface
|
|
625
|
+
subroutine tdb_breakpoint() bind(C, name="tdb_breakpoint")
|
|
626
|
+
end subroutine tdb_breakpoint
|
|
627
|
+
end interface
|
|
628
|
+
...
|
|
629
|
+
call tdb_breakpoint() ! tdb opens here, paused on the next line
|
|
630
|
+
```
|
|
631
|
+
|
|
632
|
+
```bash
|
|
633
|
+
gcc -g -O0 -c -x c "$(tdb --info | awk -F': ' '/tdb.h dir/ {print $2}')/tdb.h" -o tdb.o
|
|
634
|
+
gfortran -g -O0 -o prog prog.f90 tdb.o
|
|
635
|
+
./prog # run it directly, not under tdb
|
|
636
|
+
```
|
|
637
|
+
|
|
638
|
+
Use gdb (the default) for Fortran: lldb-dap stops on the right line but,
|
|
639
|
+
lacking Fortran support, shows no Fortran locals. See
|
|
640
|
+
`examples/Fortran/breakpoint_hook_demo.f90`.
|
|
641
|
+
|
|
570
642
|
### Rust
|
|
571
643
|
|
|
572
644
|
Rust debugging is intentionally explicit: build a normal debug executable,
|
|
@@ -587,7 +659,7 @@ cargo rustc -- -C debuginfo=2 -C opt-level=0
|
|
|
587
659
|
# Equivalent direct rustc settings: rustc -C debuginfo=2 -C opt-level=0 src/main.rs
|
|
588
660
|
```
|
|
589
661
|
|
|
590
|
-
As for C/C
|
|
662
|
+
As for C/C++/Fortran, the Console view cannot feed the program's stdin (the gdb and
|
|
591
663
|
lldb adapters spawn it themselves); use `--terminal` with `--adapter
|
|
592
664
|
lldb-dap` for interactive programs. A panic that terminates the debuggee opens the error modal with the parsed
|
|
593
665
|
panic message and backtrace; `tdb` injects `RUST_BACKTRACE=1` into launched
|
|
@@ -624,7 +696,7 @@ for example `ssh -L 2345:127.0.0.1:2345 host`, then attach to `127.0.0.1:2345`.
|
|
|
624
696
|
`--adapter lldb-dap`) to a live Rust process and stops it; tdb loads
|
|
625
697
|
symbols from `/proc/PID/exe`, or from an executable path you pass as well.
|
|
626
698
|
Without `--lang`, tdb recognizes a non-stripped Rust binary by its runtime
|
|
627
|
-
symbols; a stripped one is debugged as C/C
|
|
699
|
+
symbols; a stripped one is debugged as C/C++/Fortran.
|
|
628
700
|
|
|
629
701
|
**Live breakpoint hook:** the Rust counterpart of Python's
|
|
630
702
|
[`tdb.breakpoint()`](#live-breakpoint-hook). Depend on the `tdb` crate from
|
|
@@ -696,12 +768,20 @@ per interpreter under its config directory (`~/.config/tdb/padwalker/` on
|
|
|
696
768
|
Linux/macOS, `%APPDATA%\\tdb\\padwalker\\` on Windows), and prepends that
|
|
697
769
|
directory to the debuggee's `PERL5LIB`. The build takes about a second and
|
|
698
770
|
needs perl's headers (`libperl-dev` on Debian/Ubuntu, `perl-devel` on
|
|
699
|
-
Fedora/RHEL)
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
771
|
+
Fedora/RHEL), a C compiler, and the core `ExtUtils::MakeMaker` module (some
|
|
772
|
+
minimal distro perls omit it; `perl-ExtUtils-MakeMaker` on Fedora/RHEL);
|
|
773
|
+
Strawberry Perl on Windows ships all three. When the build is not possible,
|
|
774
|
+
`tdb` prints a one-line notice on the console and falls back to a read-only
|
|
775
|
+
pad walk, so outer-frame lexicals degrade but debugging otherwise proceeds.
|
|
776
|
+
`tdb --info` reports the source directory, the cache directory, and the
|
|
777
|
+
`ExtUtils::MakeMaker` version of the `perl` it would use, with a warning when
|
|
778
|
+
that module is missing and PadWalker therefore cannot be built.
|
|
704
779
|
`TDB_PADWALKER_CACHE` overrides the cache location.
|
|
780
|
+
To build it ahead of time (for example when provisioning a machine, or to
|
|
781
|
+
see the compiler's error output without starting a debug session), run
|
|
782
|
+
`tdb --config install-padwalker`; it exits 0 when PadWalker loads
|
|
783
|
+
(natively, from the cache, or freshly built) and 1 with the reason when it
|
|
784
|
+
cannot be built.
|
|
705
785
|
|
|
706
786
|
**Launching a script:**
|
|
707
787
|
|
|
@@ -1001,7 +1081,7 @@ tihs line correctly.
|
|
|
1001
1081
|
usual behavior.
|
|
1002
1082
|
|
|
1003
1083
|
A stripped native binary that byte-checking can't identify as OCaml falls
|
|
1004
|
-
back to C/C
|
|
1084
|
+
back to C/C++/Fortran; force it with `--lang ocaml`. Override the adapter or point
|
|
1005
1085
|
at a non-`PATH` install in `config.json` (see
|
|
1006
1086
|
[Configuration](#configuration)):
|
|
1007
1087
|
|
|
@@ -1131,7 +1211,7 @@ tdb -r host:port --lang go # attach to a `dlv dap --listen` already running remo
|
|
|
1131
1211
|
|
|
1132
1212
|
`tdb --test ./pkg` debugs the package's tests under Delve's `test` mode;
|
|
1133
1213
|
pass test-binary flags after `--`, e.g. `tdb --test ./pkg -- -run TestFoo`.
|
|
1134
|
-
`-a`/`--attach` works for Go and, through gdb/lldb-dap, for C/C
|
|
1214
|
+
`-a`/`--attach` works for Go and, through gdb/lldb-dap, for C/C++/Fortran, Rust,
|
|
1135
1215
|
and OCaml; on Linux `tdb` identifies the language from `/proc/PID/exe`
|
|
1136
1216
|
without `--lang` (elsewhere pass `--lang go` alongside `-a`). Attaching
|
|
1137
1217
|
stops the process immediately so you get control right away;
|
|
@@ -1330,6 +1410,13 @@ A cursor line (blue) tracks your position; the current execution line is highlig
|
|
|
1330
1410
|
| `Ctrl+S` | Stack View |
|
|
1331
1411
|
| `Ctrl+B` | Breakpoint View |
|
|
1332
1412
|
|
|
1413
|
+
Pressing the shortcut of the view that already has focus returns focus to
|
|
1414
|
+
the previous view, so e.g. `Ctrl+E` jumps from the Code View to the
|
|
1415
|
+
Evaluate Console and a second `Ctrl+E` jumps back.
|
|
1416
|
+
The shortcuts also work while typing in the Evaluate Console and the
|
|
1417
|
+
Console View's stdin line, where `Ctrl+E` and `Ctrl+V` take precedence over
|
|
1418
|
+
end-of-line and paste (`End` and the terminal's own paste still work).
|
|
1419
|
+
|
|
1333
1420
|
**Menu-bar shortcuts (global):**
|
|
1334
1421
|
|
|
1335
1422
|
`Alt+<first-letter>` opens the corresponding tab in the menu bar.
|
|
@@ -1507,7 +1594,7 @@ returns. Two ways to pin, two ways to unpin:
|
|
|
1507
1594
|
| | Evaluate Console | Variables View |
|
|
1508
1595
|
|---|---|---|
|
|
1509
1596
|
| pin | `display b` | right-click the variable's row |
|
|
1510
|
-
| unpin | `undisplay b` |
|
|
1597
|
+
| unpin | `undisplay b` | right-click its row under **Display** |
|
|
1511
1598
|
|
|
1512
1599
|
```
|
|
1513
1600
|
>>> display b
|
|
@@ -1523,6 +1610,8 @@ returns. Two ways to pin, two ways to unpin:
|
|
|
1523
1610
|
|
|
1524
1611
|
Right-clicking a child of an expanded object pins the full path
|
|
1525
1612
|
(`obj.count`, `items[2]`), and a bare `display` lists everything pinned.
|
|
1613
|
+
Left-click works the same under **Display** as in every other scope:
|
|
1614
|
+
it expands or collapses an object, and a double-click opens it in a modal.
|
|
1526
1615
|
A click in the Variables View is recorded exactly as the typed command,
|
|
1527
1616
|
so `--record`/`--replay` sessions reproduce it. Some terminals keep
|
|
1528
1617
|
right-click for their own paste or context menu (Windows Terminal and
|
|
@@ -1588,8 +1677,8 @@ variable lives:
|
|
|
1588
1677
|
| tcsh | `set name …`, `setenv NAME …` | the whole run |
|
|
1589
1678
|
| Ruby | `name = …`, `$name = …`, `@name = …` | globals and instance variables persist; plain locals live only in the eval's binding and read back as unavailable after the next step |
|
|
1590
1679
|
| PowerShell | `$name = …`, `$global:name = …` | the function scope, or the whole run for `$global:` |
|
|
1591
|
-
| C/C++/Rust/OCaml under gdb | `set $name = …` (a gdb convenience variable) | the whole run |
|
|
1592
|
-
| C/C++/Rust/OCaml under lldb-dap | `int $name = …` (an lldb persistent variable) | the whole run |
|
|
1680
|
+
| C/C++/Fortran/Rust/OCaml under gdb | `set $name = …` (a gdb convenience variable) | the whole run |
|
|
1681
|
+
| C/C++/Fortran/Rust/OCaml under lldb-dap | `int $name = …` (an lldb persistent variable) | the whole run |
|
|
1593
1682
|
| Go (dlv), OCaml under ocamlearlybird | not possible: their evaluate cannot create variables | — |
|
|
1594
1683
|
|
|
1595
1684
|
A tracked name that no longer resolves (a Python local after its frame
|
|
@@ -1619,7 +1708,7 @@ when the session has no stdin to feed.
|
|
|
1619
1708
|
|
|
1620
1709
|
Stdin forwarding works for the languages whose program `tdb` launches on a
|
|
1621
1710
|
pipe it owns: Python, Perl, Bash, Tcsh, Ruby, and PowerShell. It is not
|
|
1622
|
-
available for the compiled languages — C/C
|
|
1711
|
+
available for the compiled languages — C/C++/Fortran, Rust, OCaml, and Go — because
|
|
1623
1712
|
their adapters (`gdb -i dap`, `lldb-dap`, `dlv dap`) spawn the debuggee
|
|
1624
1713
|
themselves and give `tdb` no handle on its stdin; the input line stays
|
|
1625
1714
|
hidden there. It is also unavailable for remote attach (`-r`), where the
|
|
@@ -1744,12 +1833,57 @@ This behavior matches hitting `c` while in a conventional (that is, the Python
|
|
|
1744
1833
|
standard library's) `breakpoint()` session.
|
|
1745
1834
|
If you want to kill the program instead, use `Ctrl+c` in the terminal running the debuggee.
|
|
1746
1835
|
|
|
1747
|
-
Perl, Ruby, Go, C/C
|
|
1836
|
+
Perl, Ruby, Go, C/C++/Fortran, Rust, and OCaml programs get the same hook as
|
|
1748
1837
|
`Devel::TdbRemote::breakpoint()`, `Tdb.breakpoint`, `tdb.Breakpoint()`,
|
|
1749
1838
|
`tdb_breakpoint()`, `tdb::breakpoint()`, and `Tdb.breakpoint ()`; see
|
|
1750
|
-
[Perl](#perl), [Ruby](#ruby), [Go](#go), [C/C
|
|
1839
|
+
[Perl](#perl), [Ruby](#ruby), [Go](#go), [C/C++/Fortran tips](#cc-tips),
|
|
1751
1840
|
[Rust](#rust), and [OCaml](#ocaml).
|
|
1752
1841
|
|
|
1842
|
+
### pytest Integration (`--pdbcls`)
|
|
1843
|
+
|
|
1844
|
+
`tdb` can stand in for `pdb` when `pytest` stops on a failing test, the
|
|
1845
|
+
same way IPython (`--pdbcls=IPython.terminal.debugger:Pdb`) and pudb
|
|
1846
|
+
(`--pdbcls=pudb.debugger:Debugger`) do:
|
|
1847
|
+
|
|
1848
|
+
```bash
|
|
1849
|
+
pytest --pdb --pdbcls=tdb.pytest_debugger:Debugger
|
|
1850
|
+
```
|
|
1851
|
+
|
|
1852
|
+
`-s` / `--capture=no` is not required; pytest suspends output capturing
|
|
1853
|
+
before handing control to the debugger. To make it the default, add the
|
|
1854
|
+
options to your pytest configuration:
|
|
1855
|
+
|
|
1856
|
+
```toml
|
|
1857
|
+
[tool.pytest.ini_options]
|
|
1858
|
+
addopts = "--pdbcls=tdb.pytest_debugger:Debugger"
|
|
1859
|
+
```
|
|
1860
|
+
|
|
1861
|
+
(`tdb.pytest_debugger:Pdb` is an alias for the same class.)
|
|
1862
|
+
|
|
1863
|
+
What you get depends on how pytest enters the debugger:
|
|
1864
|
+
|
|
1865
|
+
| pytest trigger | `tdb` behavior |
|
|
1866
|
+
|---|---|
|
|
1867
|
+
| `--pdb`, test fails or errors | Post-mortem TUI on the failing test, as with [`tdb.exception_hook`](#post-mortem-exception-hook). Navigate the stack and inspect every frame's variables at the point of failure. pytest's own runner frames are trimmed from the Stack View. Quit `tdb` (`q`, then `q` again to confirm) and pytest moves on to the next test. |
|
|
1868
|
+
| `breakpoint()` or `pytest.set_trace()` in a test | Live `tdb` attached to the pytest process, paused on the line after the call, as with [`tdb.breakpoint()`](#live-breakpoint-hook). Step, evaluate, set breakpoints, continue. |
|
|
1869
|
+
| `--trace` | Live `tdb` paused on the first line of each test. |
|
|
1870
|
+
|
|
1871
|
+
Notes:
|
|
1872
|
+
|
|
1873
|
+
- Post-mortem mode is a frozen snapshot: no Evaluate View, no stepping.
|
|
1874
|
+
For a live view of a failure, put a `breakpoint()` in the test (or use
|
|
1875
|
+
`--trace`) and `continue`. `tdb` stops on the failing line with the
|
|
1876
|
+
interpreter still alive.
|
|
1877
|
+
- One live `tdb` serves the whole pytest run. After `continue` it stays
|
|
1878
|
+
attached, showing **Running**, and the next `breakpoint()` or `--trace`
|
|
1879
|
+
stop appears in it. If a test fails under `--pdb` while it is still
|
|
1880
|
+
attached, the post-mortem view opens once you quit the live `tdb`.
|
|
1881
|
+
- Every failure opens its own post-mortem session. Combine with `-x` or
|
|
1882
|
+
`--maxfail=N` to limit how many you step through.
|
|
1883
|
+
- Live stops need `debugpy` installed in the environment running pytest.
|
|
1884
|
+
- When stdin/stdout aren't a terminal (CI, `pytest-xdist` workers), the
|
|
1885
|
+
class falls back to plain `pdb` behavior.
|
|
1886
|
+
|
|
1753
1887
|
### Async Task Inspector
|
|
1754
1888
|
|
|
1755
1889
|
For programs using `asyncio`, the menu bar shows an **Async Tasks (N)** label with the count of
|
|
@@ -1924,8 +2058,8 @@ tdb --terminal xterm my_tui_app.py
|
|
|
1924
2058
|
```
|
|
1925
2059
|
|
|
1926
2060
|
`--terminal` works for every language `tdb` can *launch* (as opposed to
|
|
1927
|
-
attach to): Python, Perl, Bash, Tcsh, Ruby, and C/C
|
|
1928
|
-
sessions via `--adapter lldb-dap`. Neither `gdb -i dap` (the default C/C
|
|
2061
|
+
attach to): Python, Perl, Bash, Tcsh, Ruby, and C/C++/Fortran or native OCaml
|
|
2062
|
+
sessions via `--adapter lldb-dap`. Neither `gdb -i dap` (the default C/C++/Fortran
|
|
1929
2063
|
adapter, and an alternate for native OCaml) nor `ocamlearlybird` (the
|
|
1930
2064
|
bytecode OCaml adapter) has any terminal integration -- `tdb` rejects
|
|
1931
2065
|
`--terminal` up front for both, with an error pointing at `--adapter
|
|
@@ -2033,7 +2167,7 @@ nonzero `sys.exit()`, which `debugpy` treats as an uncaught `SystemExit` -- `tdb
|
|
|
2033
2167
|
the TUI at the point of failure instead of exiting silently, so you can inspect the
|
|
2034
2168
|
crash. Exit-code passthrough applies only to a clean exit during the headless phase.
|
|
2035
2169
|
|
|
2036
|
-
Supported languages: Python, Perl, Bash, Tcsh, Ruby, PowerShell 7, C/C
|
|
2170
|
+
Supported languages: Python, Perl, Bash, Tcsh, Ruby, PowerShell 7, C/C++/Fortran
|
|
2037
2171
|
(both `gdb` and `lldb-dap`), and native OCaml (both `gdb` and `lldb-dap`;
|
|
2038
2172
|
bytecode/`ocamlearlybird` sessions don't support pause, so `--run` is
|
|
2039
2173
|
unavailable for those). `--run` is rejected up front for any other
|
|
@@ -2043,7 +2177,18 @@ language.
|
|
|
2043
2177
|
blocking external call or syscall, the pause can't land until that call returns --
|
|
2044
2178
|
`tdb` prints a notice and opens the TUI once the stop actually arrives.
|
|
2045
2179
|
|
|
2046
|
-
**
|
|
2180
|
+
**Breakpoints:** run mode never uses breakpoints saved in `breakpoints.json`, and
|
|
2181
|
+
never writes to it either, so the breakpoints you saved for normal sessions are left
|
|
2182
|
+
untouched. Breakpoints given on the command line with `-k`/`-t` are accepted, but they
|
|
2183
|
+
stay inactive while the program runs headlessly. They are installed the first time the
|
|
2184
|
+
TUI opens (normally when you press Ctrl-C), and stay live after you detach, so the
|
|
2185
|
+
program then stops at them:
|
|
2186
|
+
|
|
2187
|
+
```bash
|
|
2188
|
+
tdb --run -k 120 -k utils.py:45 my_program.py # breakpoints arm on the first Ctrl-C
|
|
2189
|
+
```
|
|
2190
|
+
|
|
2191
|
+
**Incompatible flags:** `-r`, `--record`, `--replay`, `--replay-tui`, `--server`,
|
|
2047
2192
|
`--headless`, `--mcp`, `--terminal`.
|
|
2048
2193
|
|
|
2049
2194
|
### Eval Mode (`-e`/`--eval`)
|
|
@@ -2085,7 +2230,7 @@ evaluated in each child process that reaches it.
|
|
|
2085
2230
|
uncaught-exception stop) is continued untouched, so the program runs to
|
|
2086
2231
|
completion unattended.
|
|
2087
2232
|
- For non-Python debuggees the expression must be in the debug adapter's
|
|
2088
|
-
own syntax, for example gdb's `print x` / `set var x=3` for C/C
|
|
2233
|
+
own syntax, for example gdb's `print x` / `set var x=3` for C/C++/Fortran, and not
|
|
2089
2234
|
necessarily the debuggee's language. The adapter may bind the breakpoint
|
|
2090
2235
|
to the next executable line (gdb moves one off a declaration or brace);
|
|
2091
2236
|
the eval point matches that bound line, so the expression still runs.
|
|
@@ -2272,6 +2417,16 @@ its companion `examples/sales_report_buggy.py`.
|
|
|
2272
2417
|
|
|
2273
2418
|
### Running the MCP server
|
|
2274
2419
|
|
|
2420
|
+
The MCP server needs the optional `mcp` extra:
|
|
2421
|
+
|
|
2422
|
+
```bash
|
|
2423
|
+
pip install "textual-debugger[mcp]"
|
|
2424
|
+
```
|
|
2425
|
+
|
|
2426
|
+
Without it, `tdb-mcp` and `tdb --mcp` exit with that install hint, and
|
|
2427
|
+
`tdb --info` reports `MCP server : not installed`. Everything else in
|
|
2428
|
+
tdb works without the extra.
|
|
2429
|
+
|
|
2275
2430
|
Configure your MCP client (Claude Desktop, an IDE extension, etc.) to
|
|
2276
2431
|
launch `tdb-mcp` over stdio. Example `claude_desktop_config.json`:
|
|
2277
2432
|
|
|
@@ -2357,13 +2512,14 @@ usage: tdb [-h] [-v] [-r [HOST:]PORT] [--cwd CWD] [--no-stop-on-entry]
|
|
|
2357
2512
|
[--terminal {xterm,konsole,gnome-terminal,ghostty,kitty,iterm2,warp,wezterm,terminator}]
|
|
2358
2513
|
[--local-root PATH] [--remote-root PATH]
|
|
2359
2514
|
[--server] [--headless] [-k FILE:LINE|LINE] [--server-port SERVER_PORT] [-d] [--doc-text] [--info]
|
|
2515
|
+
[--config {write-default,install-padwalker}]
|
|
2360
2516
|
[program] [args ...]
|
|
2361
2517
|
```
|
|
2362
2518
|
|
|
2363
2519
|
| Flag | Description |
|
|
2364
2520
|
|------|-------------|
|
|
2365
2521
|
| `-r HOST:PORT` | Attach to a remote debugpy server |
|
|
2366
|
-
| `-a`, `--attach PID` | Attach to a running local process by pid: Go (Delve) or a native C/C++, Rust, or OCaml program (gdb or lldb-dap). Linux identifies the language from `/proc/PID/exe`; elsewhere pass `--lang` and, for native programs, the executable path. |
|
|
2522
|
+
| `-a`, `--attach PID` | Attach to a running local process by pid: Go (Delve) or a native C/C++, Fortran, Rust, or OCaml program (gdb or lldb-dap). Linux identifies the language from `/proc/PID/exe`; elsewhere pass `--lang` and, for native programs, the executable path. |
|
|
2367
2523
|
| `--local-root PATH` | Local directory containing a copy of remote code (repeat to mirror multiple trees). Pair with `--remote-root`; counts must match. Required when `-k` sets a breakpoint against a remote debuggee whose code lives at a different path. |
|
|
2368
2524
|
| `--remote-root PATH` | Remote directory matched to `--local-root` (same CLI position via `zip()`). |
|
|
2369
2525
|
| `-k`, `--breakpoint FILE:LINE|LINE` | Set a breakpoint (may be repeated). Passing `-k` implies `--no-stop-on-entry` so the program runs straight to the first breakpoint. |
|
|
@@ -2392,6 +2548,11 @@ usage: tdb [-h] [-v] [-r [HOST:]PORT] [--cwd CWD] [--no-stop-on-entry]
|
|
|
2392
2548
|
| `--replay-interval S` | With `--replay`/`--replay-tui`: fixed S-second delay before each action instead of the recorded gaps |
|
|
2393
2549
|
| `--replay-timeout S` | With `--replay`/`--replay-tui`: per-action stop-wait timeout (default 30) |
|
|
2394
2550
|
| `--examine-log DEST` | With --run: write each Ctrl-\ / SIGUSR2 stack snapshot to DEST (- = stdout; repeatable) |
|
|
2551
|
+
| `--doc` | Display this README in a terminal Markdown viewer and exit |
|
|
2552
|
+
| `--doc-text` | Print this README to stdout as wrapped plain text and exit |
|
|
2553
|
+
| `--info` | Print the About text, file locations, and the path and version of each interpreter and debugger `tdb` would use, then exit |
|
|
2554
|
+
| `--config write-default` | Rename the existing `config.json` to `config.json-YYYY-mm-DD-HH:MM:SS` (`HH.MM.SS` on Windows, which forbids colons in filenames) and write a new one holding every default value, then exit |
|
|
2555
|
+
| `--config install-padwalker` | Build and cache the bundled PadWalker Perl module now, for the perl `tdb` would debug with (`adapters.perl` in `config.json`, else `perl` on `PATH`), instead of waiting for the first Perl launch; exits 1 if it cannot be built |
|
|
2395
2556
|
|
|
2396
2557
|
## Configuration
|
|
2397
2558
|
|
|
@@ -2406,7 +2567,9 @@ On Windows, it uses `%APPDATA%\tdb\`.
|
|
|
2406
2567
|
|
|
2407
2568
|
### Sample `config.json`
|
|
2408
2569
|
|
|
2409
|
-
Every key `tdb` reads, with its default or a representative value.
|
|
2570
|
+
Every key `tdb` reads, with its default or a representative value.
|
|
2571
|
+
`tdb --config write-default` writes a fresh file with these defaults
|
|
2572
|
+
(moving the old one aside as `config.json-YYYY-mm-DD-HH:MM:SS`), or copy
|
|
2410
2573
|
this to restore a deleted or corrupted file, then delete the entries you
|
|
2411
2574
|
don't need: a missing key takes its default, an unknown key is ignored,
|
|
2412
2575
|
and an invalid value (say a misspelled `step_mode`) falls back to the
|
|
@@ -2495,7 +2658,7 @@ fires as expected.
|
|
|
2495
2658
|
|
|
2496
2659
|
- [textual](https://github.com/Textualize/textual) : TUI framework
|
|
2497
2660
|
- [debugpy](https://github.com/microsoft/debugpy) : Debug Adapter Protocol implementation for Python
|
|
2498
|
-
- [gdb](https://sourceware.org/gdb/) / [lldb-dap](https://lldb.llvm.org/resources/lldbdap.html) : optional, user-installed DAP adapters for C/C
|
|
2661
|
+
- [gdb](https://sourceware.org/gdb/) / [lldb-dap](https://lldb.llvm.org/resources/lldbdap.html) : optional, user-installed DAP adapters for C/C++/Fortran
|
|
2499
2662
|
- [debug gem](https://github.com/ruby/debug) (`rdbg`) : optional, user-installed DAP adapter for Ruby
|
|
2500
2663
|
- [ocamlearlybird](https://github.com/hackwaly/ocamlearlybird) : optional, user-installed DAP adapter for OCaml bytecode (native OCaml reuses `gdb`/`lldb-dap`)
|
|
2501
2664
|
- [pygments](https://pygments.org/) : Syntax highlighting
|