textual-debugger 0.2.8__tar.gz → 0.2.10__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.8 → textual_debugger-0.2.10}/PKG-INFO +296 -45
- {textual_debugger-0.2.8/src/tdb → textual_debugger-0.2.10}/README.md +294 -43
- {textual_debugger-0.2.8 → textual_debugger-0.2.10}/pyproject.toml +2 -2
- {textual_debugger-0.2.8 → textual_debugger-0.2.10/src/tdb}/README.md +294 -43
- {textual_debugger-0.2.8 → textual_debugger-0.2.10}/src/tdb/__init__.py +1 -1
- {textual_debugger-0.2.8 → textual_debugger-0.2.10}/src/tdb/_timeouts.py +4 -0
- textual_debugger-0.2.10/src/tdb/adapters/powershell/__init__.py +3 -0
- textual_debugger-0.2.10/src/tdb/adapters/powershell/__main__.py +23 -0
- textual_debugger-0.2.10/src/tdb/adapters/powershell/locate.py +121 -0
- textual_debugger-0.2.10/src/tdb/adapters/powershell/output.py +80 -0
- textual_debugger-0.2.10/src/tdb/adapters/powershell/server.py +913 -0
- textual_debugger-0.2.10/src/tdb/adapters/powershell/tdb_launch.ps1 +14 -0
- textual_debugger-0.2.10/src/tdb/adapters/seqs.py +62 -0
- {textual_debugger-0.2.8 → textual_debugger-0.2.10}/src/tdb/app.py +3 -0
- {textual_debugger-0.2.8 → textual_debugger-0.2.10}/src/tdb/app_handlers/inspection.py +71 -1
- {textual_debugger-0.2.8 → textual_debugger-0.2.10}/src/tdb/app_handlers/routing.py +36 -0
- {textual_debugger-0.2.8 → textual_debugger-0.2.10}/src/tdb/app_handlers/ui_panels.py +39 -0
- {textual_debugger-0.2.8 → textual_debugger-0.2.10}/src/tdb/breakpoint_hook.py +16 -1
- {textual_debugger-0.2.8 → textual_debugger-0.2.10}/src/tdb/cli.py +215 -15
- {textual_debugger-0.2.8 → textual_debugger-0.2.10}/src/tdb/dap/client.py +77 -1
- textual_debugger-0.2.10/src/tdb/eval_mode.py +314 -0
- textual_debugger-0.2.10/src/tdb/go_concurrency/analyzer.py +112 -0
- textual_debugger-0.2.10/src/tdb/go_concurrency/classifier.py +59 -0
- textual_debugger-0.2.10/src/tdb/go_concurrency/collector.py +122 -0
- textual_debugger-0.2.10/src/tdb/go_concurrency/models.py +123 -0
- {textual_debugger-0.2.8 → textual_debugger-0.2.10}/src/tdb/languages/base.py +25 -0
- {textual_debugger-0.2.8 → textual_debugger-0.2.10}/src/tdb/languages/errors.py +210 -0
- textual_debugger-0.2.10/src/tdb/languages/go.py +217 -0
- {textual_debugger-0.2.8 → textual_debugger-0.2.10}/src/tdb/languages/ocaml.py +78 -3
- textual_debugger-0.2.10/src/tdb/languages/powershell.py +124 -0
- {textual_debugger-0.2.8 → textual_debugger-0.2.10}/src/tdb/languages/registry.py +26 -3
- {textual_debugger-0.2.8 → textual_debugger-0.2.10}/src/tdb/mcp/server.py +12 -0
- {textual_debugger-0.2.8 → textual_debugger-0.2.10}/src/tdb/run_mode.py +64 -30
- {textual_debugger-0.2.8 → textual_debugger-0.2.10}/src/tdb/server/handlers.py +21 -0
- {textual_debugger-0.2.8 → textual_debugger-0.2.10}/src/tdb/server/runner.py +4 -0
- {textual_debugger-0.2.8 → textual_debugger-0.2.10}/src/tdb/session/controller.py +83 -3
- {textual_debugger-0.2.8 → textual_debugger-0.2.10}/src/tdb/session/inspect_service.py +12 -3
- {textual_debugger-0.2.8 → textual_debugger-0.2.10}/src/tdb/session/state.py +7 -0
- textual_debugger-0.2.10/src/tdb/widgets/__init__.py +0 -0
- textual_debugger-0.2.10/src/tdb/widgets/goroutines_modal.py +354 -0
- {textual_debugger-0.2.8 → textual_debugger-0.2.10}/src/textual_debugger.egg-info/PKG-INFO +296 -45
- {textual_debugger-0.2.8 → textual_debugger-0.2.10}/src/textual_debugger.egg-info/SOURCES.txt +16 -0
- {textual_debugger-0.2.8 → textual_debugger-0.2.10}/src/textual_debugger.egg-info/requires.txt +1 -1
- {textual_debugger-0.2.8 → textual_debugger-0.2.10}/LICENSE +0 -0
- {textual_debugger-0.2.8 → textual_debugger-0.2.10}/setup.cfg +0 -0
- {textual_debugger-0.2.8 → textual_debugger-0.2.10}/src/tdb/__main__.py +0 -0
- {textual_debugger-0.2.8 → textual_debugger-0.2.10}/src/tdb/adapters/__init__.py +0 -0
- {textual_debugger-0.2.8 → textual_debugger-0.2.10}/src/tdb/adapters/bash/__init__.py +0 -0
- {textual_debugger-0.2.8 → textual_debugger-0.2.10}/src/tdb/adapters/bash/__main__.py +0 -0
- {textual_debugger-0.2.8 → textual_debugger-0.2.10}/src/tdb/adapters/bash/declares.py +0 -0
- {textual_debugger-0.2.8 → textual_debugger-0.2.10}/src/tdb/adapters/bash/server.py +0 -0
- {textual_debugger-0.2.8 → textual_debugger-0.2.10}/src/tdb/adapters/bash/session.py +0 -0
- {textual_debugger-0.2.8 → textual_debugger-0.2.10}/src/tdb/adapters/bash/tdb_harness.sh +0 -0
- {textual_debugger-0.2.8 → textual_debugger-0.2.10}/src/tdb/adapters/ocaml/__init__.py +0 -0
- {textual_debugger-0.2.8 → textual_debugger-0.2.10}/src/tdb/adapters/ocaml/lldb_formatters.py +0 -0
- {textual_debugger-0.2.8 → textual_debugger-0.2.10}/src/tdb/adapters/perl/Devel/TdbCompile.pm +0 -0
- {textual_debugger-0.2.8 → textual_debugger-0.2.10}/src/tdb/adapters/perl/Devel/TdbRemote.pm +0 -0
- {textual_debugger-0.2.8 → textual_debugger-0.2.10}/src/tdb/adapters/perl/__init__.py +0 -0
- {textual_debugger-0.2.8 → textual_debugger-0.2.10}/src/tdb/adapters/perl/__main__.py +0 -0
- {textual_debugger-0.2.8 → textual_debugger-0.2.10}/src/tdb/adapters/perl/helpers.pl +0 -0
- {textual_debugger-0.2.8 → textual_debugger-0.2.10}/src/tdb/adapters/perl/protocol.py +0 -0
- {textual_debugger-0.2.8 → textual_debugger-0.2.10}/src/tdb/adapters/perl/refs.py +0 -0
- {textual_debugger-0.2.8 → textual_debugger-0.2.10}/src/tdb/adapters/perl/server.py +0 -0
- {textual_debugger-0.2.8 → textual_debugger-0.2.10}/src/tdb/adapters/perl/session.py +0 -0
- {textual_debugger-0.2.8 → textual_debugger-0.2.10}/src/tdb/adapters/ruby/__init__.py +0 -0
- {textual_debugger-0.2.8 → textual_debugger-0.2.10}/src/tdb/adapters/ruby/__main__.py +0 -0
- {textual_debugger-0.2.8 → textual_debugger-0.2.10}/src/tdb/adapters/ruby/server.py +0 -0
- {textual_debugger-0.2.8 → textual_debugger-0.2.10}/src/tdb/adapters/tcsh/__init__.py +0 -0
- {textual_debugger-0.2.8 → textual_debugger-0.2.10}/src/tdb/adapters/tcsh/__main__.py +0 -0
- {textual_debugger-0.2.8 → textual_debugger-0.2.10}/src/tdb/adapters/tcsh/breakpoints.py +0 -0
- {textual_debugger-0.2.8 → textual_debugger-0.2.10}/src/tdb/adapters/tcsh/cli.py +0 -0
- {textual_debugger-0.2.8 → textual_debugger-0.2.10}/src/tdb/adapters/tcsh/guardian.py +0 -0
- {textual_debugger-0.2.8 → textual_debugger-0.2.10}/src/tdb/adapters/tcsh/inspect.py +0 -0
- {textual_debugger-0.2.8 → textual_debugger-0.2.10}/src/tdb/adapters/tcsh/instrumenter.py +0 -0
- {textual_debugger-0.2.8 → textual_debugger-0.2.10}/src/tdb/adapters/tcsh/models.py +0 -0
- {textual_debugger-0.2.8 → textual_debugger-0.2.10}/src/tdb/adapters/tcsh/protocol.py +0 -0
- {textual_debugger-0.2.8 → textual_debugger-0.2.10}/src/tdb/adapters/tcsh/runtime.py +0 -0
- {textual_debugger-0.2.8 → textual_debugger-0.2.10}/src/tdb/adapters/tcsh/scanner.py +0 -0
- {textual_debugger-0.2.8 → textual_debugger-0.2.10}/src/tdb/adapters/tcsh/server.py +0 -0
- {textual_debugger-0.2.8 → textual_debugger-0.2.10}/src/tdb/adapters/tcsh/session.py +0 -0
- {textual_debugger-0.2.8 → textual_debugger-0.2.10}/src/tdb/adapters/tcsh/transport.py +0 -0
- {textual_debugger-0.2.8 → textual_debugger-0.2.10}/src/tdb/app_handlers/__init__.py +0 -0
- {textual_debugger-0.2.8 → textual_debugger-0.2.10}/src/tdb/app_handlers/dap_events.py +0 -0
- {textual_debugger-0.2.8 → textual_debugger-0.2.10}/src/tdb/app_helpers.py +0 -0
- {textual_debugger-0.2.8 → textual_debugger-0.2.10}/src/tdb/dap/__init__.py +0 -0
- {textual_debugger-0.2.8 → textual_debugger-0.2.10}/src/tdb/dap/messages.py +0 -0
- {textual_debugger-0.2.8 → textual_debugger-0.2.10}/src/tdb/dap/protocol.py +0 -0
- {textual_debugger-0.2.8 → textual_debugger-0.2.10}/src/tdb/dap/reverse.py +0 -0
- {textual_debugger-0.2.8 → textual_debugger-0.2.10}/src/tdb/dap/types.py +0 -0
- {textual_debugger-0.2.8/src/tdb/server → textual_debugger-0.2.10/src/tdb/go_concurrency}/__init__.py +0 -0
- {textual_debugger-0.2.8 → textual_debugger-0.2.10}/src/tdb/inspection.py +0 -0
- {textual_debugger-0.2.8 → textual_debugger-0.2.10}/src/tdb/inspection_full.py +0 -0
- {textual_debugger-0.2.8 → textual_debugger-0.2.10}/src/tdb/keybindings/__init__.py +0 -0
- {textual_debugger-0.2.8 → textual_debugger-0.2.10}/src/tdb/languages/__init__.py +0 -0
- {textual_debugger-0.2.8 → textual_debugger-0.2.10}/src/tdb/languages/bash.py +0 -0
- {textual_debugger-0.2.8 → textual_debugger-0.2.10}/src/tdb/languages/cpp.py +0 -0
- {textual_debugger-0.2.8 → textual_debugger-0.2.10}/src/tdb/languages/perl.py +0 -0
- {textual_debugger-0.2.8 → textual_debugger-0.2.10}/src/tdb/languages/python.py +0 -0
- {textual_debugger-0.2.8 → textual_debugger-0.2.10}/src/tdb/languages/ruby.py +0 -0
- {textual_debugger-0.2.8 → textual_debugger-0.2.10}/src/tdb/languages/rust.py +0 -0
- {textual_debugger-0.2.8 → textual_debugger-0.2.10}/src/tdb/languages/tcsh.py +0 -0
- {textual_debugger-0.2.8 → textual_debugger-0.2.10}/src/tdb/mcp/__init__.py +0 -0
- {textual_debugger-0.2.8 → textual_debugger-0.2.10}/src/tdb/mcp/__main__.py +0 -0
- {textual_debugger-0.2.8 → textual_debugger-0.2.10}/src/tdb/mcp/session.py +0 -0
- {textual_debugger-0.2.8 → textual_debugger-0.2.10}/src/tdb/persist.py +0 -0
- {textual_debugger-0.2.8 → textual_debugger-0.2.10}/src/tdb/post_mortem.py +0 -0
- {textual_debugger-0.2.8 → textual_debugger-0.2.10}/src/tdb/processes_cache.py +0 -0
- {textual_debugger-0.2.8 → textual_debugger-0.2.10}/src/tdb/replay.py +0 -0
- {textual_debugger-0.2.8 → textual_debugger-0.2.10}/src/tdb/rust_concurrency/__init__.py +0 -0
- {textual_debugger-0.2.8 → textual_debugger-0.2.10}/src/tdb/rust_concurrency/analyzer.py +0 -0
- {textual_debugger-0.2.8 → textual_debugger-0.2.10}/src/tdb/rust_concurrency/classifier.py +0 -0
- {textual_debugger-0.2.8 → textual_debugger-0.2.10}/src/tdb/rust_concurrency/collector.py +0 -0
- {textual_debugger-0.2.8 → textual_debugger-0.2.10}/src/tdb/rust_concurrency/models.py +0 -0
- {textual_debugger-0.2.8 → textual_debugger-0.2.10}/src/tdb/rust_concurrency/probes/__init__.py +0 -0
- {textual_debugger-0.2.8 → textual_debugger-0.2.10}/src/tdb/rust_concurrency/probes/base.py +0 -0
- {textual_debugger-0.2.8 → textual_debugger-0.2.10}/src/tdb/rust_concurrency/probes/gdb.py +0 -0
- {textual_debugger-0.2.8 → textual_debugger-0.2.10}/src/tdb/rust_concurrency/probes/gdb_script.py +0 -0
- {textual_debugger-0.2.8 → textual_debugger-0.2.10}/src/tdb/rust_concurrency/probes/lldb.py +0 -0
- {textual_debugger-0.2.8 → textual_debugger-0.2.10}/src/tdb/rust_concurrency/probes/lldb_script.py +0 -0
- {textual_debugger-0.2.8/src/tdb/session → textual_debugger-0.2.10/src/tdb/server}/__init__.py +0 -0
- {textual_debugger-0.2.8 → textual_debugger-0.2.10}/src/tdb/server/app.py +0 -0
- {textual_debugger-0.2.8 → textual_debugger-0.2.10}/src/tdb/server/event_handler.py +0 -0
- {textual_debugger-0.2.8 → textual_debugger-0.2.10}/src/tdb/server/rpc_types.py +0 -0
- {textual_debugger-0.2.8/src/tdb/widgets → textual_debugger-0.2.10/src/tdb/session}/__init__.py +0 -0
- {textual_debugger-0.2.8 → textual_debugger-0.2.10}/src/tdb/session/child_processes.py +0 -0
- {textual_debugger-0.2.8 → textual_debugger-0.2.10}/src/tdb/session/errors.py +0 -0
- {textual_debugger-0.2.8 → textual_debugger-0.2.10}/src/tdb/session/event_bus.py +0 -0
- {textual_debugger-0.2.8 → textual_debugger-0.2.10}/src/tdb/session/messages.py +0 -0
- {textual_debugger-0.2.8 → textual_debugger-0.2.10}/src/tdb/session/post_mortem_loader.py +0 -0
- {textual_debugger-0.2.8 → textual_debugger-0.2.10}/src/tdb/session/recorder.py +0 -0
- {textual_debugger-0.2.8 → textual_debugger-0.2.10}/src/tdb/session/statement_stepper.py +0 -0
- {textual_debugger-0.2.8 → textual_debugger-0.2.10}/src/tdb/session/terminal.py +0 -0
- {textual_debugger-0.2.8 → textual_debugger-0.2.10}/src/tdb/session/textual_handler.py +0 -0
- {textual_debugger-0.2.8 → textual_debugger-0.2.10}/src/tdb/source_analysis.py +0 -0
- {textual_debugger-0.2.8 → textual_debugger-0.2.10}/src/tdb/widgets/_inspection_modal.py +0 -0
- {textual_debugger-0.2.8 → textual_debugger-0.2.10}/src/tdb/widgets/async_tasks_modal.py +0 -0
- {textual_debugger-0.2.8 → textual_debugger-0.2.10}/src/tdb/widgets/breakpoint_view.py +0 -0
- {textual_debugger-0.2.8 → textual_debugger-0.2.10}/src/tdb/widgets/code_view.py +0 -0
- {textual_debugger-0.2.8 → textual_debugger-0.2.10}/src/tdb/widgets/console_view.py +0 -0
- {textual_debugger-0.2.8 → textual_debugger-0.2.10}/src/tdb/widgets/evaluate_console.py +0 -0
- {textual_debugger-0.2.8 → textual_debugger-0.2.10}/src/tdb/widgets/full_contents_modal.py +0 -0
- {textual_debugger-0.2.8 → textual_debugger-0.2.10}/src/tdb/widgets/menu_bar.py +0 -0
- {textual_debugger-0.2.8 → textual_debugger-0.2.10}/src/tdb/widgets/modals.py +0 -0
- {textual_debugger-0.2.8 → textual_debugger-0.2.10}/src/tdb/widgets/processes_modal.py +0 -0
- {textual_debugger-0.2.8 → textual_debugger-0.2.10}/src/tdb/widgets/rust_concurrency_modal.py +0 -0
- {textual_debugger-0.2.8 → textual_debugger-0.2.10}/src/tdb/widgets/stack_view.py +0 -0
- {textual_debugger-0.2.8 → textual_debugger-0.2.10}/src/tdb/widgets/status_bar.py +0 -0
- {textual_debugger-0.2.8 → textual_debugger-0.2.10}/src/tdb/widgets/threads_modal.py +0 -0
- {textual_debugger-0.2.8 → textual_debugger-0.2.10}/src/tdb/widgets/variable_view.py +0 -0
- {textual_debugger-0.2.8 → textual_debugger-0.2.10}/src/textual_debugger.egg-info/dependency_links.txt +0 -0
- {textual_debugger-0.2.8 → textual_debugger-0.2.10}/src/textual_debugger.egg-info/entry_points.txt +0 -0
- {textual_debugger-0.2.8 → textual_debugger-0.2.10}/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.10
|
|
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:
|
|
@@ -49,7 +49,7 @@ Requires-Python: >=3.11
|
|
|
49
49
|
Description-Content-Type: text/markdown
|
|
50
50
|
License-File: LICENSE
|
|
51
51
|
Requires-Dist: textual>=8.0.0
|
|
52
|
-
Requires-Dist: debugpy>=1.8.
|
|
52
|
+
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
|
|
@@ -79,6 +79,8 @@ with a Debug Adapter Protocol (DAP) implementation. In addition to Python,
|
|
|
79
79
|
- Tcsh (via source instrumentation of a stock `tcsh`)
|
|
80
80
|
- Ruby (via the [debug gem](https://github.com/ruby/debug)'s `rdbg`; debug ≥ 1.9)
|
|
81
81
|
- OCaml (native via `lldb-dap`/`gdb`, bytecode via [ocamlearlybird](https://github.com/hackwaly/ocamlearlybird))
|
|
82
|
+
- Go (via [Delve](https://github.com/go-delve/delve)'s `dlv dap`)
|
|
83
|
+
- PowerShell 7 (via [PowerShell Editor Services](https://github.com/PowerShell/PowerShellEditorServices); Linux/macOS, Windows experimental)
|
|
82
84
|
|
|
83
85
|
`tdb` is built with [textual](https://github.com/Textualize/textual) and speaks
|
|
84
86
|
DAP to a pluggable debug adapter.
|
|
@@ -99,8 +101,9 @@ MIT License. Copyright 2026 by Al Danial.
|
|
|
99
101
|
the richest feature set), C/C++ (via `gdb -i dap` or `lldb-dap`), Rust (via `gdb` or
|
|
100
102
|
`lldb-dap`), Perl (via `perl -d`),
|
|
101
103
|
Bash (via bash's own `DEBUG` trap), Tcsh (via source instrumentation of a
|
|
102
|
-
stock `tcsh`), Ruby (via the debug gem's `rdbg`),
|
|
103
|
-
`lldb-dap`/`gdb`, bytecode via ocamlearlybird)
|
|
104
|
+
stock `tcsh`), Ruby (via the debug gem's `rdbg`), OCaml (native via
|
|
105
|
+
`lldb-dap`/`gdb`, bytecode via ocamlearlybird), Go (via Delve's `dlv
|
|
106
|
+
dap`), and PowerShell 7 (via PowerShell Editor Services). Most languages are
|
|
104
107
|
auto-detected from the target; Rust intentionally requires `--lang rust`
|
|
105
108
|
(ref. [Multi-Language Debugging](#multi-language-debugging)).
|
|
106
109
|
|
|
@@ -110,7 +113,7 @@ It specifically supports modules
|
|
|
110
113
|
- `threading` (with a thread inspector)
|
|
111
114
|
- `multiprocessing` / `concurrent.futures` (with automatic child process attachment and a process inspector)
|
|
112
115
|
|
|
113
|
-
- supports remote attachment to Python, Perl, Ruby, Rust,
|
|
116
|
+
- supports remote attachment to Python, Perl, Ruby, Rust, C/C++, and Go programs
|
|
114
117
|
|
|
115
118
|
- includes a JSON-RPC server mode, an MCP mode, and a `SKILL.md` file that enable
|
|
116
119
|
programmatic debug control, making it suitable for
|
|
@@ -212,6 +215,10 @@ tdb -k 20 -k 35 -k module.py:14 my_program.py arg1 arg2
|
|
|
212
215
|
# sessions (-t is -k minus the persistence)
|
|
213
216
|
tdb -t 20 my_program.py
|
|
214
217
|
|
|
218
|
+
# no TUI: run at (almost) full speed, printing nr each time line 25 is
|
|
219
|
+
# reached, then continuing (-e may be repeated; see "Eval Mode" below)
|
|
220
|
+
tdb --eval my_program.py:25 "print(f'{nr=}')" my_program.py
|
|
221
|
+
|
|
215
222
|
# use a specific virtualenv
|
|
216
223
|
tdb --python /path/to/venv/bin/python my_program.py
|
|
217
224
|
|
|
@@ -238,6 +245,11 @@ tdb -r remotehost:5678 -k my_program.py:42
|
|
|
238
245
|
# than code on the remote host
|
|
239
246
|
tdb -r remotehost:5678 --local-root /my/code/dir --remote-root /app -k my_program.py:42
|
|
240
247
|
|
|
248
|
+
# attach to a program that pauses itself (debugpy.breakpoint() right after
|
|
249
|
+
# debugpy.wait_for_client()); without this flag tdb pauses the program on
|
|
250
|
+
# attach, which can leave it suspended after tdb quits
|
|
251
|
+
tdb -r remotehost:5678 --no-pause-on-attach
|
|
252
|
+
|
|
241
253
|
# separate tdb arguments from debuggee arguments with `--`
|
|
242
254
|
tdb --python /path/to/venv/bin/python -- my_program.py -k 17 --max 23.3
|
|
243
255
|
```
|
|
@@ -250,7 +262,7 @@ python -m tdb my_program.py
|
|
|
250
262
|
|
|
251
263
|
## Multi-Language Debugging
|
|
252
264
|
|
|
253
|
-
`tdb` debugs any language that has a Debug Adapter Protocol backend.
|
|
265
|
+
`tdb` debugs any language that has a Debug Adapter Protocol backend. Ten
|
|
254
266
|
languages are supported out of the box:
|
|
255
267
|
|
|
256
268
|
| Language | Adapter(s) | Dependencies | Feature level |
|
|
@@ -262,33 +274,42 @@ languages are supported out of the box:
|
|
|
262
274
|
| Bash | bash-tdb (bundled) | bash ≥ 4.4 on PATH | core debugging (no remote attach) |
|
|
263
275
|
| Tcsh | tcsh-tdb (bundled) | tcsh on PATH | core debugging (no remote attach, no conditional breakpoints, no pause) |
|
|
264
276
|
| Ruby | `rdbg` (the [debug gem](https://github.com/ruby/debug)) | `rdbg` ≥ 1.9 on PATH | core debugging + remote attach |
|
|
265
|
-
| OCaml (native executable) | `lldb-dap` (default), `gdb` (alternate) |
|
|
266
|
-
| OCaml (bytecode executable) | `ocamlearlybird` (default) |
|
|
277
|
+
| OCaml (native executable) | `lldb-dap` (default), `gdb` (alternate) | `lldb-dap` ships with LLVM ≥ 17; `gdb -i dap` requires GDB ≥ 14 | core debugging + domains-as-threads; Variables view shows no OCaml locals (upstream DWARF limitation); evaluate console is lldb/C-level, not OCaml |
|
|
278
|
+
| OCaml (bytecode executable) | `ocamlearlybird` (default) | `opam install earlybird` | core debugging + rich OCaml locals; no pause/`--run`, no evaluate responses, no fatal-error modal (ocamlearlybird 1.3.6 limitations); single-domain only |
|
|
279
|
+
| Go | `dlv` (the [Delve](https://github.com/go-delve/delve) DAP server) | Delve ≥ 1.21 on PATH (`go install github.com/go-delve/delve/cmd/dlv@latest`) | core debugging + goroutine inspection (wait graph, findings) + remote attach (no `--terminal`) |
|
|
280
|
+
| PowerShell 7 | `pses` (PowerShell Editor Services, driven by tdb's bundled proxy) | `pwsh` ≥ 7.2 on PATH + the PSES module (see [PowerShell](#powershell)) | core debugging (breakpoints incl. conditional/hit-count/log, stepping, stack, variables, evaluate console) + `--run`; no `--terminal`, no remote attach; Windows untested |
|
|
267
281
|
|
|
268
282
|
### Language detection and selection
|
|
269
283
|
|
|
270
284
|
The language is auto-detected from the debug target:
|
|
271
285
|
|
|
272
|
-
1.
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
286
|
+
1. A directory → Go, if it contains any `*.go` file (a Go package
|
|
287
|
+
directory, e.g. `tdb ./pkg`); otherwise an error naming `--lang`.
|
|
288
|
+
2. File extension: `.py` → Python; `.go` → Go; `.pl` / `.pm` / `.t` → Perl;
|
|
289
|
+
`.sh` / `.bash` → Bash; `.csh` / `.tcsh` → Tcsh; `.rb` → Ruby; `.ps1` /
|
|
290
|
+
`.psm1` → PowerShell. (`.ml` / `.mli` do *not* auto-select OCaml, see
|
|
291
|
+
point 6.)
|
|
292
|
+
3. Native executables (ELF, Mach-O, PE magic bytes) → C/C++, unless
|
|
293
|
+
byte-checking finds an OCaml marker (a native binary's
|
|
277
294
|
`caml_program`/`caml_startup` runtime symbols, a bytecode file's
|
|
278
|
-
trailing `Caml1999` marker, or a `#!...ocamlrun` shebang
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
295
|
+
trailing `Caml1999` marker, or a `#!...ocamlrun` shebang) → OCaml
|
|
296
|
+
(native or bytecode respectively), or a Go buildinfo blob (the marker
|
|
297
|
+
`go version` itself locates, scanned in the first 16MB of the file) →
|
|
298
|
+
Go. A stripped native OCaml binary, or a Go binary whose buildinfo
|
|
299
|
+
blob sits beyond the 16MB scan window, that byte-checking can't
|
|
300
|
+
identify falls back to C/C++; force it with `--lang ocaml` or `--lang
|
|
301
|
+
go` respectively. Rust is never inferred from an executable; select it
|
|
302
|
+
explicitly with `--lang rust`.
|
|
303
|
+
4. A `#!...python`, `#!...perl`, `#!...bash`, `#!...csh`/`#!...tcsh`,
|
|
304
|
+
`#!...ruby`, or `#!...pwsh` shebang → Python / Perl / Bash / Tcsh / Ruby /
|
|
305
|
+
PowerShell respectively.
|
|
306
|
+
5. C/C++/Rust *source* files (`.c`, `.cpp`, `.rs`, …) produce an error with a
|
|
286
307
|
hint: compile with debug info (`g++ -g -O0`) and debug the binary.
|
|
287
|
-
|
|
308
|
+
6. `.ml` / `.mli` (OCaml source) produce an error too: build the project
|
|
288
309
|
first (dune's dev profile keeps debug info) and pass the **built
|
|
289
310
|
executable** to `tdb` (`tdb ./_build/default/bin/main.exe`), never the
|
|
290
311
|
`.ml` file.
|
|
291
|
-
|
|
312
|
+
7. Anything else produces an error naming the `--lang` override.
|
|
292
313
|
|
|
293
314
|
`--lang` forces the language; `--adapter` picks a non-default adapter within
|
|
294
315
|
it (`tdb --lang cpp --adapter lldb-dap ./myprog`). Rust always requires the
|
|
@@ -320,19 +341,25 @@ and the JSON-RPC / MCP programmatic modes.
|
|
|
320
341
|
|
|
321
342
|
Python-specific features are hidden or return "not supported for this
|
|
322
343
|
language" message when debugging other languages: statement-granularity
|
|
323
|
-
stepping (non-Python languages
|
|
324
|
-
|
|
344
|
+
stepping (non-Python languages step at their debugger's native granularity
|
|
345
|
+
— per line, except PowerShell, whose debugger stops per statement, see
|
|
346
|
+
[PowerShell](#powershell)), the async task / process inspectors and wait
|
|
347
|
+
graph, the evaluate console's trailing-`?` help,
|
|
325
348
|
`--python`/`--pv`, `--no-subprocess`, automatic child-process attachment, and
|
|
326
349
|
the post-mortem / `tdb.breakpoint()` hooks (those hooks live inside Python
|
|
327
350
|
programs by nature). Remote attach (`-r`) also works for Perl (see
|
|
328
351
|
[Perl](#perl), `Devel::TdbRemote` in place of `debugpy.listen()`), Ruby
|
|
329
|
-
(see [Ruby](#ruby), `rdbg --open` in place of `debugpy.listen()`),
|
|
352
|
+
(see [Ruby](#ruby), `rdbg --open` in place of `debugpy.listen()`), Go (see
|
|
353
|
+
[Go](#go), `dlv dap --listen` in place of `debugpy.listen()`), and for
|
|
330
354
|
Rust and C/C++ native binaries (against a gdbserver/lldb-server stub, with
|
|
331
355
|
a local symbol-bearing executable; see [Rust](#rust) — the same flags work
|
|
332
|
-
for a C/C++ target without `--lang`), but not for Bash, Tcsh,
|
|
356
|
+
for a C/C++ target without `--lang`), but not for Bash, Tcsh, OCaml, or
|
|
357
|
+
PowerShell. `--terminal` works for every launch-mode
|
|
333
358
|
language — Python, Perl, Bash, Tcsh, Ruby, and C/C++, OCaml native, or Rust
|
|
334
359
|
sessions via `--adapter lldb-dap` — see
|
|
335
|
-
[External Terminal Support](#external-terminal-support).
|
|
360
|
+
[External Terminal Support](#external-terminal-support). Go and PowerShell do
|
|
361
|
+
not support `--terminal` yet (`dlv dap` and PSES have no terminal-routing
|
|
362
|
+
mode).
|
|
336
363
|
|
|
337
364
|
**Bash limitations (v1):** the bash adapter uses bash's own `DEBUG` trap and
|
|
338
365
|
has a smaller feature set than Python:
|
|
@@ -397,7 +424,30 @@ picture:
|
|
|
397
424
|
reaches `tdb`). Run the program outside the debugger to see the
|
|
398
425
|
backtrace instead.
|
|
399
426
|
- No Windows support, no remote attach, and a stripped native binary that
|
|
400
|
-
byte-
|
|
427
|
+
byte-checking can't identify needs `--lang ocaml`.
|
|
428
|
+
|
|
429
|
+
**Go limitations (v1):**
|
|
430
|
+
|
|
431
|
+
- `--terminal` is not supported (`dlv dap` has no terminal-routing mode).
|
|
432
|
+
- The Goroutines workspace's wait graph shows channel-send/-receive,
|
|
433
|
+
mutex, and `WaitGroup` edges; a goroutine parked in a `select` is
|
|
434
|
+
classified but contributes no wait edge (Delve can't tell which of the
|
|
435
|
+
`select`'s cases it's waiting on).
|
|
436
|
+
- No mutex-holder identification: Go's `sync.Mutex` doesn't record an
|
|
437
|
+
owner at the runtime level, so unlike Python's Lock/Semaphore inspector
|
|
438
|
+
the wait graph can name what a goroutine is blocked on but never who
|
|
439
|
+
holds it.
|
|
440
|
+
- Goroutines spawned by `exec.Command` (child OS processes) are not
|
|
441
|
+
automatically attached or debugged, unlike Python's automatic
|
|
442
|
+
multiprocessing child attach.
|
|
443
|
+
- Detection of a Go binary via buildinfo check scans only the first
|
|
444
|
+
16MB of the file; a huge binary whose buildinfo blob sits beyond that
|
|
445
|
+
falls back to C/C++ — force it with `--lang go`.
|
|
446
|
+
- `-a`/`--attach`'s language auto-detection (reading the target pid's
|
|
447
|
+
buildinfo from `/proc/PID/exe`) is Linux-only; on macOS/Windows pass
|
|
448
|
+
`--lang go` alongside `-a`.
|
|
449
|
+
|
|
450
|
+
See [Go](#go) below for launch details.
|
|
401
451
|
|
|
402
452
|
### C/C++ tips
|
|
403
453
|
|
|
@@ -703,18 +753,35 @@ does). Always pass the **built executable** to `tdb`, never the `.ml`
|
|
|
703
753
|
source, as in `tdb ./_build/default/bin/main.exe`, not `tdb main.ml` (which
|
|
704
754
|
errors with this exact guidance).
|
|
705
755
|
|
|
756
|
+
Earlybird additionally as a fragile relative path matching so for
|
|
757
|
+
best results provide a fully quallified path to the source files.
|
|
758
|
+
|
|
759
|
+
```
|
|
760
|
+
ocamlc -g -o my_program.byte "$PWD/my_program.ml"
|
|
761
|
+
```
|
|
762
|
+
|
|
763
|
+
Then, to ensure transition from bytecode to OCaml source in the
|
|
764
|
+
Code view, provide an explicit temporary breakpoint (`-t`)
|
|
765
|
+
at the first line of execution:
|
|
766
|
+
|
|
767
|
+
```
|
|
768
|
+
tdb --lang ocaml --adapter ocamlearlybird -t "$PWD/my_program.ml:2" ./my_program.byte
|
|
769
|
+
```
|
|
770
|
+
|
|
706
771
|
**OCaml version:** tdb requires **OCaml ≥ 4.12**. Older runtimes print
|
|
707
772
|
`Printexc` backtraces without function names, which the fatal-error
|
|
708
773
|
modal's parser does not understand (frames would be dropped and the
|
|
709
774
|
modal would wrongly suggest recompiling with `-g`).
|
|
710
775
|
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
776
|
+
With native GDB, the default entry stop is translated to the first
|
|
777
|
+
executable line in project OCaml source; the generated C/ELF startup code is
|
|
778
|
+
not shown.
|
|
779
|
+
Unfortunately OCaml's native debug information does not always identify
|
|
780
|
+
tihs line correctly.
|
|
781
|
+
`--no-stop-on-entry` and explicit CLI breakpoints retain their
|
|
782
|
+
usual behavior.
|
|
716
783
|
|
|
717
|
-
A stripped native binary that byte-
|
|
784
|
+
A stripped native binary that byte-checking can't identify as OCaml falls
|
|
718
785
|
back to C/C++; force it with `--lang ocaml`. Override the adapter or point
|
|
719
786
|
at a non-`PATH` install in `config.json` (see
|
|
720
787
|
[Configuration](#configuration)):
|
|
@@ -774,6 +841,139 @@ sessions can't `pause` a running program (so `--run` is unavailable for
|
|
|
774
841
|
bytecode. Native sessions support `--run` normally); `Unix.fork` and Eio
|
|
775
842
|
fibers are out of scope (only OCaml 5 domains are presented as threads).
|
|
776
843
|
|
|
844
|
+
### Go
|
|
845
|
+
|
|
846
|
+
`tdb` debugs Go through [Delve](https://github.com/go-delve/delve)'s own
|
|
847
|
+
DAP server, `dlv dap` (Delve ≥ 1.21). Install it with:
|
|
848
|
+
|
|
849
|
+
```bash
|
|
850
|
+
go install github.com/go-delve/delve/cmd/dlv@latest
|
|
851
|
+
```
|
|
852
|
+
|
|
853
|
+
`dlv` must be on `PATH`, or point tdb at it with
|
|
854
|
+
`{"adapters": {"dlv": "/path/to/dlv"}}` in `config.json`.
|
|
855
|
+
|
|
856
|
+
**Launch modes** — `tdb` picks the right Delve mode automatically:
|
|
857
|
+
|
|
858
|
+
```bash
|
|
859
|
+
tdb main.go # source file: `go run`-style debug mode
|
|
860
|
+
tdb ./pkg # package directory: `go run`-style debug mode
|
|
861
|
+
tdb ./binary # pre-built Go binary (buildinfo-detected): exec mode
|
|
862
|
+
tdb --test ./pkg # Go test package: Delve test mode
|
|
863
|
+
tdb -a PID # attach to a running local Go process by pid
|
|
864
|
+
tdb -r host:port --lang go # attach to a `dlv dap --listen` already running remotely
|
|
865
|
+
```
|
|
866
|
+
|
|
867
|
+
`tdb --test ./pkg` debugs the package's tests under Delve's `test` mode;
|
|
868
|
+
pass test-binary flags after `--`, e.g. `tdb --test ./pkg -- -run TestFoo`.
|
|
869
|
+
`-a`/`--attach` currently supports Go only; on Linux, and only on Linux,
|
|
870
|
+
`tdb` can identify the target as Go from `/proc/PID/exe`'s buildinfo
|
|
871
|
+
without `--lang` (elsewhere pass `--lang go` alongside `-a`). Attaching
|
|
872
|
+
stops the process immediately so you get control right away.
|
|
873
|
+
|
|
874
|
+
**Remote attach:** start Delve's own DAP server against your program
|
|
875
|
+
first —
|
|
876
|
+
|
|
877
|
+
```bash
|
|
878
|
+
dlv dap --listen=host:port ./binary
|
|
879
|
+
```
|
|
880
|
+
|
|
881
|
+
— then connect from `tdb`:
|
|
882
|
+
|
|
883
|
+
```bash
|
|
884
|
+
tdb -r host:port --lang go
|
|
885
|
+
```
|
|
886
|
+
|
|
887
|
+
Do not expose the port to an untrusted network; prefer an SSH tunnel.
|
|
888
|
+
|
|
889
|
+
**Goroutine inspection:** in a Go session the Threads action (`Alt+T`, or
|
|
890
|
+
the **Goroutines (N)** menu label) opens the Goroutines workspace while
|
|
891
|
+
the debuggee is stopped — a fresh, bounded snapshot of goroutines, wait
|
|
892
|
+
edges, and findings, the same shape as the Rust Concurrency workspace.
|
|
893
|
+
Goroutines parked entirely in Go-runtime internals (GC workers,
|
|
894
|
+
finalizers, netpoll) are hidden by default; press `a` to reveal them
|
|
895
|
+
alongside the rest. The **Wait Graph** tab groups goroutines by the
|
|
896
|
+
channel, mutex, or `WaitGroup` they're blocked on; the **Findings** tab
|
|
897
|
+
surfaces stuck channels, mutex convoys, and likely leaks with a
|
|
898
|
+
confidence level (`confirmed` vs `probable`) — Go mutexes never record an
|
|
899
|
+
owner, so, unlike Python's Lock/Semaphore inspector, findings can name
|
|
900
|
+
what's blocked but not who holds it. The snapshot collects up to 150
|
|
901
|
+
goroutines; a busier program reports the header
|
|
902
|
+
`Goroutines (150) — N more not collected` rather than silently truncating.
|
|
903
|
+
Refresh (`r`) after the next stop to collect a new snapshot.
|
|
904
|
+
|
|
905
|
+
**Limitations (v1):** `--terminal` is not supported (`dlv dap` has no
|
|
906
|
+
terminal-routing mode); a goroutine parked in a `select` is classified but
|
|
907
|
+
contributes no wait edge (Delve can't tell which case it's waiting on);
|
|
908
|
+
no mutex-holder identification (impossible for Go's runtime); goroutines
|
|
909
|
+
spawned indirectly via `exec.Command` child OS processes are not
|
|
910
|
+
automatically attached; buildinfo-based binary detection scans only the
|
|
911
|
+
first 16MB of the file (`--lang go` overrides for anything larger); `-a`'s
|
|
912
|
+
`/proc`-based language auto-detection is Linux-only (pass `--lang go`
|
|
913
|
+
alongside `-a` on macOS/Windows).
|
|
914
|
+
|
|
915
|
+
### PowerShell
|
|
916
|
+
|
|
917
|
+
tdb debugs PowerShell 7 scripts through [PowerShell Editor Services](https://github.com/PowerShell/PowerShellEditorServices)
|
|
918
|
+
(PSES), the Debug Adapter Protocol server behind the VS Code PowerShell
|
|
919
|
+
extension. You need `pwsh` (>= 7.2; https://aka.ms/powershell) on PATH
|
|
920
|
+
and the PSES module. tdb looks for the module in this order:
|
|
921
|
+
|
|
922
|
+
1. `{"adapters": {"pses": "/path/to/PowerShellEditorServices"}}` in `config.json`
|
|
923
|
+
2. the `TDB_PSES_PATH` environment variable
|
|
924
|
+
3. the copy bundled with an installed VS Code PowerShell extension
|
|
925
|
+
(`~/.vscode/extensions/ms-vscode.powershell-*/modules/PowerShellEditorServices`)
|
|
926
|
+
|
|
927
|
+
Without VS Code, download the release once:
|
|
928
|
+
|
|
929
|
+
```bash
|
|
930
|
+
mkdir -p ~/.local/share/tdb/pses && cd ~/.local/share/tdb/pses
|
|
931
|
+
curl -sLO https://github.com/PowerShell/PowerShellEditorServices/releases/download/v4.7.0/PowerShellEditorServices.zip
|
|
932
|
+
unzip -q PowerShellEditorServices.zip
|
|
933
|
+
export TDB_PSES_PATH=~/.local/share/tdb/pses/PowerShellEditorServices
|
|
934
|
+
```
|
|
935
|
+
|
|
936
|
+
A `pwsh` that isn't on PATH can be named with `{"adapters": {"pwsh": "/path/to/pwsh"}}`.
|
|
937
|
+
|
|
938
|
+
```bash
|
|
939
|
+
tdb script.ps1 # launch, stop at the first statement
|
|
940
|
+
tdb --run script.ps1 # run immediately, debug on demand (pause works)
|
|
941
|
+
```
|
|
942
|
+
|
|
943
|
+
Notes:
|
|
944
|
+
|
|
945
|
+
- Entry stop lands on the first statement of your script (comments and
|
|
946
|
+
function definitions are skipped): PSES has no native `stopOnEntry` for
|
|
947
|
+
this launch shape, so tdb sets a synthetic breakpoint on the bundled
|
|
948
|
+
launcher, steps in, and clears it — no line-1 breakpoint appears in the
|
|
949
|
+
Breakpoint view.
|
|
950
|
+
- The script runs inside that small bundled launcher (`tdb_launch.ps1`) so
|
|
951
|
+
tdb can report the script's exit code. In the Stack view, top to bottom:
|
|
952
|
+
PSES's `<Breakpoint>` marker frame (the frame to inspect — it tracks the
|
|
953
|
+
accurate current position), your script's own frames, the launcher's
|
|
954
|
+
`<ScriptBlock>`, and a source-less `Interactive Session` frame at the
|
|
955
|
+
bottom.
|
|
956
|
+
- Stepping is statement-granular, as in VS Code: a line containing a
|
|
957
|
+
`$( ... )` subexpression takes two `next` presses to clear, and `stepIn`
|
|
958
|
+
first lands on the called function's declaration line before its body.
|
|
959
|
+
- An uncaught terminating error ends the script with exit code 1 and opens
|
|
960
|
+
the fatal-error modal from pwsh's concise error text. Non-terminating
|
|
961
|
+
errors (`Write-Error`, failing cmdlets without `-ErrorAction Stop`) print
|
|
962
|
+
the same concise error block to the Console as stderr and let the script
|
|
963
|
+
continue with exit code 0, as in pwsh itself; there is no break-on-error
|
|
964
|
+
yet. The error block names the launcher's `& $Script` line rather than
|
|
965
|
+
your script's actual line for some error kinds (a known cosmetic
|
|
966
|
+
limitation).
|
|
967
|
+
- The fatal-error modal is gated on a non-zero exit code, since pwsh prints
|
|
968
|
+
the identical block for terminating and non-terminating errors. A script
|
|
969
|
+
that reports a non-terminating error and then `exit 3` can therefore still
|
|
970
|
+
raise the modal, showing the last error block that names a file of yours;
|
|
971
|
+
blocks attributed to tdb's own `tdb_launch.ps1` are skipped, so a bare
|
|
972
|
+
`Write-Error` before the `exit` opens no modal at all.
|
|
973
|
+
- `--terminal` and remote attach are not supported for PowerShell yet.
|
|
974
|
+
- Windows PowerShell 5.1 is not supported (pwsh 7 only). Running tdb *on*
|
|
975
|
+
Windows against pwsh is designed for but not yet verified (experimental).
|
|
976
|
+
|
|
777
977
|
## Layout
|
|
778
978
|
|
|
779
979
|
```
|
|
@@ -900,7 +1100,9 @@ stops on each physical line--useful for inspecting how a complex expression is b
|
|
|
900
1100
|
The choice is saved to `~/.config/tdb/config.json`.
|
|
901
1101
|
|
|
902
1102
|
Statement mode requires a source-language model and is currently Python-only;
|
|
903
|
-
other languages
|
|
1103
|
+
other languages step at their debugger's native granularity — per line,
|
|
1104
|
+
except PowerShell, whose debugger stops per statement, see
|
|
1105
|
+
[PowerShell](#powershell) (the Step Mode menu says so if you try).
|
|
904
1106
|
|
|
905
1107
|
### Breakpoints
|
|
906
1108
|
|
|
@@ -1266,12 +1468,14 @@ sessions via `--adapter lldb-dap`. Neither `gdb -i dap` (the default C/C++
|
|
|
1266
1468
|
adapter, and an alternate for native OCaml) nor `ocamlearlybird` (the
|
|
1267
1469
|
bytecode OCaml adapter) has any terminal integration -- `tdb` rejects
|
|
1268
1470
|
`--terminal` up front for both, with an error pointing at `--adapter
|
|
1269
|
-
lldb-dap` instead.
|
|
1270
|
-
|
|
1271
|
-
|
|
1471
|
+
lldb-dap` instead. Go and PowerShell don't support `--terminal` either
|
|
1472
|
+
(`dlv dap` has no terminal-routing mode; PSES likewise). `--terminal` also
|
|
1473
|
+
only applies when `tdb` launches the program itself; it is rejected for
|
|
1474
|
+
remote-attach (`-r`), since there's no program for `tdb` to spawn a
|
|
1475
|
+
terminal around.
|
|
1272
1476
|
|
|
1273
1477
|
The debuggee runs in a separate window of the specified terminal, including
|
|
1274
|
-
all of its stdin/stdout/stderr
|
|
1478
|
+
all of its stdin/stdout/stderr. Keyboard input, program output, and
|
|
1275
1479
|
anything the program itself draws to the terminal all happen in that
|
|
1276
1480
|
window, not in `tdb`'s Console View. Supported choices:
|
|
1277
1481
|
`xterm`, `konsole`, `gnome-terminal`, `ghostty`, `kitty`, `iterm2`, `warp`,
|
|
@@ -1309,7 +1513,7 @@ tdb --run my_program.py; echo $? # my_program.py's own exit code
|
|
|
1309
1513
|
**Interrupting:** press Ctrl-C in the terminal (any platform), or, on Unix, send
|
|
1310
1514
|
`SIGUSR1` to `tdb`'s pid from another terminal: `kill -USR1 <tdb pid>`. Either one pauses
|
|
1311
1515
|
the debuggee at its currently executing line and opens the TUI with full debugging
|
|
1312
|
-
available
|
|
1516
|
+
available (breakpoints, stepping, variable inspection, the evaluate console). The
|
|
1313
1517
|
debuggee itself never receives the signal (`tdb`'s adapter runs in its own process
|
|
1314
1518
|
group), so its own `SIGINT` handling is undisturbed.
|
|
1315
1519
|
|
|
@@ -1327,10 +1531,11 @@ nonzero `sys.exit()`, which `debugpy` treats as an uncaught `SystemExit` -- `tdb
|
|
|
1327
1531
|
the TUI at the point of failure instead of exiting silently, so you can inspect the
|
|
1328
1532
|
crash. Exit-code passthrough applies only to a clean exit during the headless phase.
|
|
1329
1533
|
|
|
1330
|
-
Supported languages: Python, Perl, Bash, Tcsh, Ruby, C/C++
|
|
1331
|
-
`lldb-dap`), and native OCaml (both `gdb` and `lldb-dap`;
|
|
1332
|
-
|
|
1333
|
-
for those). `--run` is rejected up front for any other
|
|
1534
|
+
Supported languages: Python, Perl, Bash, Tcsh, Ruby, PowerShell 7, C/C++
|
|
1535
|
+
(both `gdb` and `lldb-dap`), and native OCaml (both `gdb` and `lldb-dap`;
|
|
1536
|
+
bytecode/`ocamlearlybird` sessions don't support pause, so `--run` is
|
|
1537
|
+
unavailable for those). `--run` is rejected up front for any other
|
|
1538
|
+
language.
|
|
1334
1539
|
|
|
1335
1540
|
**Limitation:** pausing is cooperative. If the debuggee is blocked inside a single
|
|
1336
1541
|
blocking external call or syscall, the pause can't land until that call returns --
|
|
@@ -1339,6 +1544,48 @@ blocking external call or syscall, the pause can't land until that call returns
|
|
|
1339
1544
|
**Incompatible flags:** `-r`, `-k`/`-t`, `--record`, `--replay`, `--server`,
|
|
1340
1545
|
`--headless`, `--mcp`, `--terminal`.
|
|
1341
1546
|
|
|
1547
|
+
### Eval Mode (`-e`/`--eval`)
|
|
1548
|
+
|
|
1549
|
+
Eval mode automates a common debugging loop--set a breakpoint, run to it,
|
|
1550
|
+
evaluate an expression in the Evaluate console, continue--without
|
|
1551
|
+
opening the TUI. `-e` takes two arguments, a location and an expression:
|
|
1552
|
+
|
|
1553
|
+
```bash
|
|
1554
|
+
tdb --eval examples/digits_of_pi.py:25 "print(f'{nr=}')" examples/digits_of_pi.py
|
|
1555
|
+
```
|
|
1556
|
+
|
|
1557
|
+
sets a breakpoint at line 25, runs the program, and each time that line is
|
|
1558
|
+
reached evaluates `print(f'{nr=}')` in the stopped frame, then continues.
|
|
1559
|
+
Program output and evaluation output both stream to the terminal; when the
|
|
1560
|
+
program exits, `tdb` exits with the same code (and with `1` if the session
|
|
1561
|
+
ends without one--as with a crash or killed adapter--so a scripted `tdb -e ...
|
|
1562
|
+
&& next` can trust the exit status). `Ctrl-C` stops the program and exits
|
|
1563
|
+
`130`. Under `multiprocessing`, an eval point placed in child code is
|
|
1564
|
+
evaluated in each child process that reaches it.
|
|
1565
|
+
|
|
1566
|
+
- The location is `FILE:LINE`, or a bare `LINE` of the program being debugged,
|
|
1567
|
+
and is snapped to the start of a logical statement just like `-k`.
|
|
1568
|
+
- `-e` may be repeated to plant several eval points in one run.
|
|
1569
|
+
- The expression is evaluated through the debug adapter (DAP `evaluate`,
|
|
1570
|
+
context `repl`), just like the Evaluate console: side effects are real
|
|
1571
|
+
and persist in the running program, for example
|
|
1572
|
+
`-e my_program.py:25 "limit = 10"` changes `limit` from line 25 onward.
|
|
1573
|
+
- A bare expression's result is printed to stdout; statement-style
|
|
1574
|
+
expressions (`print(...)`, assignments) print nothing beyond their own
|
|
1575
|
+
output. An expression error is reported on stderr and the run continues --
|
|
1576
|
+
a typo isn't fatal, matching the Evaluate console.
|
|
1577
|
+
- Saved breakpoints are ignored, and any other stop (e.g. an
|
|
1578
|
+
uncaught-exception stop) is continued untouched, so the program runs to
|
|
1579
|
+
completion unattended.
|
|
1580
|
+
- For non-Python debuggees the expression must be in the debug adapter's
|
|
1581
|
+
own syntax, for example gdb's `print x` / `set var x=3` for C/C++, and not
|
|
1582
|
+
necessarily the debuggee's language. The adapter may bind the breakpoint
|
|
1583
|
+
to the next executable line (gdb moves one off a declaration or brace);
|
|
1584
|
+
the eval point matches that bound line, so the expression still runs.
|
|
1585
|
+
|
|
1586
|
+
**Incompatible flags:** `--run`, `-r`, `-a`, `-k`/`-t`, `--record`,
|
|
1587
|
+
`--replay`, `--server`, `--headless`, `--mcp`, `--terminal`.
|
|
1588
|
+
|
|
1342
1589
|
### Keybinding Schemes
|
|
1343
1590
|
|
|
1344
1591
|
```bash
|
|
@@ -1634,6 +1881,10 @@ found; it's Python code, not an external executable), so
|
|
|
1634
1881
|
`{"adapters": {"perl": "/path/to/perl"}}`. Use this when the `perl` on
|
|
1635
1882
|
`PATH` is too old (< 5.18) or you need a specific `perlbrew`/`plenv` version.
|
|
1636
1883
|
|
|
1884
|
+
**PowerShell** follows the same pattern with two keys: `adapters.pwsh` names
|
|
1885
|
+
the interpreter and `adapters.pses` names the PowerShell Editor Services
|
|
1886
|
+
module directory (see [PowerShell](#powershell)).
|
|
1887
|
+
|
|
1637
1888
|
Breakpoints are saved on exit and restored when debugging a program in the same
|
|
1638
1889
|
directory. Each project's breakpoints are independent. Breakpoints set with
|
|
1639
1890
|
`-t`/`--to-line` are the exception: they behave like `-k` breakpoints during
|