textual-debugger 0.2.2__tar.gz → 0.2.6__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.2 → textual_debugger-0.2.6}/PKG-INFO +277 -42
- {textual_debugger-0.2.2/src/tdb → textual_debugger-0.2.6}/README.md +271 -38
- {textual_debugger-0.2.2 → textual_debugger-0.2.6}/pyproject.toml +6 -4
- {textual_debugger-0.2.2 → textual_debugger-0.2.6/src/tdb}/README.md +271 -38
- {textual_debugger-0.2.2 → textual_debugger-0.2.6}/src/tdb/__init__.py +1 -1
- textual_debugger-0.2.6/src/tdb/adapters/bash/__main__.py +23 -0
- textual_debugger-0.2.6/src/tdb/adapters/bash/declares.py +92 -0
- textual_debugger-0.2.6/src/tdb/adapters/bash/server.py +472 -0
- textual_debugger-0.2.6/src/tdb/adapters/bash/session.py +593 -0
- textual_debugger-0.2.6/src/tdb/adapters/bash/tdb_harness.sh +240 -0
- textual_debugger-0.2.6/src/tdb/adapters/perl/Devel/TdbCompile.pm +68 -0
- {textual_debugger-0.2.2 → textual_debugger-0.2.6}/src/tdb/adapters/perl/helpers.pl +64 -1
- textual_debugger-0.2.6/src/tdb/adapters/perl/server.py +1158 -0
- {textual_debugger-0.2.2 → textual_debugger-0.2.6}/src/tdb/adapters/perl/session.py +164 -21
- textual_debugger-0.2.6/src/tdb/adapters/tcsh/__init__.py +7 -0
- textual_debugger-0.2.6/src/tdb/adapters/tcsh/__main__.py +3 -0
- textual_debugger-0.2.6/src/tdb/adapters/tcsh/breakpoints.py +50 -0
- textual_debugger-0.2.6/src/tdb/adapters/tcsh/cli.py +163 -0
- textual_debugger-0.2.6/src/tdb/adapters/tcsh/guardian.py +888 -0
- textual_debugger-0.2.6/src/tdb/adapters/tcsh/inspect.py +193 -0
- textual_debugger-0.2.6/src/tdb/adapters/tcsh/instrumenter.py +368 -0
- textual_debugger-0.2.6/src/tdb/adapters/tcsh/models.py +62 -0
- textual_debugger-0.2.6/src/tdb/adapters/tcsh/protocol.py +68 -0
- textual_debugger-0.2.6/src/tdb/adapters/tcsh/runtime.py +314 -0
- textual_debugger-0.2.6/src/tdb/adapters/tcsh/scanner.py +225 -0
- textual_debugger-0.2.6/src/tdb/adapters/tcsh/server.py +813 -0
- textual_debugger-0.2.6/src/tdb/adapters/tcsh/session.py +1576 -0
- textual_debugger-0.2.6/src/tdb/adapters/tcsh/transport.py +1000 -0
- {textual_debugger-0.2.2 → textual_debugger-0.2.6}/src/tdb/app.py +108 -21
- {textual_debugger-0.2.2 → textual_debugger-0.2.6}/src/tdb/app_handlers/dap_events.py +61 -64
- {textual_debugger-0.2.2 → textual_debugger-0.2.6}/src/tdb/app_handlers/ui_panels.py +2 -0
- {textual_debugger-0.2.2 → textual_debugger-0.2.6}/src/tdb/cli.py +70 -0
- {textual_debugger-0.2.2 → textual_debugger-0.2.6}/src/tdb/dap/client.py +13 -1
- textual_debugger-0.2.6/src/tdb/dap/reverse.py +54 -0
- {textual_debugger-0.2.2 → textual_debugger-0.2.6}/src/tdb/dap/types.py +19 -0
- {textual_debugger-0.2.2 → textual_debugger-0.2.6}/src/tdb/languages/base.py +52 -0
- textual_debugger-0.2.6/src/tdb/languages/bash.py +84 -0
- {textual_debugger-0.2.2 → textual_debugger-0.2.6}/src/tdb/languages/cpp.py +12 -1
- textual_debugger-0.2.6/src/tdb/languages/errors.py +235 -0
- {textual_debugger-0.2.2 → textual_debugger-0.2.6}/src/tdb/languages/perl.py +6 -2
- {textual_debugger-0.2.2 → textual_debugger-0.2.6}/src/tdb/languages/python.py +3 -1
- {textual_debugger-0.2.2 → textual_debugger-0.2.6}/src/tdb/languages/registry.py +18 -0
- textual_debugger-0.2.6/src/tdb/languages/tcsh.py +102 -0
- textual_debugger-0.2.6/src/tdb/run_mode.py +271 -0
- {textual_debugger-0.2.2 → textual_debugger-0.2.6}/src/tdb/server/event_handler.py +0 -3
- {textual_debugger-0.2.2 → textual_debugger-0.2.6}/src/tdb/session/controller.py +92 -12
- {textual_debugger-0.2.2 → textual_debugger-0.2.6}/src/tdb/session/event_bus.py +49 -0
- {textual_debugger-0.2.2 → textual_debugger-0.2.6}/src/tdb/session/state.py +7 -0
- {textual_debugger-0.2.2 → textual_debugger-0.2.6}/src/tdb/session/textual_handler.py +0 -1
- textual_debugger-0.2.6/src/tdb/widgets/__init__.py +0 -0
- {textual_debugger-0.2.2 → textual_debugger-0.2.6}/src/tdb/widgets/async_tasks_modal.py +1 -1
- {textual_debugger-0.2.2 → textual_debugger-0.2.6}/src/tdb/widgets/code_view.py +0 -1
- {textual_debugger-0.2.2 → textual_debugger-0.2.6}/src/tdb/widgets/evaluate_console.py +2 -3
- {textual_debugger-0.2.2 → textual_debugger-0.2.6}/src/tdb/widgets/modals.py +55 -1
- {textual_debugger-0.2.2 → textual_debugger-0.2.6}/src/textual_debugger.egg-info/PKG-INFO +277 -42
- {textual_debugger-0.2.2 → textual_debugger-0.2.6}/src/textual_debugger.egg-info/SOURCES.txt +26 -0
- textual_debugger-0.2.2/src/tdb/adapters/perl/server.py +0 -593
- {textual_debugger-0.2.2 → textual_debugger-0.2.6}/LICENSE +0 -0
- {textual_debugger-0.2.2 → textual_debugger-0.2.6}/setup.cfg +0 -0
- {textual_debugger-0.2.2 → textual_debugger-0.2.6}/src/tdb/__main__.py +0 -0
- {textual_debugger-0.2.2 → textual_debugger-0.2.6}/src/tdb/_timeouts.py +0 -0
- {textual_debugger-0.2.2 → textual_debugger-0.2.6}/src/tdb/adapters/__init__.py +0 -0
- {textual_debugger-0.2.2/src/tdb/adapters/perl → textual_debugger-0.2.6/src/tdb/adapters/bash}/__init__.py +0 -0
- {textual_debugger-0.2.2 → textual_debugger-0.2.6}/src/tdb/adapters/perl/Devel/TdbRemote.pm +0 -0
- {textual_debugger-0.2.2/src/tdb/dap → textual_debugger-0.2.6/src/tdb/adapters/perl}/__init__.py +0 -0
- {textual_debugger-0.2.2 → textual_debugger-0.2.6}/src/tdb/adapters/perl/__main__.py +0 -0
- {textual_debugger-0.2.2 → textual_debugger-0.2.6}/src/tdb/adapters/perl/protocol.py +0 -0
- {textual_debugger-0.2.2 → textual_debugger-0.2.6}/src/tdb/adapters/perl/refs.py +0 -0
- {textual_debugger-0.2.2 → textual_debugger-0.2.6}/src/tdb/app_handlers/__init__.py +0 -0
- {textual_debugger-0.2.2 → textual_debugger-0.2.6}/src/tdb/app_handlers/inspection.py +0 -0
- {textual_debugger-0.2.2 → textual_debugger-0.2.6}/src/tdb/app_handlers/routing.py +0 -0
- {textual_debugger-0.2.2 → textual_debugger-0.2.6}/src/tdb/app_helpers.py +0 -0
- {textual_debugger-0.2.2 → textual_debugger-0.2.6}/src/tdb/breakpoint_hook.py +0 -0
- {textual_debugger-0.2.2/src/tdb/server → textual_debugger-0.2.6/src/tdb/dap}/__init__.py +0 -0
- {textual_debugger-0.2.2 → textual_debugger-0.2.6}/src/tdb/dap/messages.py +0 -0
- {textual_debugger-0.2.2 → textual_debugger-0.2.6}/src/tdb/dap/protocol.py +0 -0
- {textual_debugger-0.2.2 → textual_debugger-0.2.6}/src/tdb/inspection.py +0 -0
- {textual_debugger-0.2.2 → textual_debugger-0.2.6}/src/tdb/inspection_full.py +0 -0
- {textual_debugger-0.2.2 → textual_debugger-0.2.6}/src/tdb/keybindings/__init__.py +0 -0
- {textual_debugger-0.2.2 → textual_debugger-0.2.6}/src/tdb/languages/__init__.py +0 -0
- {textual_debugger-0.2.2 → textual_debugger-0.2.6}/src/tdb/mcp/__init__.py +0 -0
- {textual_debugger-0.2.2 → textual_debugger-0.2.6}/src/tdb/mcp/__main__.py +0 -0
- {textual_debugger-0.2.2 → textual_debugger-0.2.6}/src/tdb/mcp/server.py +0 -0
- {textual_debugger-0.2.2 → textual_debugger-0.2.6}/src/tdb/mcp/session.py +0 -0
- {textual_debugger-0.2.2 → textual_debugger-0.2.6}/src/tdb/persist.py +0 -0
- {textual_debugger-0.2.2 → textual_debugger-0.2.6}/src/tdb/post_mortem.py +0 -0
- {textual_debugger-0.2.2 → textual_debugger-0.2.6}/src/tdb/processes_cache.py +0 -0
- {textual_debugger-0.2.2 → textual_debugger-0.2.6}/src/tdb/replay.py +0 -0
- {textual_debugger-0.2.2/src/tdb/session → textual_debugger-0.2.6/src/tdb/server}/__init__.py +0 -0
- {textual_debugger-0.2.2 → textual_debugger-0.2.6}/src/tdb/server/app.py +0 -0
- {textual_debugger-0.2.2 → textual_debugger-0.2.6}/src/tdb/server/handlers.py +0 -0
- {textual_debugger-0.2.2 → textual_debugger-0.2.6}/src/tdb/server/rpc_types.py +0 -0
- {textual_debugger-0.2.2 → textual_debugger-0.2.6}/src/tdb/server/runner.py +0 -0
- {textual_debugger-0.2.2/src/tdb/widgets → textual_debugger-0.2.6/src/tdb/session}/__init__.py +0 -0
- {textual_debugger-0.2.2 → textual_debugger-0.2.6}/src/tdb/session/child_processes.py +0 -0
- {textual_debugger-0.2.2 → textual_debugger-0.2.6}/src/tdb/session/inspect_service.py +0 -0
- {textual_debugger-0.2.2 → textual_debugger-0.2.6}/src/tdb/session/messages.py +0 -0
- {textual_debugger-0.2.2 → textual_debugger-0.2.6}/src/tdb/session/post_mortem_loader.py +0 -0
- {textual_debugger-0.2.2 → textual_debugger-0.2.6}/src/tdb/session/recorder.py +0 -0
- {textual_debugger-0.2.2 → textual_debugger-0.2.6}/src/tdb/session/statement_stepper.py +0 -0
- {textual_debugger-0.2.2 → textual_debugger-0.2.6}/src/tdb/session/terminal.py +0 -0
- {textual_debugger-0.2.2 → textual_debugger-0.2.6}/src/tdb/source_analysis.py +0 -0
- {textual_debugger-0.2.2 → textual_debugger-0.2.6}/src/tdb/widgets/_inspection_modal.py +0 -0
- {textual_debugger-0.2.2 → textual_debugger-0.2.6}/src/tdb/widgets/breakpoint_view.py +0 -0
- {textual_debugger-0.2.2 → textual_debugger-0.2.6}/src/tdb/widgets/console_view.py +0 -0
- {textual_debugger-0.2.2 → textual_debugger-0.2.6}/src/tdb/widgets/full_contents_modal.py +0 -0
- {textual_debugger-0.2.2 → textual_debugger-0.2.6}/src/tdb/widgets/menu_bar.py +0 -0
- {textual_debugger-0.2.2 → textual_debugger-0.2.6}/src/tdb/widgets/processes_modal.py +0 -0
- {textual_debugger-0.2.2 → textual_debugger-0.2.6}/src/tdb/widgets/stack_view.py +0 -0
- {textual_debugger-0.2.2 → textual_debugger-0.2.6}/src/tdb/widgets/status_bar.py +0 -0
- {textual_debugger-0.2.2 → textual_debugger-0.2.6}/src/tdb/widgets/threads_modal.py +0 -0
- {textual_debugger-0.2.2 → textual_debugger-0.2.6}/src/tdb/widgets/variable_view.py +0 -0
- {textual_debugger-0.2.2 → textual_debugger-0.2.6}/src/textual_debugger.egg-info/dependency_links.txt +0 -0
- {textual_debugger-0.2.2 → textual_debugger-0.2.6}/src/textual_debugger.egg-info/entry_points.txt +0 -0
- {textual_debugger-0.2.2 → textual_debugger-0.2.6}/src/textual_debugger.egg-info/requires.txt +0 -0
- {textual_debugger-0.2.2 → textual_debugger-0.2.6}/src/textual_debugger.egg-info/top_level.txt +0 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: textual-debugger
|
|
3
|
-
Version: 0.2.
|
|
4
|
-
Summary: A TUI Python
|
|
3
|
+
Version: 0.2.6
|
|
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:
|
|
7
7
|
|
|
@@ -39,11 +39,13 @@ Classifier: Intended Audience :: Developers
|
|
|
39
39
|
Classifier: License :: OSI Approved :: MIT License
|
|
40
40
|
Classifier: Operating System :: POSIX :: Linux
|
|
41
41
|
Classifier: Programming Language :: Python :: 3
|
|
42
|
-
Classifier: Programming Language :: Python :: 3.10
|
|
43
42
|
Classifier: Programming Language :: Python :: 3.11
|
|
44
43
|
Classifier: Programming Language :: Python :: 3.12
|
|
44
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
45
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
46
|
+
Classifier: Programming Language :: Python :: 3.15
|
|
45
47
|
Classifier: Topic :: Software Development :: Debuggers
|
|
46
|
-
Requires-Python: >=3.
|
|
48
|
+
Requires-Python: >=3.11
|
|
47
49
|
Description-Content-Type: text/markdown
|
|
48
50
|
License-File: LICENSE
|
|
49
51
|
Requires-Dist: textual>=8.0.0
|
|
@@ -68,8 +70,12 @@ Dynamic: license-file
|
|
|
68
70
|
|
|
69
71
|
`textual-debugger` (the package) provides `tdb` (the command-line tool and module),
|
|
70
72
|
a full-featured terminal-based debugger for Python and other languages
|
|
71
|
-
with a Debug Adapter Protocol (DAP) implementation.
|
|
72
|
-
`
|
|
73
|
+
with a Debug Adapter Protocol (DAP) implementation. In addition to Python,
|
|
74
|
+
`tdb` comes with built-in support for
|
|
75
|
+
- C and C++ (via `gdb` or `lldb-dap`)
|
|
76
|
+
- Perl (via `perl -d`)
|
|
77
|
+
- Bash (via bash's own `DEBUG` trap; bash ≥ 4.4)
|
|
78
|
+
- Tcsh (via source instrumentation of a stock `tcsh`)
|
|
73
79
|
|
|
74
80
|
`tdb` is built with [textual](https://github.com/Textualize/textual) and speaks
|
|
75
81
|
DAP to a pluggable debug adapter: [debugpy](https://github.com/microsoft/debugpy)
|
|
@@ -90,7 +96,9 @@ MIT License. Copyright 2026 by Al Danial.
|
|
|
90
96
|
`tdb`:
|
|
91
97
|
|
|
92
98
|
- debugs multiple languages through the Debug Adapter Protocol: Python (via `debugpy`,
|
|
93
|
-
the richest feature set)
|
|
99
|
+
the richest feature set), C/C++ (via `gdb -i dap` or `lldb-dap`), Perl (via `perl -d`),
|
|
100
|
+
Bash (via bash's own `DEBUG` trap), and Tcsh (via source instrumentation of a
|
|
101
|
+
stock `tcsh`), with the language
|
|
94
102
|
auto-detected from the target (ref. [Multi-Language Debugging](#multi-language-debugging)).
|
|
95
103
|
|
|
96
104
|
- supports debugging of synchronous, asynchronous, multi-threaded, and multi-process Python code.
|
|
@@ -134,6 +142,8 @@ as open source.
|
|
|
134
142
|
- OpenAI, for providing access to Codex through the
|
|
135
143
|
[Codex for Open Source](https://developers.openai.com/community/codex-for-oss) program.
|
|
136
144
|
|
|
145
|
+
This project was inspired by Andreas Klöckner's excellent [pudb](https://pypi.org/project/pudb/) debugger.
|
|
146
|
+
|
|
137
147
|
## Gallery
|
|
138
148
|
<p align="center">
|
|
139
149
|
<img src="https://github.com/AlDanial/tdb/blob/main/gallery/async_breakpoint.png" alt="at breakpoint" width="300">
|
|
@@ -236,22 +246,26 @@ python -m tdb my_program.py
|
|
|
236
246
|
|
|
237
247
|
## Multi-Language Debugging
|
|
238
248
|
|
|
239
|
-
`tdb` debugs any language that has a Debug Adapter Protocol backend.
|
|
249
|
+
`tdb` debugs any language that has a Debug Adapter Protocol backend. Five
|
|
240
250
|
languages are supported out of the box:
|
|
241
251
|
|
|
242
|
-
| Language | Adapter(s) |
|
|
252
|
+
| Language | Adapter(s) | Dependencies | Feature level |
|
|
243
253
|
|----------|------------|------------------------|---------------|
|
|
244
|
-
| Python | `debugpy` (default) |
|
|
254
|
+
| Python | `debugpy` (default) | Python ≥ 3.11 | everything in this README |
|
|
245
255
|
| C / C++ (any native binary) | `gdb` (default), `lldb-dap` (alternate) | `gdb -i dap` requires GDB ≥ 14; `lldb-dap` ships with LLVM ≥ 17 (e.g. `apt install lldb`) | core debugging: breakpoints, stepping, stack, variables, evaluate console |
|
|
246
|
-
| Perl | perl-tdb (bundled) |
|
|
256
|
+
| Perl | perl-tdb (bundled) | perl ≥ 5.18 on PATH | core debugging + remote attach |
|
|
257
|
+
| Bash | bash-tdb (bundled) | bash ≥ 4.4 on PATH | core debugging (no remote attach) |
|
|
258
|
+
| Tcsh | tcsh-tdb (bundled) | tcsh on PATH | core debugging (no remote attach, no conditional breakpoints, no pause) |
|
|
247
259
|
|
|
248
260
|
### Language detection and selection
|
|
249
261
|
|
|
250
262
|
The language is auto-detected from the debug target:
|
|
251
263
|
|
|
252
|
-
1. File extension: `.py` → Python; `.pl` / `.pm` / `.t` → Perl
|
|
264
|
+
1. File extension: `.py` → Python; `.pl` / `.pm` / `.t` → Perl; `.sh` / `.bash`
|
|
265
|
+
→ Bash; `.csh` / `.tcsh` → Tcsh.
|
|
253
266
|
2. Native executables (ELF, Mach-O, PE magic bytes) → C/C++.
|
|
254
|
-
3. A `#!...python
|
|
267
|
+
3. A `#!...python`, `#!...perl`, `#!...bash`, or `#!...csh`/`#!...tcsh`
|
|
268
|
+
shebang → Python / Perl / Bash / Tcsh respectively.
|
|
255
269
|
4. C/C++/Rust *source* files (`.c`, `.cpp`, `.rs`, …) produce an error with a
|
|
256
270
|
hint: compile with debug info (`g++ -g -O0`) and debug the binary.
|
|
257
271
|
5. Anything else produces an error naming the `--lang` override.
|
|
@@ -283,16 +297,62 @@ conditions and persistence), stepping, continue/pause, run-to-cursor, stack
|
|
|
283
297
|
navigation, variable inspection, the evaluate console, syntax highlighting,
|
|
284
298
|
and the JSON-RPC / MCP programmatic modes.
|
|
285
299
|
|
|
286
|
-
Python-specific features are hidden or return
|
|
300
|
+
Python-specific features are hidden or return "not supported for this
|
|
287
301
|
language" message when debugging other languages: statement-granularity
|
|
288
302
|
stepping (non-Python languages always step per line), the async task /
|
|
289
303
|
process inspectors and wait graph, the evaluate console's trailing-`?` help,
|
|
290
304
|
`--python`/`--pv`, `--no-subprocess`, automatic child-process attachment, and
|
|
291
305
|
the post-mortem / `tdb.breakpoint()` hooks (those hooks live inside Python
|
|
292
306
|
programs by nature). Remote attach (`-r`) also works for Perl (see
|
|
293
|
-
[Perl](#perl)
|
|
294
|
-
for C/C
|
|
295
|
-
|
|
307
|
+
[Perl](#perl), `Devel::TdbRemote` in place of `debugpy.listen()`), but not
|
|
308
|
+
for C/C++, Bash, or Tcsh. `--terminal` works for every launch-mode
|
|
309
|
+
language — Python, Perl, Bash, Tcsh, and C/C++ via `--adapter lldb-dap` —
|
|
310
|
+
see [External Terminal Support](#external-terminal-support).
|
|
311
|
+
|
|
312
|
+
**Bash limitations (v1):** the bash adapter uses bash's own `DEBUG` trap and
|
|
313
|
+
has a smaller feature envelope than Python/Perl:
|
|
314
|
+
|
|
315
|
+
- Debuggee code that installs its own `DEBUG` trap clobbers the harness;
|
|
316
|
+
debugging silently degrades to free-running.
|
|
317
|
+
- No stopping inside subshells `(...)`, `$(...)`, or pipeline segments; they
|
|
318
|
+
execute normally.
|
|
319
|
+
- Child bash processes run uninstrumented.
|
|
320
|
+
- Outer-frame locals not inspectable (innermost frame only).
|
|
321
|
+
- Pause is deferred while blocked in an external command.
|
|
322
|
+
- `.sh` files that aren't bash are only diagnosed at launch, by bash itself
|
|
323
|
+
or the harness version check.
|
|
324
|
+
- The `DEBUG` trap never fires on a function-definition line, so a
|
|
325
|
+
breakpoint on a `func() {` line never hits; entry and step-in stops land
|
|
326
|
+
on the first executable line of the function body instead.
|
|
327
|
+
- The debug control channel occupies two inherited file descriptors
|
|
328
|
+
(typically high-numbered). A script that execs redirections onto those
|
|
329
|
+
exact fds (e.g. `exec 63>&-` or reusing them for its own I/O) will
|
|
330
|
+
silently break debugging.
|
|
331
|
+
|
|
332
|
+
See [Bash](#bash) below for launch details.
|
|
333
|
+
|
|
334
|
+
**Tcsh limitations (v1):** tcsh has no debug hooks at all, so the tcsh
|
|
335
|
+
adapter debugs an instrumented temporary *copy* of the script (original
|
|
336
|
+
paths and line numbers are preserved in everything tdb displays):
|
|
337
|
+
|
|
338
|
+
- Conditional breakpoints are not supported; a condition set in the
|
|
339
|
+
Breakpoint View is ignored for tcsh (the breakpoint always stops).
|
|
340
|
+
- No asynchronous pause: a free-running script stops only at the next
|
|
341
|
+
breakpoint (or when it exits).
|
|
342
|
+
- A breakpoint binds to the nearest safe statement at or after the
|
|
343
|
+
requested line; unplaceable breakpoints are reported unverified.
|
|
344
|
+
- Stack frames represent `source`d files, not native call frames, and only
|
|
345
|
+
literal `source` targets resolvable at launch are instrumented (computed
|
|
346
|
+
or `cd`-dependent sources run normally but are atomic to the debugger).
|
|
347
|
+
- All frames show the same live shell state (Shell Variables, Environment,
|
|
348
|
+
Aliases, Arguments). Stock tcsh keeps no per-frame history.
|
|
349
|
+
- Multiple commands on one physical line (`a ; b`), command substitutions,
|
|
350
|
+
and external commands are atomic stepping units.
|
|
351
|
+
- `$0` inside dynamically generated or evaluated text can expose the
|
|
352
|
+
generated copy's path (ordinary lexical `$0` is rewritten correctly).
|
|
353
|
+
- Requires Python ≥ 3.11.
|
|
354
|
+
|
|
355
|
+
See [Tcsh](#tcsh) below for launch details.
|
|
296
356
|
|
|
297
357
|
### C/C++ tips
|
|
298
358
|
|
|
@@ -304,16 +364,19 @@ currently ignored for non-Python targets.
|
|
|
304
364
|
variables, and evaluate console remain fully usable.
|
|
305
365
|
- GDB (the default adapter) has the most complete libstdc++
|
|
306
366
|
pretty-printing. `lldb-dap` (via `--adapter lldb-dap`) also debugs
|
|
307
|
-
GCC-built binaries fine
|
|
367
|
+
GCC-built binaries fine. DWARF is compiler-neutral.
|
|
308
368
|
- **GDB evaluate-console quirk:** GDB's DAP treats REPL input as CLI
|
|
309
369
|
commands, so evaluate expressions with an explicit `print`, e.g.
|
|
310
370
|
`print x` rather than bare `x` (bare `x` collides with GDB's
|
|
311
371
|
examine-memory command). `lldb-dap` evaluates bare expressions directly.
|
|
372
|
+
- `--terminal` (see [External Terminal Support](#external-terminal-support))
|
|
373
|
+
requires `--adapter lldb-dap`; GDB's DAP mode has no terminal integration
|
|
374
|
+
and `tdb` refuses `--terminal` with the default `gdb` adapter.
|
|
312
375
|
|
|
313
376
|
### Perl
|
|
314
377
|
|
|
315
|
-
`tdb` bundles its own Perl adapter (`perl-tdb`)
|
|
316
|
-
|
|
378
|
+
`tdb` bundles its own Perl adapter (`perl-tdb`) so only need
|
|
379
|
+
`perl` ≥ 5.18 on `PATH`. It drives stock `perl5db` under the
|
|
317
380
|
hood, so it works with any Perl already on the system.
|
|
318
381
|
|
|
319
382
|
**Launching a script:**
|
|
@@ -322,15 +385,64 @@ hood, so it works with any Perl already on the system.
|
|
|
322
385
|
tdb script.pl
|
|
323
386
|
```
|
|
324
387
|
|
|
388
|
+
`--terminal` is supported (see
|
|
389
|
+
[External Terminal Support](#external-terminal-support)).
|
|
390
|
+
|
|
391
|
+
**Compile-time code (`BEGIN` blocks):** Perl runs `BEGIN` blocks and the
|
|
392
|
+
`use` statements that are themselves `BEGIN` blocks while it is still
|
|
393
|
+
*compiling* your program, before stock `perl5db` ever stops. `tdb` arms the
|
|
394
|
+
debugger ahead of compilation so that code is debuggable too, which means the
|
|
395
|
+
first stop is the first **compile-time** statement of your file (typically
|
|
396
|
+
`use strict;` near the top) rather than the first runtime statement. Step from
|
|
397
|
+
there and you land inside your `BEGIN` blocks, with the stack and evaluate
|
|
398
|
+
views working normally (local variable listing is limited at a compile-time
|
|
399
|
+
stop); the `Stack` view shows the frame as `main::BEGIN`. Stepping through a
|
|
400
|
+
`use` line takes a few steps (the pragma's
|
|
401
|
+
own compile-time work happens in between) but you are never dragged into
|
|
402
|
+
another module's internals.
|
|
403
|
+
|
|
404
|
+
Two consequences worth knowing:
|
|
405
|
+
|
|
406
|
+
- **Breakpoints are deferred while your program compiles.** During the compile
|
|
407
|
+
phase Perl has only parsed part of your file, so its line table is
|
|
408
|
+
incomplete and a breakpoint can't be verified yet. `tdb` holds such requests
|
|
409
|
+
and, while it single-steps through the rest of compilation, checks each
|
|
410
|
+
compile-time statement it lands on against them. A breakpoint placed
|
|
411
|
+
*inside* a `BEGIN` block fires there directly, on the first run, without
|
|
412
|
+
needing to be stepped into by hand. Conditional breakpoints work the same
|
|
413
|
+
way at compile time; a condition that itself errors behaves exactly like a
|
|
414
|
+
bad condition at runtime in that it does not fire. Two residual caveats: a
|
|
415
|
+
breakpoint on a non-statement line (the `BEGIN {` line itself, or a blank
|
|
416
|
+
line) never fires during the compile phase, since it's never actually
|
|
417
|
+
trapped as a statement; and `hitCondition` (break on the Nth hit) isn't
|
|
418
|
+
honored for a compile-time stop, only a plain `condition`.
|
|
419
|
+
- **Startup is slower for large dependency graphs**, because the debugger is
|
|
420
|
+
active throughout compilation. A script with a big `use` tree takes
|
|
421
|
+
noticeably longer to reach its first stop under `tdb`.
|
|
422
|
+
|
|
423
|
+
**`END` blocks** are entered with **step-in** (`s`). `next` and `continue` run
|
|
424
|
+
straight past them to program termination, which is standard `perl5db`
|
|
425
|
+
behavior, not a `tdb` limitation.
|
|
426
|
+
|
|
427
|
+
**When your program dies:** an uncaught Perl error (`die`, or a fatal runtime
|
|
428
|
+
error such as division by zero) opens the same error modal Python tracebacks
|
|
429
|
+
get: the message, the call stack parsed from Perl's `at FILE line N.` /
|
|
430
|
+
`... called at FILE line N` output, and Code View navigated to the failing
|
|
431
|
+
line. This works for compile-time failures too, including a `die` inside a
|
|
432
|
+
`BEGIN` block that aborts compilation. Press `e` in Code View to re-summon the
|
|
433
|
+
last error. `tdb` also reports the debuggee's real exit status rather than
|
|
434
|
+
assuming success.
|
|
435
|
+
|
|
325
436
|
**Remote attach:** useful when the Perl process is already running (a long-
|
|
326
437
|
lived service, a process started by something other than `tdb`) or lives on
|
|
327
438
|
another host/container. Add three lines to the target program, with the
|
|
328
439
|
`use` line first so the debugger is armed before any of your code compiles:
|
|
329
440
|
|
|
330
441
|
```perl
|
|
331
|
-
use Devel::TdbRemote; #
|
|
442
|
+
use Devel::TdbRemote; # first line of your program
|
|
332
443
|
...
|
|
333
444
|
Devel::TdbRemote::listen(5678); # non-blocking
|
|
445
|
+
print "Waiting for tdb to attach on port 5678\n";
|
|
334
446
|
Devel::TdbRemote::wait_for_client(); # blocks until tdb connects
|
|
335
447
|
```
|
|
336
448
|
|
|
@@ -349,8 +461,8 @@ script controls startup), arm it before Perl even parses your file instead:
|
|
|
349
461
|
environment that launches the debuggee.
|
|
350
462
|
|
|
351
463
|
**Copying the adapter to a remote host:** `Devel::TdbRemote` and its helper
|
|
352
|
-
script are plain files, not a CPAN install
|
|
353
|
-
machine and point `PERL5LIB` at the directory that contains them:
|
|
464
|
+
script are plain files, not a CPAN install. Copy both onto the remote
|
|
465
|
+
machine and point `PERL5LIB` at the directory that contains them, for example:
|
|
354
466
|
|
|
355
467
|
```bash
|
|
356
468
|
# From a checkout or an installed wheel's site-packages/tdb/adapters/perl:
|
|
@@ -360,7 +472,7 @@ export PERL5LIB=/opt/tdb-perl:$PERL5LIB
|
|
|
360
472
|
```
|
|
361
473
|
|
|
362
474
|
(`Devel/TdbRemote.pm` locates `helpers.pl` next to itself at runtime, so keep
|
|
363
|
-
the two files in the same relative layout shown above
|
|
475
|
+
the two files in the same relative layout shown above; `helpers.pl` is a
|
|
364
476
|
sibling of the `Devel/` directory, not inside it.)
|
|
365
477
|
|
|
366
478
|
**PadWalker (optional but recommended):** inspecting lexical (`my`)
|
|
@@ -372,9 +484,70 @@ Install with `cpanm PadWalker` (or your distro's package) for full fidelity.
|
|
|
372
484
|
|
|
373
485
|
**Pause is unavailable in attach mode.** Launch-mode sessions (`tdb
|
|
374
486
|
script.pl`) support pausing a running program at any time. Remote-attach
|
|
375
|
-
sessions don't
|
|
487
|
+
sessions don't. Asynchronous pause (as Python gets via `debugpy`) needs a control channel
|
|
376
488
|
`Devel::TdbRemote` doesn't implement yet; `pause` in attach mode returns a
|
|
377
|
-
|
|
489
|
+
"not available" error instead of hanging.
|
|
490
|
+
|
|
491
|
+
### Bash
|
|
492
|
+
|
|
493
|
+
`tdb` bundles its own bash adapter (`bash-tdb`) so no separate adapter install
|
|
494
|
+
needed, just a `bash` ≥ 4.4 on `PATH`. It drives stock bash's own `DEBUG`
|
|
495
|
+
trap (with `extdebug` for return-value control) under the hood via a small
|
|
496
|
+
harness script sourced through `BASH_ENV`, so it works with any bash already
|
|
497
|
+
on the system.
|
|
498
|
+
|
|
499
|
+
**Launching a script:**
|
|
500
|
+
|
|
501
|
+
```bash
|
|
502
|
+
tdb script.sh
|
|
503
|
+
```
|
|
504
|
+
|
|
505
|
+
Core debugging works as described above (breakpoints, stepping,
|
|
506
|
+
continue/pause, stack, variables, evaluate console), with the v1 caveats
|
|
507
|
+
listed in [What works for non-Python languages](#what-works-for-non-python-languages).
|
|
508
|
+
Most notably, a breakpoint can't be set on a `func() {` line itself (the
|
|
509
|
+
`DEBUG` trap never fires there), stops never land inside subshells or
|
|
510
|
+
pipeline segments, child bash processes run uninstrumented, and only the
|
|
511
|
+
innermost frame's locals are inspectable. There is no remote-attach mode for
|
|
512
|
+
Bash. `--terminal` is supported (see
|
|
513
|
+
[External Terminal Support](#external-terminal-support)).
|
|
514
|
+
|
|
515
|
+
The Variables view shows three scopes for bash: Locals (innermost frame
|
|
516
|
+
only), Globals (unexported shell variables), and Environment (exported
|
|
517
|
+
variables, both inherited and script-`export`ed).
|
|
518
|
+
|
|
519
|
+
### Tcsh
|
|
520
|
+
|
|
521
|
+
`tdb` bundles its own tcsh adapter (`tcsh-tdb`) so no separate adapter
|
|
522
|
+
is needed, just a stock `tcsh` on `PATH` (or
|
|
523
|
+
`{"adapters": {"tcsh": "/path/to/tcsh"}}` in `config.json`). Stock tcsh has
|
|
524
|
+
no debugger hooks, so the adapter instruments a temporary copy of the script
|
|
525
|
+
(and of any literal `source`d files), runs it with `tcsh -f`, and
|
|
526
|
+
coordinates stops through private FIFOs. tdb always shows the original
|
|
527
|
+
source paths and line numbers; the generated copies are private adapter
|
|
528
|
+
details and are cleaned up when the session ends.
|
|
529
|
+
|
|
530
|
+
**Launching a script:**
|
|
531
|
+
|
|
532
|
+
```bash
|
|
533
|
+
tdb script.csh
|
|
534
|
+
```
|
|
535
|
+
|
|
536
|
+
Core debugging works as described above: line breakpoints, stepping
|
|
537
|
+
(`next` steps over `source`d files, `stepIn` steps into instrumented ones),
|
|
538
|
+
stack navigation across `source` nesting, variable inspection, and the
|
|
539
|
+
evaluate console with the v1 caveats listed in
|
|
540
|
+
[What works for non-Python languages](#what-works-for-non-python-languages),
|
|
541
|
+
most notably: no conditional breakpoints, no pause of a free-running
|
|
542
|
+
script, and stepping is per logical source line. `--terminal` is supported
|
|
543
|
+
(see [External Terminal Support](#external-terminal-support)).
|
|
544
|
+
|
|
545
|
+
The Variables view shows four scopes for tcsh: Shell Variables (`set`),
|
|
546
|
+
Environment (`setenv`), Aliases, and Arguments (`argv`). All of them show
|
|
547
|
+
the live state of the single tcsh process. The evaluate console executes
|
|
548
|
+
text directly in the paused shell. It can inspect *and mutate* state
|
|
549
|
+
(`set name = value` takes effect immediately), and a syntax error in
|
|
550
|
+
evaluated text can terminate the debuggee; there is no isolation.
|
|
378
551
|
|
|
379
552
|
## Layout
|
|
380
553
|
|
|
@@ -519,8 +692,10 @@ Breakpoints persist across session restarts.
|
|
|
519
692
|
|
|
520
693
|
### Variable Inspection
|
|
521
694
|
|
|
522
|
-
The Variable View shows a tree of scopes
|
|
523
|
-
|
|
695
|
+
The Variable View shows a tree of scopes with all variables in the current frame. The scopes
|
|
696
|
+
themselves are language-dependent: Locals, Globals, plus Environment for bash; Lexicals,
|
|
697
|
+
Globals, Specials for Perl (see the [Bash](#bash) and [Perl](#perl) sections above for
|
|
698
|
+
details). Expand nodes to drill into complex objects. Children are loaded lazily on demand.
|
|
524
699
|
Variable values can be changed in the Evaluate Console.
|
|
525
700
|
|
|
526
701
|
Double-click a variable, or highlight the variable with the text cursor in
|
|
@@ -843,22 +1018,82 @@ application directory and a shared library directory) in one invocation.
|
|
|
843
1018
|
|
|
844
1019
|
### External Terminal Support
|
|
845
1020
|
|
|
846
|
-
Some
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
1021
|
+
Some programs, notably text user interfaces, use terminal control codes and
|
|
1022
|
+
require direct access to the terminal to function properly. Such programs
|
|
1023
|
+
can be debugged with `tdb` by having it launch the debuggee in a separate
|
|
1024
|
+
terminal:
|
|
850
1025
|
|
|
851
1026
|
```bash
|
|
852
1027
|
tdb --terminal xterm my_tui_app.py
|
|
853
1028
|
```
|
|
854
1029
|
|
|
855
|
-
|
|
1030
|
+
`--terminal` works for every language `tdb` can *launch* (as opposed to
|
|
1031
|
+
attach to): Python, Perl, Bash, Tcsh, and C/C++ via `--adapter lldb-dap`.
|
|
1032
|
+
The default C/C++ adapter, `gdb -i dap`, has no terminal integration --
|
|
1033
|
+
`tdb` rejects `--terminal` up front with an error pointing at
|
|
1034
|
+
`--adapter lldb-dap` instead. `--terminal` also only applies when `tdb`
|
|
1035
|
+
launches the program itself; it is rejected for remote-attach (`-r`), since
|
|
1036
|
+
there's no program for `tdb` to spawn a terminal around.
|
|
1037
|
+
|
|
1038
|
+
The debuggee runs in a separate window of the specified terminal, including
|
|
1039
|
+
all of its stdin/stdout/stderr -- keyboard input, program output, and
|
|
1040
|
+
anything the program itself draws to the terminal all happen in that
|
|
1041
|
+
window, not in `tdb`'s Console View. Supported choices:
|
|
856
1042
|
`xterm`, `konsole`, `gnome-terminal`, `ghostty`, `kitty`, `iterm2`, `warp`,
|
|
857
1043
|
`wezterm`, `terminator`. The selected terminal must be on `PATH`. Debugging
|
|
858
|
-
|
|
1044
|
+
(breakpoints, stepping, variable inspection, the evaluate console) proceeds
|
|
1045
|
+
as usual in the terminal where `tdb` was invoked.
|
|
859
1046
|
|
|
860
1047
|
This feature only works in graphical environments where external terminals are available.
|
|
861
1048
|
|
|
1049
|
+
### Run Mode (`--run`)
|
|
1050
|
+
|
|
1051
|
+
For inspecting a program that appears hung: run it headless, at full speed, with no
|
|
1052
|
+
breakpoints installed and no stop-on-entry, then drop into the full TUI the moment you
|
|
1053
|
+
actually need it -- without paying for either up front.
|
|
1054
|
+
|
|
1055
|
+
```bash
|
|
1056
|
+
tdb --run my_program.py args...
|
|
1057
|
+
```
|
|
1058
|
+
|
|
1059
|
+
The debuggee's stdout/stderr stream straight to the terminal. If the program exits on
|
|
1060
|
+
its own, `tdb` exits with the same code:
|
|
1061
|
+
|
|
1062
|
+
```bash
|
|
1063
|
+
tdb --run my_program.py; echo $? # my_program.py's own exit code
|
|
1064
|
+
```
|
|
1065
|
+
|
|
1066
|
+
**Interrupting:** press Ctrl-C in the terminal (any platform), or, on Unix, send
|
|
1067
|
+
`SIGUSR1` to `tdb`'s pid from another terminal: `kill -USR1 <tdb pid>`. Either one pauses
|
|
1068
|
+
the debuggee at its currently executing line and opens the TUI with full debugging
|
|
1069
|
+
available -- breakpoints, stepping, variable inspection, the evaluate console. The
|
|
1070
|
+
debuggee itself never receives the signal (`tdb`'s adapter runs in its own process
|
|
1071
|
+
group), so its own `SIGINT` handling is undisturbed.
|
|
1072
|
+
|
|
1073
|
+
**Quitting an adopted session** adds a third choice to the usual quit dialog:
|
|
1074
|
+
- `d` (or `q`) -- detach and resume: the program keeps running headlessly; interrupt it
|
|
1075
|
+
again later the same way.
|
|
1076
|
+
- `t` -- terminate the program and quit `tdb`.
|
|
1077
|
+
- `Esc` -- cancel, stay in the TUI.
|
|
1078
|
+
|
|
1079
|
+
A breakpoint set during one of these episodes stays live after you detach; if it's hit,
|
|
1080
|
+
`tdb` reopens the TUI there, just like an interrupt.
|
|
1081
|
+
|
|
1082
|
+
If the program instead dies on an unhandled exception -- in Python this includes a
|
|
1083
|
+
nonzero `sys.exit()`, which `debugpy` treats as an uncaught `SystemExit` -- `tdb` opens
|
|
1084
|
+
the TUI at the point of failure instead of exiting silently, so you can inspect the
|
|
1085
|
+
crash. Exit-code passthrough applies only to a clean exit during the headless phase.
|
|
1086
|
+
|
|
1087
|
+
Supported languages: Python, Perl, Bash, Tcsh, and C/C++ (both `gdb` and `lldb-dap`).
|
|
1088
|
+
`--run` is rejected up front for any other language.
|
|
1089
|
+
|
|
1090
|
+
**Limitation:** pausing is cooperative. If the debuggee is blocked inside a single
|
|
1091
|
+
blocking external call or syscall, the pause can't land until that call returns --
|
|
1092
|
+
`tdb` prints a notice and opens the TUI once the stop actually arrives.
|
|
1093
|
+
|
|
1094
|
+
**Incompatible flags:** `-r`, `-k`/`-t`, `--record`, `--replay`, `--server`,
|
|
1095
|
+
`--headless`, `--mcp`, `--terminal`.
|
|
1096
|
+
|
|
862
1097
|
### Keybinding Schemes
|
|
863
1098
|
|
|
864
1099
|
```bash
|
|
@@ -969,23 +1204,23 @@ Each is JSON with `event`, `data`, and `timestamp` fields.
|
|
|
969
1204
|
## Recording and replaying sessions
|
|
970
1205
|
|
|
971
1206
|
`tdb --record session.jsonl prog.py` runs a normal TUI session and captures
|
|
972
|
-
your debugging actions
|
|
1207
|
+
your debugging actions including breakpoints (including `-k`/`-t` and persisted
|
|
973
1208
|
ones), stepping, continue/pause, Evaluate-console entries, stack-frame
|
|
974
|
-
navigation, variable expansion, restart, quit
|
|
1209
|
+
navigation, variable expansion, restart, quit. The session is
|
|
1210
|
+
written to `session.jsonl` as
|
|
975
1211
|
JSON-RPC commands. Works with launch mode (any language) and `-r`
|
|
976
1212
|
remote attach.
|
|
977
1213
|
|
|
978
1214
|
Replay it two ways:
|
|
979
1215
|
|
|
980
|
-
- `tdb --replay session.jsonl`
|
|
1216
|
+
- `tdb --replay session.jsonl` launches the recorded
|
|
981
1217
|
program headless, feeds every recorded command through the same RPC
|
|
982
1218
|
dispatch `tdb --server` uses, and prints a transcript (recorded time,
|
|
983
1219
|
command, verbatim result, interleaved program output). Exit code 0 iff
|
|
984
1220
|
every command succeeded. Add `--timing` to reproduce the original
|
|
985
1221
|
pacing, `--replay-timeout S` to bound each stop-wait (default 30 s).
|
|
986
1222
|
- Against a live server: start `tdb --server prog.py`, then feed line 2
|
|
987
|
-
onward of the file to `POST /rpc`
|
|
988
|
-
request body:
|
|
1223
|
+
onward of the file to `POST /rpc` . Each line is a valid request body:
|
|
989
1224
|
|
|
990
1225
|
tail -n +2 session.jsonl | while read line; do
|
|
991
1226
|
curl -s -X POST -H 'Content-Type: application/json' \
|
|
@@ -1039,7 +1274,7 @@ client expects to launch servers.
|
|
|
1039
1274
|
| Cluster | Tools |
|
|
1040
1275
|
|---------|-------|
|
|
1041
1276
|
| Lifecycle | `debug_launch`, `debug_attach`, `quit` |
|
|
1042
|
-
| Control | `control(action, timeout_s=30)`
|
|
1277
|
+
| Control | `control(action, timeout_s=30)` where `action ∈ {continue, next, step_in, step_out, pause, wait_for_stop}` |
|
|
1043
1278
|
| Inspection | `inspect(expressions)`, `read_source(file_path)`, `stack_trace()`, `status()`, `get_output()` |
|
|
1044
1279
|
| Breakpoints | `set_breakpoint(spec, condition?, hit_condition?)`, `remove_breakpoint(spec)`, `list_breakpoints()` |
|
|
1045
1280
|
| Differentiators | `threads(thread_id?)`, `tasks(task_name?)`, `processes(name_or_pid?)`, `wait_graph()` |
|
|
@@ -1109,7 +1344,7 @@ usage: tdb [-h] [-v] [-r [HOST:]PORT] [--cwd CWD] [--no-stop-on-entry]
|
|
|
1109
1344
|
| `--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. |
|
|
1110
1345
|
| `--remote-root PATH` | Remote directory matched to `--local-root` (same CLI position via `zip()`). |
|
|
1111
1346
|
| `-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. |
|
|
1112
|
-
| `-t`, `--to-line FILE:LINE|LINE` | Like `-k`, but the breakpoint is not saved to the breakpoints file
|
|
1347
|
+
| `-t`, `--to-line FILE:LINE|LINE` | Like `-k`, but the breakpoint is not saved to the breakpoints file, it just takes you to that spot in the code for this session (may be repeated). |
|
|
1113
1348
|
| `--no-stop-on-entry` | Do not pause at the first line (default: stop on entry; automatic when `-k` is given) |
|
|
1114
1349
|
| `--cwd DIR` | Working directory for the debuggee |
|
|
1115
1350
|
| `--python PATH` | Python interpreter for the debuggee (Python targets only) |
|
|
@@ -1144,7 +1379,7 @@ executable path (`{"adapters": {"lldb-dap": "/opt/llvm/bin/lldb-dap"}}`), and
|
|
|
1144
1379
|
(`{"default_adapters": {"cpp": "lldb-dap"}}`).
|
|
1145
1380
|
|
|
1146
1381
|
**Perl is a special case:** `perl-tdb` is tdb's own bundled adapter (always
|
|
1147
|
-
found
|
|
1382
|
+
found; it's Python code, not an external executable), so
|
|
1148
1383
|
`adapters.perl` doesn't select an adapter binary. Instead it names the
|
|
1149
1384
|
*Perl interpreter* tdb should spawn to run the debuggee:
|
|
1150
1385
|
`{"adapters": {"perl": "/path/to/perl"}}`. Use this when the `perl` on
|