textual-debugger 0.1.5__tar.gz → 0.2.0__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.1.5 → textual_debugger-0.2.0}/PKG-INFO +141 -20
- {textual_debugger-0.1.5/src/tdb → textual_debugger-0.2.0}/README.md +140 -19
- {textual_debugger-0.1.5 → textual_debugger-0.2.0/src/tdb}/README.md +140 -19
- {textual_debugger-0.1.5 → textual_debugger-0.2.0}/src/tdb/__init__.py +1 -1
- {textual_debugger-0.1.5 → textual_debugger-0.2.0}/src/tdb/app.py +63 -13
- {textual_debugger-0.1.5 → textual_debugger-0.2.0}/src/tdb/app_handlers/dap_events.py +2 -0
- {textual_debugger-0.1.5 → textual_debugger-0.2.0}/src/tdb/app_handlers/inspection.py +56 -8
- {textual_debugger-0.1.5 → textual_debugger-0.2.0}/src/tdb/cli.py +61 -2
- {textual_debugger-0.1.5 → textual_debugger-0.2.0}/src/tdb/dap/client.py +45 -75
- textual_debugger-0.2.0/src/tdb/languages/__init__.py +21 -0
- textual_debugger-0.2.0/src/tdb/languages/base.py +139 -0
- textual_debugger-0.2.0/src/tdb/languages/cpp.py +150 -0
- textual_debugger-0.2.0/src/tdb/languages/python.py +116 -0
- textual_debugger-0.2.0/src/tdb/languages/registry.py +106 -0
- {textual_debugger-0.1.5 → textual_debugger-0.2.0}/src/tdb/mcp/server.py +12 -2
- {textual_debugger-0.1.5 → textual_debugger-0.2.0}/src/tdb/mcp/session.py +48 -4
- {textual_debugger-0.1.5 → textual_debugger-0.2.0}/src/tdb/persist.py +15 -1
- {textual_debugger-0.1.5 → textual_debugger-0.2.0}/src/tdb/server/handlers.py +9 -4
- {textual_debugger-0.1.5 → textual_debugger-0.2.0}/src/tdb/server/runner.py +23 -9
- {textual_debugger-0.1.5 → textual_debugger-0.2.0}/src/tdb/session/child_processes.py +7 -0
- {textual_debugger-0.1.5 → textual_debugger-0.2.0}/src/tdb/session/controller.py +71 -19
- {textual_debugger-0.1.5 → textual_debugger-0.2.0}/src/tdb/session/inspect_service.py +14 -2
- {textual_debugger-0.1.5 → textual_debugger-0.2.0}/src/tdb/session/statement_stepper.py +16 -3
- {textual_debugger-0.1.5 → textual_debugger-0.2.0}/src/tdb/widgets/code_view.py +6 -3
- {textual_debugger-0.1.5 → textual_debugger-0.2.0}/src/textual_debugger.egg-info/PKG-INFO +141 -20
- {textual_debugger-0.1.5 → textual_debugger-0.2.0}/src/textual_debugger.egg-info/SOURCES.txt +5 -0
- {textual_debugger-0.1.5 → textual_debugger-0.2.0}/LICENSE +0 -0
- {textual_debugger-0.1.5 → textual_debugger-0.2.0}/pyproject.toml +0 -0
- {textual_debugger-0.1.5 → textual_debugger-0.2.0}/setup.cfg +0 -0
- {textual_debugger-0.1.5 → textual_debugger-0.2.0}/src/tdb/__main__.py +0 -0
- {textual_debugger-0.1.5 → textual_debugger-0.2.0}/src/tdb/_timeouts.py +0 -0
- {textual_debugger-0.1.5 → textual_debugger-0.2.0}/src/tdb/app_handlers/__init__.py +0 -0
- {textual_debugger-0.1.5 → textual_debugger-0.2.0}/src/tdb/app_handlers/routing.py +0 -0
- {textual_debugger-0.1.5 → textual_debugger-0.2.0}/src/tdb/app_handlers/ui_panels.py +0 -0
- {textual_debugger-0.1.5 → textual_debugger-0.2.0}/src/tdb/app_helpers.py +0 -0
- {textual_debugger-0.1.5 → textual_debugger-0.2.0}/src/tdb/breakpoint_hook.py +0 -0
- {textual_debugger-0.1.5 → textual_debugger-0.2.0}/src/tdb/dap/__init__.py +0 -0
- {textual_debugger-0.1.5 → textual_debugger-0.2.0}/src/tdb/dap/messages.py +0 -0
- {textual_debugger-0.1.5 → textual_debugger-0.2.0}/src/tdb/dap/protocol.py +0 -0
- {textual_debugger-0.1.5 → textual_debugger-0.2.0}/src/tdb/dap/types.py +0 -0
- {textual_debugger-0.1.5 → textual_debugger-0.2.0}/src/tdb/inspection.py +0 -0
- {textual_debugger-0.1.5 → textual_debugger-0.2.0}/src/tdb/inspection_full.py +0 -0
- {textual_debugger-0.1.5 → textual_debugger-0.2.0}/src/tdb/keybindings/__init__.py +0 -0
- {textual_debugger-0.1.5 → textual_debugger-0.2.0}/src/tdb/mcp/__init__.py +0 -0
- {textual_debugger-0.1.5 → textual_debugger-0.2.0}/src/tdb/mcp/__main__.py +0 -0
- {textual_debugger-0.1.5 → textual_debugger-0.2.0}/src/tdb/post_mortem.py +0 -0
- {textual_debugger-0.1.5 → textual_debugger-0.2.0}/src/tdb/processes_cache.py +0 -0
- {textual_debugger-0.1.5 → textual_debugger-0.2.0}/src/tdb/server/__init__.py +0 -0
- {textual_debugger-0.1.5 → textual_debugger-0.2.0}/src/tdb/server/app.py +0 -0
- {textual_debugger-0.1.5 → textual_debugger-0.2.0}/src/tdb/server/event_handler.py +0 -0
- {textual_debugger-0.1.5 → textual_debugger-0.2.0}/src/tdb/server/rpc_types.py +0 -0
- {textual_debugger-0.1.5 → textual_debugger-0.2.0}/src/tdb/session/__init__.py +0 -0
- {textual_debugger-0.1.5 → textual_debugger-0.2.0}/src/tdb/session/event_bus.py +0 -0
- {textual_debugger-0.1.5 → textual_debugger-0.2.0}/src/tdb/session/messages.py +0 -0
- {textual_debugger-0.1.5 → textual_debugger-0.2.0}/src/tdb/session/post_mortem_loader.py +0 -0
- {textual_debugger-0.1.5 → textual_debugger-0.2.0}/src/tdb/session/state.py +0 -0
- {textual_debugger-0.1.5 → textual_debugger-0.2.0}/src/tdb/session/terminal.py +0 -0
- {textual_debugger-0.1.5 → textual_debugger-0.2.0}/src/tdb/session/textual_handler.py +0 -0
- {textual_debugger-0.1.5 → textual_debugger-0.2.0}/src/tdb/source_analysis.py +0 -0
- {textual_debugger-0.1.5 → textual_debugger-0.2.0}/src/tdb/widgets/__init__.py +0 -0
- {textual_debugger-0.1.5 → textual_debugger-0.2.0}/src/tdb/widgets/_inspection_modal.py +0 -0
- {textual_debugger-0.1.5 → textual_debugger-0.2.0}/src/tdb/widgets/async_tasks_modal.py +0 -0
- {textual_debugger-0.1.5 → textual_debugger-0.2.0}/src/tdb/widgets/breakpoint_view.py +0 -0
- {textual_debugger-0.1.5 → textual_debugger-0.2.0}/src/tdb/widgets/console_view.py +0 -0
- {textual_debugger-0.1.5 → textual_debugger-0.2.0}/src/tdb/widgets/evaluate_console.py +0 -0
- {textual_debugger-0.1.5 → textual_debugger-0.2.0}/src/tdb/widgets/full_contents_modal.py +0 -0
- {textual_debugger-0.1.5 → textual_debugger-0.2.0}/src/tdb/widgets/menu_bar.py +0 -0
- {textual_debugger-0.1.5 → textual_debugger-0.2.0}/src/tdb/widgets/modals.py +0 -0
- {textual_debugger-0.1.5 → textual_debugger-0.2.0}/src/tdb/widgets/processes_modal.py +0 -0
- {textual_debugger-0.1.5 → textual_debugger-0.2.0}/src/tdb/widgets/stack_view.py +0 -0
- {textual_debugger-0.1.5 → textual_debugger-0.2.0}/src/tdb/widgets/status_bar.py +0 -0
- {textual_debugger-0.1.5 → textual_debugger-0.2.0}/src/tdb/widgets/threads_modal.py +0 -0
- {textual_debugger-0.1.5 → textual_debugger-0.2.0}/src/tdb/widgets/variable_view.py +0 -0
- {textual_debugger-0.1.5 → textual_debugger-0.2.0}/src/textual_debugger.egg-info/dependency_links.txt +0 -0
- {textual_debugger-0.1.5 → textual_debugger-0.2.0}/src/textual_debugger.egg-info/entry_points.txt +0 -0
- {textual_debugger-0.1.5 → textual_debugger-0.2.0}/src/textual_debugger.egg-info/requires.txt +0 -0
- {textual_debugger-0.1.5 → textual_debugger-0.2.0}/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.
|
|
3
|
+
Version: 0.2.0
|
|
4
4
|
Summary: A TUI Python debugger based on textual and debugpy
|
|
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:
|
|
@@ -67,12 +67,18 @@ Dynamic: license-file
|
|
|
67
67
|
# `textual-debugger`
|
|
68
68
|
|
|
69
69
|
`textual-debugger` (the package) provides `tdb` (the command-line tool and module),
|
|
70
|
-
a full-featured terminal-based Python
|
|
71
|
-
|
|
72
|
-
`
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
70
|
+
a full-featured terminal-based debugger for Python and other languages
|
|
71
|
+
with a Debug Adapter Protocol (DAP) implementation. C and C++ support (via
|
|
72
|
+
`gdb` or `lldb-dap`) is built in.
|
|
73
|
+
|
|
74
|
+
`tdb` is built with [textual](https://github.com/Textualize/textual) and speaks
|
|
75
|
+
DAP to a pluggable debug adapter: [debugpy](https://github.com/microsoft/debugpy)
|
|
76
|
+
(the engine behind VS Code's Python debugger) for Python,
|
|
77
|
+
[GDB's DAP mode](https://sourceware.org/gdb/current/onlinedocs/gdb.html/Debugger-Adapter-Protocol.html) or
|
|
78
|
+
[lldb-dap](https://lldb.llvm.org/resources/lldbdap.html)
|
|
79
|
+
for compiled code. It provides a rich interactive interface for stepping through
|
|
80
|
+
code, inspecting variables, managing breakpoints, and evaluating expressions in
|
|
81
|
+
complex programs.
|
|
76
82
|
|
|
77
83
|
- PyPI: https://pypi.org/project/textual-debugger/
|
|
78
84
|
- GitHub: https://github.com/AlDanial/tdb
|
|
@@ -83,6 +89,10 @@ MIT License. Copyright 2026 by Al Danial.
|
|
|
83
89
|
|
|
84
90
|
`tdb`:
|
|
85
91
|
|
|
92
|
+
- debugs multiple languages through the Debug Adapter Protocol: Python (via `debugpy`,
|
|
93
|
+
the richest feature set) and C/C++ (via `gdb -i dap` or `lldb-dap`), with the language
|
|
94
|
+
auto-detected from the target (ref. [Multi-Language Debugging](#multi-language-debugging)).
|
|
95
|
+
|
|
86
96
|
- supports debugging of synchronous, asynchronous, multi-threaded, and multi-process Python code.
|
|
87
97
|
It specifically supports modules
|
|
88
98
|
- `asyncio` (with a built-in async task inspector and task wait graph)
|
|
@@ -169,6 +179,16 @@ tdb my_program.py
|
|
|
169
179
|
# debug with arguments
|
|
170
180
|
tdb my_program.py arg1 arg2
|
|
171
181
|
|
|
182
|
+
# debug a C/C++ (or other native) executable built with -g. The ELF/Mach-O/PE
|
|
183
|
+
# binary is auto-detected and debugged through GDB's DAP mode (GDB >= 14)
|
|
184
|
+
tdb ./myprog arg1 arg2
|
|
185
|
+
|
|
186
|
+
# same, but using lldb-dap (LLVM >= 17) instead of gdb
|
|
187
|
+
tdb --adapter lldb-dap ./myprog
|
|
188
|
+
|
|
189
|
+
# force the language when auto-detection can't tell (e.g. an extensionless script)
|
|
190
|
+
tdb --lang python ./mytool
|
|
191
|
+
|
|
172
192
|
# add breakpoints at lines 20 and 35 of `my_program.py` and line 14
|
|
173
193
|
# of `module.py` (when -k is given, --no-stop-on-entry is set and the
|
|
174
194
|
# program runs to the first breakpoint)
|
|
@@ -210,6 +230,79 @@ Alternatively, use the module entry point:
|
|
|
210
230
|
python -m tdb my_program.py
|
|
211
231
|
```
|
|
212
232
|
|
|
233
|
+
## Multi-Language Debugging
|
|
234
|
+
|
|
235
|
+
`tdb` debugs any language that has a Debug Adapter Protocol backend. Two
|
|
236
|
+
languages are supported out of the box:
|
|
237
|
+
|
|
238
|
+
| Language | Adapter(s) | How to get the adapter | Feature level |
|
|
239
|
+
|----------|------------|------------------------|---------------|
|
|
240
|
+
| Python | `debugpy` (default) | installed with `textual-debugger` | everything in this README |
|
|
241
|
+
| 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 |
|
|
242
|
+
|
|
243
|
+
### Language detection and selection
|
|
244
|
+
|
|
245
|
+
The language is auto-detected from the debug target:
|
|
246
|
+
|
|
247
|
+
1. File extension: `.py` → Python.
|
|
248
|
+
2. Native executables (ELF, Mach-O, PE magic bytes) → C/C++.
|
|
249
|
+
3. A `#!...python` shebang → Python.
|
|
250
|
+
4. C/C++/Rust *source* files (`.c`, `.cpp`, `.rs`, …) produce an error with a
|
|
251
|
+
hint: compile with debug info (`g++ -g -O0`) and debug the binary.
|
|
252
|
+
5. Anything else produces an error naming the `--lang` override.
|
|
253
|
+
|
|
254
|
+
`--lang` forces the language; `--adapter` picks a non-default adapter within
|
|
255
|
+
it (`tdb --lang cpp --adapter lldb-dap ./myprog`).
|
|
256
|
+
|
|
257
|
+
> **Migration note:** extensionless Python scripts without a `python` shebang
|
|
258
|
+
> were previously assumed to be Python; they now require `--lang python`.
|
|
259
|
+
|
|
260
|
+
### Adapters are found on `PATH`
|
|
261
|
+
|
|
262
|
+
`tdb` does not download or bundle adapters. If the adapter executable isn't
|
|
263
|
+
found, the error names the package to install. To use an adapter from a
|
|
264
|
+
non-standard location, or change a language's default adapter, add to
|
|
265
|
+
`config.json` (see [Configuration](#configuration)):
|
|
266
|
+
|
|
267
|
+
```json
|
|
268
|
+
{
|
|
269
|
+
"adapters": {"lldb-dap": "/opt/llvm/bin/lldb-dap"},
|
|
270
|
+
"default_adapters": {"cpp": "lldb-dap"}
|
|
271
|
+
}
|
|
272
|
+
```
|
|
273
|
+
|
|
274
|
+
### What works for non-Python languages
|
|
275
|
+
|
|
276
|
+
Core debugging works identically for every language: breakpoints (incl.
|
|
277
|
+
conditions and persistence), stepping, continue/pause, run-to-cursor, stack
|
|
278
|
+
navigation, variable inspection, the evaluate console, syntax highlighting,
|
|
279
|
+
and the JSON-RPC / MCP programmatic modes.
|
|
280
|
+
|
|
281
|
+
Python-specific features are hidden or return a clear "not supported for this
|
|
282
|
+
language" message when debugging other languages: statement-granularity
|
|
283
|
+
stepping (non-Python languages always step per line), the async task /
|
|
284
|
+
process inspectors and wait graph, the evaluate console's trailing-`?` help,
|
|
285
|
+
remote attach (`-r`), `--python`/`--pv`, `--no-subprocess`,
|
|
286
|
+
automatic child-process attachment, and the post-mortem / `tdb.breakpoint()`
|
|
287
|
+
hooks (those hooks live inside Python programs by nature). `--terminal` is
|
|
288
|
+
currently ignored for non-Python targets.
|
|
289
|
+
|
|
290
|
+
### C/C++ tips
|
|
291
|
+
|
|
292
|
+
- Compile with `-g` (ideally `-g -O0`). If no breakpoint in a file can be
|
|
293
|
+
bound, `tdb` prints a console warning suggesting the program may lack
|
|
294
|
+
debug info.
|
|
295
|
+
- Stack frames pointing into system libraries often have no source on disk;
|
|
296
|
+
the Code View shows a `<Could not read …>` placeholder while the stack,
|
|
297
|
+
variables, and evaluate console remain fully usable.
|
|
298
|
+
- GDB (the default adapter) has the most complete libstdc++
|
|
299
|
+
pretty-printing. `lldb-dap` (via `--adapter lldb-dap`) also debugs
|
|
300
|
+
GCC-built binaries fine — DWARF is compiler-neutral.
|
|
301
|
+
- **GDB evaluate-console quirk:** GDB's DAP treats REPL input as CLI
|
|
302
|
+
commands, so evaluate expressions with an explicit `print`, e.g.
|
|
303
|
+
`print x` rather than bare `x` (bare `x` collides with GDB's
|
|
304
|
+
examine-memory command). `lldb-dap` evaluates bare expressions directly.
|
|
305
|
+
|
|
213
306
|
## Layout
|
|
214
307
|
|
|
215
308
|
```
|
|
@@ -238,7 +331,7 @@ The footer shows the most relevant keybindings for the current mode.
|
|
|
238
331
|
### Navigation and Keybindings
|
|
239
332
|
|
|
240
333
|
|
|
241
|
-
The Code View shows syntax-highlighted
|
|
334
|
+
The Code View shows syntax-highlighted source (lexer chosen per language) with line numbers.
|
|
242
335
|
A cursor line (blue) tracks your position; the current execution line is highlighted in gold.
|
|
243
336
|
|
|
244
337
|
**View focus shortcuts (global):**
|
|
@@ -330,6 +423,9 @@ lands on `print(results)`, not on each interior sub-line of the `gather` call. S
|
|
|
330
423
|
stops on each physical line--useful for inspecting how a complex expression is built up.
|
|
331
424
|
The choice is saved to `~/.config/tdb/config.json`.
|
|
332
425
|
|
|
426
|
+
Statement mode requires a source-language model and is currently Python-only;
|
|
427
|
+
other languages always step per line (the Step Mode menu says so if you try).
|
|
428
|
+
|
|
333
429
|
### Breakpoints
|
|
334
430
|
|
|
335
431
|
Click the gutter in the Code View to toggle a breakpoint, or press `b` in Debug mode.
|
|
@@ -387,6 +483,15 @@ interactive evaluation of expressions in the current scope:
|
|
|
387
483
|
|
|
388
484
|
Variable values set here are reflected in the running code.
|
|
389
485
|
|
|
486
|
+
### Cut / Paste
|
|
487
|
+
|
|
488
|
+
Expression for the Evaluate Console are often copied from the Code View.
|
|
489
|
+
Doing this in `tdb` differs from traditional terminal behavior, because `textual` applications
|
|
490
|
+
capture mouse events for their own use.
|
|
491
|
+
|
|
492
|
+
Instead, hold the `Shift` key while performing your conventional cut/paste keystrokes or mouse
|
|
493
|
+
operation to get the expected behavior.
|
|
494
|
+
|
|
390
495
|
### Console Output
|
|
391
496
|
|
|
392
497
|
The Console View captures stdout (normal text) and stderr (red text) from the debuggee
|
|
@@ -754,7 +859,7 @@ curl -s -X POST http://127.0.0.1:8150/rpc \
|
|
|
754
859
|
| `set_breakpoint` | `["file:line"]` or `["file:line", "condition", "hit_condition"]` | Set a breakpoint |
|
|
755
860
|
| `remove_breakpoint` | `["file:line"]` | Remove a breakpoint |
|
|
756
861
|
| `list_breakpoints` | `[]` | Show all breakpoints |
|
|
757
|
-
| `continue` | `[]` or `[timeout_s]` | Resume execution; on timeout returns `"still running
|
|
862
|
+
| `continue` | `[]` or `[timeout_s]` | Resume execution; on timeout returns `"still running--call pause or wait again"` (success) |
|
|
758
863
|
| `next` | `[]` or `[timeout_s]` | Step over |
|
|
759
864
|
| `step_in` | `[]` or `[timeout_s]` | Step into |
|
|
760
865
|
| `step_out` | `[]` or `[timeout_s]` | Step out |
|
|
@@ -793,7 +898,7 @@ Each is JSON with `event`, `data`, and `timestamp` fields.
|
|
|
793
898
|
tdb ships a Model Context Protocol (MCP) server (`tdb-mcp`) that exposes
|
|
794
899
|
the debugger as a curated set of tools an AI agent can call. The MCP
|
|
795
900
|
server is a third in-process consumer of the same dispatch handlers the
|
|
796
|
-
TUI and the HTTP server use
|
|
901
|
+
TUI and the HTTP server use so an agent gets the same lock semantics,
|
|
797
902
|
including the pause-during-continue bypass, and the same DAP-backed
|
|
798
903
|
inspection surface.
|
|
799
904
|
|
|
@@ -832,17 +937,24 @@ client expects to launch servers.
|
|
|
832
937
|
| Breakpoints | `set_breakpoint(spec, condition?, hit_condition?)`, `remove_breakpoint(spec)`, `list_breakpoints()` |
|
|
833
938
|
| Differentiators | `threads(thread_id?)`, `tasks(task_name?)`, `processes(name_or_pid?)`, `wait_graph()` |
|
|
834
939
|
|
|
835
|
-
`control` is intentionally one tool that takes an action enum
|
|
940
|
+
`control` is intentionally one tool that takes an action enum. The six
|
|
836
941
|
underlying RPC actions share a return shape, and agents perform
|
|
837
942
|
measurably better with a small surface than with one tool per action.
|
|
838
943
|
`threads` / `tasks` / `processes` overload list-vs-inspect via a
|
|
839
944
|
single optional argument for the same reason.
|
|
840
945
|
|
|
946
|
+
`debug_launch` accepts optional `lang` and `adapter` parameters mirroring the
|
|
947
|
+
CLI's `--lang`/`--adapter`; when omitted, the language is auto-detected from
|
|
948
|
+
`program`, so an agent can hand it a compiled binary directly. The
|
|
949
|
+
`tasks`/`processes`/`wait_graph` tools stay registered for every language but
|
|
950
|
+
return a structured "not supported when debugging C/C++"-style error for
|
|
951
|
+
non-Python debuggees.
|
|
952
|
+
|
|
841
953
|
### Agent flow for a long-running step
|
|
842
954
|
|
|
843
955
|
```
|
|
844
956
|
agent → control(action="continue", timeout_s=30)
|
|
845
|
-
mcp → "still running
|
|
957
|
+
mcp → "still running, call pause or wait again"
|
|
846
958
|
agent → control(action="pause") # OR: control(action="wait_for_stop", timeout_s=30)
|
|
847
959
|
mcp → "<file>:<line>"
|
|
848
960
|
agent → inspect(["x", "len(buf)"])
|
|
@@ -851,7 +963,7 @@ mcp → "x = 7\nlen(buf) = 1024"
|
|
|
851
963
|
|
|
852
964
|
`pause` bypasses the dispatch lock so it can interrupt a `continue`
|
|
853
965
|
that's still mid-flight (HTTP and MCP share the same `NO_LOCK_ACTIONS`
|
|
854
|
-
policy
|
|
966
|
+
policy; see `tdb/server/app.py`).
|
|
855
967
|
|
|
856
968
|
### Security caveat
|
|
857
969
|
|
|
@@ -860,22 +972,23 @@ execution in the debuggee process**. This is inherent to a debugger and
|
|
|
860
972
|
not a tdb-specific concern, but MCP clients (and the humans running
|
|
861
973
|
them) should apply appropriate permission models: don't auto-approve
|
|
862
974
|
`inspect` against untrusted expressions, and don't expose `tdb-mcp` on
|
|
863
|
-
a network
|
|
975
|
+
a network (stdio transport only by design).
|
|
864
976
|
|
|
865
977
|
### Deferred / out of scope (v1)
|
|
866
978
|
|
|
867
|
-
- SSE-style event push
|
|
979
|
+
- SSE-style event push: `control` and `wait_for_stop` make polling
|
|
868
980
|
efficient enough; events would also need uneven MCP-client support.
|
|
869
|
-
- HTTP / streamable-HTTP transports
|
|
981
|
+
- HTTP / streamable-HTTP transports: would require auth (which the
|
|
870
982
|
HTTP RPC server also currently lacks); stdio inherits the trust of
|
|
871
983
|
the process that spawned it.
|
|
872
|
-
- Multi-session
|
|
984
|
+
- Multi-session: one debug session per MCP process.
|
|
873
985
|
|
|
874
986
|
## CLI Reference
|
|
875
987
|
|
|
876
988
|
```
|
|
877
989
|
usage: tdb [-h] [-v] [-r [HOST:]PORT] [--cwd CWD] [--no-stop-on-entry]
|
|
878
990
|
[--no-just-my-code] [--no-subprocess] [--python PYTHON] [--pv]
|
|
991
|
+
[--lang LANGUAGE] [--adapter ADAPTER]
|
|
879
992
|
[--keybindings {default,vim,emacs}]
|
|
880
993
|
[--terminal {xterm,konsole,gnome-terminal,ghostty,kitty,iterm2,warp,wezterm,terminator}]
|
|
881
994
|
[--local-root PATH] [--remote-root PATH]
|
|
@@ -891,8 +1004,10 @@ usage: tdb [-h] [-v] [-r [HOST:]PORT] [--cwd CWD] [--no-stop-on-entry]
|
|
|
891
1004
|
| `-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. |
|
|
892
1005
|
| `--no-stop-on-entry` | Do not pause at the first line (default: stop on entry; automatic when `-k` is given) |
|
|
893
1006
|
| `--cwd DIR` | Working directory for the debuggee |
|
|
894
|
-
| `--python PATH` | Python interpreter for the debuggee |
|
|
1007
|
+
| `--python PATH` | Python interpreter for the debuggee (Python targets only) |
|
|
895
1008
|
| `--pv` | Shorthand for --python .venv/bin/python |
|
|
1009
|
+
| `--lang LANGUAGE` | Debuggee language (`python`, `cpp`); default: auto-detect from the target |
|
|
1010
|
+
| `--adapter ADAPTER` | Debug adapter within the language (e.g. `--lang cpp --adapter lldb-dap`); default: the language's standard adapter |
|
|
896
1011
|
| `--no-just-my-code` | Step into stdlib/site-packages code instead of skipping it
|
|
897
1012
|
(default: skipped). On uncaught exceptions, the crash modal always shows the full traceback
|
|
898
1013
|
including library frames, regardless of this flag. |
|
|
@@ -912,9 +1027,14 @@ On Windows, it uses `%APPDATA%\tdb\`.
|
|
|
912
1027
|
|
|
913
1028
|
| File | Contents |
|
|
914
1029
|
|------|----------|
|
|
915
|
-
| `config.json` | User preferences (keybinding scheme, color theme, step mode) |
|
|
1030
|
+
| `config.json` | User preferences (keybinding scheme, color theme, step mode, adapter overrides) |
|
|
916
1031
|
| `breakpoints.json` | Breakpoints from previous sessions, keyed by project directory |
|
|
917
1032
|
|
|
1033
|
+
Adapter-related keys in `config.json`: `adapters` maps an adapter id to an
|
|
1034
|
+
executable path (`{"adapters": {"lldb-dap": "/opt/llvm/bin/lldb-dap"}}`), and
|
|
1035
|
+
`default_adapters` picks a language's default adapter
|
|
1036
|
+
(`{"default_adapters": {"cpp": "lldb-dap"}}`).
|
|
1037
|
+
|
|
918
1038
|
Breakpoints are saved on exit and restored when debugging a program in the same
|
|
919
1039
|
directory. Each project's breakpoints are independent.
|
|
920
1040
|
|
|
@@ -934,7 +1054,8 @@ fires as expected.
|
|
|
934
1054
|
## Tech Stack
|
|
935
1055
|
|
|
936
1056
|
- [textual](https://github.com/Textualize/textual) : TUI framework
|
|
937
|
-
- [debugpy](https://github.com/microsoft/debugpy) : Debug Adapter Protocol implementation
|
|
1057
|
+
- [debugpy](https://github.com/microsoft/debugpy) : Debug Adapter Protocol implementation for Python
|
|
1058
|
+
- [gdb](https://sourceware.org/gdb/) / [lldb-dap](https://lldb.llvm.org/resources/lldbdap.html) : optional, user-installed DAP adapters for C/C++
|
|
938
1059
|
- [pygments](https://pygments.org/) : Syntax highlighting
|
|
939
1060
|
- [FastAPI](https://fastapi.tiangolo.com/) + [uvicorn](https://www.uvicorn.org/) : JSON-RPC server
|
|
940
1061
|
|
|
@@ -1,12 +1,18 @@
|
|
|
1
1
|
# `textual-debugger`
|
|
2
2
|
|
|
3
3
|
`textual-debugger` (the package) provides `tdb` (the command-line tool and module),
|
|
4
|
-
a full-featured terminal-based Python
|
|
5
|
-
|
|
6
|
-
`
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
4
|
+
a full-featured terminal-based debugger for Python and other languages
|
|
5
|
+
with a Debug Adapter Protocol (DAP) implementation. C and C++ support (via
|
|
6
|
+
`gdb` or `lldb-dap`) is built in.
|
|
7
|
+
|
|
8
|
+
`tdb` is built with [textual](https://github.com/Textualize/textual) and speaks
|
|
9
|
+
DAP to a pluggable debug adapter: [debugpy](https://github.com/microsoft/debugpy)
|
|
10
|
+
(the engine behind VS Code's Python debugger) for Python,
|
|
11
|
+
[GDB's DAP mode](https://sourceware.org/gdb/current/onlinedocs/gdb.html/Debugger-Adapter-Protocol.html) or
|
|
12
|
+
[lldb-dap](https://lldb.llvm.org/resources/lldbdap.html)
|
|
13
|
+
for compiled code. It provides a rich interactive interface for stepping through
|
|
14
|
+
code, inspecting variables, managing breakpoints, and evaluating expressions in
|
|
15
|
+
complex programs.
|
|
10
16
|
|
|
11
17
|
- PyPI: https://pypi.org/project/textual-debugger/
|
|
12
18
|
- GitHub: https://github.com/AlDanial/tdb
|
|
@@ -17,6 +23,10 @@ MIT License. Copyright 2026 by Al Danial.
|
|
|
17
23
|
|
|
18
24
|
`tdb`:
|
|
19
25
|
|
|
26
|
+
- debugs multiple languages through the Debug Adapter Protocol: Python (via `debugpy`,
|
|
27
|
+
the richest feature set) and C/C++ (via `gdb -i dap` or `lldb-dap`), with the language
|
|
28
|
+
auto-detected from the target (ref. [Multi-Language Debugging](#multi-language-debugging)).
|
|
29
|
+
|
|
20
30
|
- supports debugging of synchronous, asynchronous, multi-threaded, and multi-process Python code.
|
|
21
31
|
It specifically supports modules
|
|
22
32
|
- `asyncio` (with a built-in async task inspector and task wait graph)
|
|
@@ -103,6 +113,16 @@ tdb my_program.py
|
|
|
103
113
|
# debug with arguments
|
|
104
114
|
tdb my_program.py arg1 arg2
|
|
105
115
|
|
|
116
|
+
# debug a C/C++ (or other native) executable built with -g. The ELF/Mach-O/PE
|
|
117
|
+
# binary is auto-detected and debugged through GDB's DAP mode (GDB >= 14)
|
|
118
|
+
tdb ./myprog arg1 arg2
|
|
119
|
+
|
|
120
|
+
# same, but using lldb-dap (LLVM >= 17) instead of gdb
|
|
121
|
+
tdb --adapter lldb-dap ./myprog
|
|
122
|
+
|
|
123
|
+
# force the language when auto-detection can't tell (e.g. an extensionless script)
|
|
124
|
+
tdb --lang python ./mytool
|
|
125
|
+
|
|
106
126
|
# add breakpoints at lines 20 and 35 of `my_program.py` and line 14
|
|
107
127
|
# of `module.py` (when -k is given, --no-stop-on-entry is set and the
|
|
108
128
|
# program runs to the first breakpoint)
|
|
@@ -144,6 +164,79 @@ Alternatively, use the module entry point:
|
|
|
144
164
|
python -m tdb my_program.py
|
|
145
165
|
```
|
|
146
166
|
|
|
167
|
+
## Multi-Language Debugging
|
|
168
|
+
|
|
169
|
+
`tdb` debugs any language that has a Debug Adapter Protocol backend. Two
|
|
170
|
+
languages are supported out of the box:
|
|
171
|
+
|
|
172
|
+
| Language | Adapter(s) | How to get the adapter | Feature level |
|
|
173
|
+
|----------|------------|------------------------|---------------|
|
|
174
|
+
| Python | `debugpy` (default) | installed with `textual-debugger` | everything in this README |
|
|
175
|
+
| 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 |
|
|
176
|
+
|
|
177
|
+
### Language detection and selection
|
|
178
|
+
|
|
179
|
+
The language is auto-detected from the debug target:
|
|
180
|
+
|
|
181
|
+
1. File extension: `.py` → Python.
|
|
182
|
+
2. Native executables (ELF, Mach-O, PE magic bytes) → C/C++.
|
|
183
|
+
3. A `#!...python` shebang → Python.
|
|
184
|
+
4. C/C++/Rust *source* files (`.c`, `.cpp`, `.rs`, …) produce an error with a
|
|
185
|
+
hint: compile with debug info (`g++ -g -O0`) and debug the binary.
|
|
186
|
+
5. Anything else produces an error naming the `--lang` override.
|
|
187
|
+
|
|
188
|
+
`--lang` forces the language; `--adapter` picks a non-default adapter within
|
|
189
|
+
it (`tdb --lang cpp --adapter lldb-dap ./myprog`).
|
|
190
|
+
|
|
191
|
+
> **Migration note:** extensionless Python scripts without a `python` shebang
|
|
192
|
+
> were previously assumed to be Python; they now require `--lang python`.
|
|
193
|
+
|
|
194
|
+
### Adapters are found on `PATH`
|
|
195
|
+
|
|
196
|
+
`tdb` does not download or bundle adapters. If the adapter executable isn't
|
|
197
|
+
found, the error names the package to install. To use an adapter from a
|
|
198
|
+
non-standard location, or change a language's default adapter, add to
|
|
199
|
+
`config.json` (see [Configuration](#configuration)):
|
|
200
|
+
|
|
201
|
+
```json
|
|
202
|
+
{
|
|
203
|
+
"adapters": {"lldb-dap": "/opt/llvm/bin/lldb-dap"},
|
|
204
|
+
"default_adapters": {"cpp": "lldb-dap"}
|
|
205
|
+
}
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
### What works for non-Python languages
|
|
209
|
+
|
|
210
|
+
Core debugging works identically for every language: breakpoints (incl.
|
|
211
|
+
conditions and persistence), stepping, continue/pause, run-to-cursor, stack
|
|
212
|
+
navigation, variable inspection, the evaluate console, syntax highlighting,
|
|
213
|
+
and the JSON-RPC / MCP programmatic modes.
|
|
214
|
+
|
|
215
|
+
Python-specific features are hidden or return a clear "not supported for this
|
|
216
|
+
language" message when debugging other languages: statement-granularity
|
|
217
|
+
stepping (non-Python languages always step per line), the async task /
|
|
218
|
+
process inspectors and wait graph, the evaluate console's trailing-`?` help,
|
|
219
|
+
remote attach (`-r`), `--python`/`--pv`, `--no-subprocess`,
|
|
220
|
+
automatic child-process attachment, and the post-mortem / `tdb.breakpoint()`
|
|
221
|
+
hooks (those hooks live inside Python programs by nature). `--terminal` is
|
|
222
|
+
currently ignored for non-Python targets.
|
|
223
|
+
|
|
224
|
+
### C/C++ tips
|
|
225
|
+
|
|
226
|
+
- Compile with `-g` (ideally `-g -O0`). If no breakpoint in a file can be
|
|
227
|
+
bound, `tdb` prints a console warning suggesting the program may lack
|
|
228
|
+
debug info.
|
|
229
|
+
- Stack frames pointing into system libraries often have no source on disk;
|
|
230
|
+
the Code View shows a `<Could not read …>` placeholder while the stack,
|
|
231
|
+
variables, and evaluate console remain fully usable.
|
|
232
|
+
- GDB (the default adapter) has the most complete libstdc++
|
|
233
|
+
pretty-printing. `lldb-dap` (via `--adapter lldb-dap`) also debugs
|
|
234
|
+
GCC-built binaries fine — DWARF is compiler-neutral.
|
|
235
|
+
- **GDB evaluate-console quirk:** GDB's DAP treats REPL input as CLI
|
|
236
|
+
commands, so evaluate expressions with an explicit `print`, e.g.
|
|
237
|
+
`print x` rather than bare `x` (bare `x` collides with GDB's
|
|
238
|
+
examine-memory command). `lldb-dap` evaluates bare expressions directly.
|
|
239
|
+
|
|
147
240
|
## Layout
|
|
148
241
|
|
|
149
242
|
```
|
|
@@ -172,7 +265,7 @@ The footer shows the most relevant keybindings for the current mode.
|
|
|
172
265
|
### Navigation and Keybindings
|
|
173
266
|
|
|
174
267
|
|
|
175
|
-
The Code View shows syntax-highlighted
|
|
268
|
+
The Code View shows syntax-highlighted source (lexer chosen per language) with line numbers.
|
|
176
269
|
A cursor line (blue) tracks your position; the current execution line is highlighted in gold.
|
|
177
270
|
|
|
178
271
|
**View focus shortcuts (global):**
|
|
@@ -264,6 +357,9 @@ lands on `print(results)`, not on each interior sub-line of the `gather` call. S
|
|
|
264
357
|
stops on each physical line--useful for inspecting how a complex expression is built up.
|
|
265
358
|
The choice is saved to `~/.config/tdb/config.json`.
|
|
266
359
|
|
|
360
|
+
Statement mode requires a source-language model and is currently Python-only;
|
|
361
|
+
other languages always step per line (the Step Mode menu says so if you try).
|
|
362
|
+
|
|
267
363
|
### Breakpoints
|
|
268
364
|
|
|
269
365
|
Click the gutter in the Code View to toggle a breakpoint, or press `b` in Debug mode.
|
|
@@ -321,6 +417,15 @@ interactive evaluation of expressions in the current scope:
|
|
|
321
417
|
|
|
322
418
|
Variable values set here are reflected in the running code.
|
|
323
419
|
|
|
420
|
+
### Cut / Paste
|
|
421
|
+
|
|
422
|
+
Expression for the Evaluate Console are often copied from the Code View.
|
|
423
|
+
Doing this in `tdb` differs from traditional terminal behavior, because `textual` applications
|
|
424
|
+
capture mouse events for their own use.
|
|
425
|
+
|
|
426
|
+
Instead, hold the `Shift` key while performing your conventional cut/paste keystrokes or mouse
|
|
427
|
+
operation to get the expected behavior.
|
|
428
|
+
|
|
324
429
|
### Console Output
|
|
325
430
|
|
|
326
431
|
The Console View captures stdout (normal text) and stderr (red text) from the debuggee
|
|
@@ -688,7 +793,7 @@ curl -s -X POST http://127.0.0.1:8150/rpc \
|
|
|
688
793
|
| `set_breakpoint` | `["file:line"]` or `["file:line", "condition", "hit_condition"]` | Set a breakpoint |
|
|
689
794
|
| `remove_breakpoint` | `["file:line"]` | Remove a breakpoint |
|
|
690
795
|
| `list_breakpoints` | `[]` | Show all breakpoints |
|
|
691
|
-
| `continue` | `[]` or `[timeout_s]` | Resume execution; on timeout returns `"still running
|
|
796
|
+
| `continue` | `[]` or `[timeout_s]` | Resume execution; on timeout returns `"still running--call pause or wait again"` (success) |
|
|
692
797
|
| `next` | `[]` or `[timeout_s]` | Step over |
|
|
693
798
|
| `step_in` | `[]` or `[timeout_s]` | Step into |
|
|
694
799
|
| `step_out` | `[]` or `[timeout_s]` | Step out |
|
|
@@ -727,7 +832,7 @@ Each is JSON with `event`, `data`, and `timestamp` fields.
|
|
|
727
832
|
tdb ships a Model Context Protocol (MCP) server (`tdb-mcp`) that exposes
|
|
728
833
|
the debugger as a curated set of tools an AI agent can call. The MCP
|
|
729
834
|
server is a third in-process consumer of the same dispatch handlers the
|
|
730
|
-
TUI and the HTTP server use
|
|
835
|
+
TUI and the HTTP server use so an agent gets the same lock semantics,
|
|
731
836
|
including the pause-during-continue bypass, and the same DAP-backed
|
|
732
837
|
inspection surface.
|
|
733
838
|
|
|
@@ -766,17 +871,24 @@ client expects to launch servers.
|
|
|
766
871
|
| Breakpoints | `set_breakpoint(spec, condition?, hit_condition?)`, `remove_breakpoint(spec)`, `list_breakpoints()` |
|
|
767
872
|
| Differentiators | `threads(thread_id?)`, `tasks(task_name?)`, `processes(name_or_pid?)`, `wait_graph()` |
|
|
768
873
|
|
|
769
|
-
`control` is intentionally one tool that takes an action enum
|
|
874
|
+
`control` is intentionally one tool that takes an action enum. The six
|
|
770
875
|
underlying RPC actions share a return shape, and agents perform
|
|
771
876
|
measurably better with a small surface than with one tool per action.
|
|
772
877
|
`threads` / `tasks` / `processes` overload list-vs-inspect via a
|
|
773
878
|
single optional argument for the same reason.
|
|
774
879
|
|
|
880
|
+
`debug_launch` accepts optional `lang` and `adapter` parameters mirroring the
|
|
881
|
+
CLI's `--lang`/`--adapter`; when omitted, the language is auto-detected from
|
|
882
|
+
`program`, so an agent can hand it a compiled binary directly. The
|
|
883
|
+
`tasks`/`processes`/`wait_graph` tools stay registered for every language but
|
|
884
|
+
return a structured "not supported when debugging C/C++"-style error for
|
|
885
|
+
non-Python debuggees.
|
|
886
|
+
|
|
775
887
|
### Agent flow for a long-running step
|
|
776
888
|
|
|
777
889
|
```
|
|
778
890
|
agent → control(action="continue", timeout_s=30)
|
|
779
|
-
mcp → "still running
|
|
891
|
+
mcp → "still running, call pause or wait again"
|
|
780
892
|
agent → control(action="pause") # OR: control(action="wait_for_stop", timeout_s=30)
|
|
781
893
|
mcp → "<file>:<line>"
|
|
782
894
|
agent → inspect(["x", "len(buf)"])
|
|
@@ -785,7 +897,7 @@ mcp → "x = 7\nlen(buf) = 1024"
|
|
|
785
897
|
|
|
786
898
|
`pause` bypasses the dispatch lock so it can interrupt a `continue`
|
|
787
899
|
that's still mid-flight (HTTP and MCP share the same `NO_LOCK_ACTIONS`
|
|
788
|
-
policy
|
|
900
|
+
policy; see `tdb/server/app.py`).
|
|
789
901
|
|
|
790
902
|
### Security caveat
|
|
791
903
|
|
|
@@ -794,22 +906,23 @@ execution in the debuggee process**. This is inherent to a debugger and
|
|
|
794
906
|
not a tdb-specific concern, but MCP clients (and the humans running
|
|
795
907
|
them) should apply appropriate permission models: don't auto-approve
|
|
796
908
|
`inspect` against untrusted expressions, and don't expose `tdb-mcp` on
|
|
797
|
-
a network
|
|
909
|
+
a network (stdio transport only by design).
|
|
798
910
|
|
|
799
911
|
### Deferred / out of scope (v1)
|
|
800
912
|
|
|
801
|
-
- SSE-style event push
|
|
913
|
+
- SSE-style event push: `control` and `wait_for_stop` make polling
|
|
802
914
|
efficient enough; events would also need uneven MCP-client support.
|
|
803
|
-
- HTTP / streamable-HTTP transports
|
|
915
|
+
- HTTP / streamable-HTTP transports: would require auth (which the
|
|
804
916
|
HTTP RPC server also currently lacks); stdio inherits the trust of
|
|
805
917
|
the process that spawned it.
|
|
806
|
-
- Multi-session
|
|
918
|
+
- Multi-session: one debug session per MCP process.
|
|
807
919
|
|
|
808
920
|
## CLI Reference
|
|
809
921
|
|
|
810
922
|
```
|
|
811
923
|
usage: tdb [-h] [-v] [-r [HOST:]PORT] [--cwd CWD] [--no-stop-on-entry]
|
|
812
924
|
[--no-just-my-code] [--no-subprocess] [--python PYTHON] [--pv]
|
|
925
|
+
[--lang LANGUAGE] [--adapter ADAPTER]
|
|
813
926
|
[--keybindings {default,vim,emacs}]
|
|
814
927
|
[--terminal {xterm,konsole,gnome-terminal,ghostty,kitty,iterm2,warp,wezterm,terminator}]
|
|
815
928
|
[--local-root PATH] [--remote-root PATH]
|
|
@@ -825,8 +938,10 @@ usage: tdb [-h] [-v] [-r [HOST:]PORT] [--cwd CWD] [--no-stop-on-entry]
|
|
|
825
938
|
| `-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. |
|
|
826
939
|
| `--no-stop-on-entry` | Do not pause at the first line (default: stop on entry; automatic when `-k` is given) |
|
|
827
940
|
| `--cwd DIR` | Working directory for the debuggee |
|
|
828
|
-
| `--python PATH` | Python interpreter for the debuggee |
|
|
941
|
+
| `--python PATH` | Python interpreter for the debuggee (Python targets only) |
|
|
829
942
|
| `--pv` | Shorthand for --python .venv/bin/python |
|
|
943
|
+
| `--lang LANGUAGE` | Debuggee language (`python`, `cpp`); default: auto-detect from the target |
|
|
944
|
+
| `--adapter ADAPTER` | Debug adapter within the language (e.g. `--lang cpp --adapter lldb-dap`); default: the language's standard adapter |
|
|
830
945
|
| `--no-just-my-code` | Step into stdlib/site-packages code instead of skipping it
|
|
831
946
|
(default: skipped). On uncaught exceptions, the crash modal always shows the full traceback
|
|
832
947
|
including library frames, regardless of this flag. |
|
|
@@ -846,9 +961,14 @@ On Windows, it uses `%APPDATA%\tdb\`.
|
|
|
846
961
|
|
|
847
962
|
| File | Contents |
|
|
848
963
|
|------|----------|
|
|
849
|
-
| `config.json` | User preferences (keybinding scheme, color theme, step mode) |
|
|
964
|
+
| `config.json` | User preferences (keybinding scheme, color theme, step mode, adapter overrides) |
|
|
850
965
|
| `breakpoints.json` | Breakpoints from previous sessions, keyed by project directory |
|
|
851
966
|
|
|
967
|
+
Adapter-related keys in `config.json`: `adapters` maps an adapter id to an
|
|
968
|
+
executable path (`{"adapters": {"lldb-dap": "/opt/llvm/bin/lldb-dap"}}`), and
|
|
969
|
+
`default_adapters` picks a language's default adapter
|
|
970
|
+
(`{"default_adapters": {"cpp": "lldb-dap"}}`).
|
|
971
|
+
|
|
852
972
|
Breakpoints are saved on exit and restored when debugging a program in the same
|
|
853
973
|
directory. Each project's breakpoints are independent.
|
|
854
974
|
|
|
@@ -868,7 +988,8 @@ fires as expected.
|
|
|
868
988
|
## Tech Stack
|
|
869
989
|
|
|
870
990
|
- [textual](https://github.com/Textualize/textual) : TUI framework
|
|
871
|
-
- [debugpy](https://github.com/microsoft/debugpy) : Debug Adapter Protocol implementation
|
|
991
|
+
- [debugpy](https://github.com/microsoft/debugpy) : Debug Adapter Protocol implementation for Python
|
|
992
|
+
- [gdb](https://sourceware.org/gdb/) / [lldb-dap](https://lldb.llvm.org/resources/lldbdap.html) : optional, user-installed DAP adapters for C/C++
|
|
872
993
|
- [pygments](https://pygments.org/) : Syntax highlighting
|
|
873
994
|
- [FastAPI](https://fastapi.tiangolo.com/) + [uvicorn](https://www.uvicorn.org/) : JSON-RPC server
|
|
874
995
|
|