debugger: share renderer between gdb/lldb, add jl path command, cap output
Factor the value-rendering logic out of julia_gdb.py and julia_lldb.py
into a shared, debugger-agnostic julia_debug_core.py; the two scripts
are now thin adapters (memory reads and debug-info lookups) plus
debugger-specific integration, so the rendering can no longer drift
between the two.
Add Julia-semantics field/index access, since the C expression
evaluator cannot look through jl_value_t*:
- a `jl` command in both debuggers: `jl v.inner.name`, `jl v.vec[2]`,
`jl v.tup.1` (1-based indexing), plus module globals resolved through
the binding table and its partitions (`jl Base.have_fma`); `$jl`
continues from the previous result, which also works through structs
stored inline in their parent
- gdb convenience functions `$jl_typeof(v)` and `$jl_field(v, "name")`
that compose inside larger expressions, returning jl_value_t* for
boxed fields and native typed values for unboxed primitives
Also cap the total size of any rendered summary (MAX_OUTPUT, on top of
the existing element/string/depth caps) so printing a huge array or
string cannot flood the terminal, and fix non-function singletons to
render as e.g. `Base.Irrational{:π}()` instead of a bare type name.
Assisted-by: Claude Code (Fable 5)