Background
GhostScope is most useful when diagnosing live production services. On a test or staging machine, adding temporary logs, rebuilding, and switching versions is often acceptable. In production, that workflow is disruptive, which is exactly the gap GhostScope tries to fill.
Today, GhostScope eagerly parses DWARF data during startup. For large targets this can dominate startup time and create an uncomfortable production experience: the user asks for one trace point, but the tool first spends noticeable time and CPU loading and indexing debug information.
This is especially noticeable when attaching to an already-running service where the operational expectation is: attach quickly, observe, detach.
Problem
The current startup path couples expensive DWARF/script preparation with "start tracing now". That makes the first attach expensive even when the script and target are known ahead of time.
We should support a workflow that either moves expensive preparation out of the production attach path, or keeps the expensive state warm across multiple attach requests.
Possible Direction A: prepared bundle mode
Add a CLI prepare mode that compiles a trace script into a reusable artifact before production attach:
ghostscope prepare -t /path/to/binary --script-file trace.gs -o trace.gsb
sudo ghostscope run-bundle trace.gsb -p <pid>
The prepare step should be explicitly non-privileged:
- no root requirement
- no eBPF capabilities required
- no BPF program load
- no uprobe attach
- no sysmon startup
- no bpffs pinned-map writes
It should only parse DWARF, resolve trace targets, compile scripts, and write a trace artifact.
The bundle should contain probe-level artifacts needed for fast attach, such as:
- target identity / compatibility metadata
- original script or script hash
- relevant compile options snapshot
- per-trace attach plan
- eBPF object bytes
- eBPF program name
- trace ID metadata
TraceContext needed to parse event output
Backtrace support should be handled separately. The bundle should not become a large dump of runtime module state.
Possible Direction B: remote / daemon mode
Add a long-running GhostScope service, similar in spirit to GDB remote workflows:
ghostscoped
ghostscope remote attach -p <pid> --script-file trace.gs
ghostscope remote detach <trace-id>
ghostscope remote status
The service could keep DWARF indexes, CFI data, symbolization data, module mappings, and other runtime state warm across multiple operations. This is likely the cleaner long-term path for repeated or interactive production diagnostics.
Backtrace considerations
bt / backtrace has at least two runtime dependencies beyond the trace bundle itself:
- CFI / unwind rows, which must be available before attach if the probe can hit immediately.
- Symbolization data, which maps frame IPs or module-relative PCs back to function names, inline frames, and source locations.
These should likely be modeled as module-level providers/caches instead of being embedded directly in the trace bundle:
RuntimeModuleResolver: runtime IP -> module path/cookie + module-relative PC, based on /proc/<pid>/maps and map-change events.
CfiProvider: module identity -> compact unwind rows for eBPF unwinding.
SymbolProvider: module identity + PC -> function/source/inline display metadata.
Bundle mode can depend on these providers, but should not own their lifecycle. Remote mode can keep them warm and update them when modules are mapped or unmapped.
Suggested initial scope
A reasonable first milestone could be:
- Implement
prepare / run-bundle for CLI mode.
- Make
prepare explicitly non-privileged.
- Initially support scripts that do not use
bt / backtrace.
- Fail clearly if bundle preparation sees unsupported backtrace usage.
- Measure startup time saved by skipping DWARF parsing and LLVM codegen in
run-bundle.
Later milestones:
- Add module-level CFI cache/provider.
- Add module-level symbolization cache/provider.
- Enable bundle mode for backtrace when required module metadata is available.
- Add remote/daemon mode that owns warm DWARF/CFI/symbol/module state.
Acceptance criteria
- Users can prepare a trace artifact without root privileges.
- Users can attach from a prepared artifact with substantially lower startup cost than normal script mode.
- The fast path does not silently fall back to full DWARF parsing unless an explicit configuration permits that behavior.
- Backtrace limitations are documented and reported clearly.
- Existing normal CLI/TUI workflows keep their current behavior.
Background
GhostScope is most useful when diagnosing live production services. On a test or staging machine, adding temporary logs, rebuilding, and switching versions is often acceptable. In production, that workflow is disruptive, which is exactly the gap GhostScope tries to fill.
Today, GhostScope eagerly parses DWARF data during startup. For large targets this can dominate startup time and create an uncomfortable production experience: the user asks for one trace point, but the tool first spends noticeable time and CPU loading and indexing debug information.
This is especially noticeable when attaching to an already-running service where the operational expectation is: attach quickly, observe, detach.
Problem
The current startup path couples expensive DWARF/script preparation with "start tracing now". That makes the first attach expensive even when the script and target are known ahead of time.
We should support a workflow that either moves expensive preparation out of the production attach path, or keeps the expensive state warm across multiple attach requests.
Possible Direction A: prepared bundle mode
Add a CLI prepare mode that compiles a trace script into a reusable artifact before production attach:
The prepare step should be explicitly non-privileged:
It should only parse DWARF, resolve trace targets, compile scripts, and write a trace artifact.
The bundle should contain probe-level artifacts needed for fast attach, such as:
TraceContextneeded to parse event outputBacktrace support should be handled separately. The bundle should not become a large dump of runtime module state.
Possible Direction B: remote / daemon mode
Add a long-running GhostScope service, similar in spirit to GDB remote workflows:
The service could keep DWARF indexes, CFI data, symbolization data, module mappings, and other runtime state warm across multiple operations. This is likely the cleaner long-term path for repeated or interactive production diagnostics.
Backtrace considerations
bt/backtracehas at least two runtime dependencies beyond the trace bundle itself:These should likely be modeled as module-level providers/caches instead of being embedded directly in the trace bundle:
RuntimeModuleResolver: runtime IP -> module path/cookie + module-relative PC, based on/proc/<pid>/mapsand map-change events.CfiProvider: module identity -> compact unwind rows for eBPF unwinding.SymbolProvider: module identity + PC -> function/source/inline display metadata.Bundle mode can depend on these providers, but should not own their lifecycle. Remote mode can keep them warm and update them when modules are mapped or unmapped.
Suggested initial scope
A reasonable first milestone could be:
prepare/run-bundlefor CLI mode.prepareexplicitly non-privileged.bt/backtrace.run-bundle.Later milestones:
Acceptance criteria