Documentation
¶
Overview ¶
Package debug wraps a Delve debugger so forge can drive a debugging session from the CLI / MCP layers.
The package exposes two complementary surfaces:
DelveDebugger — the rich per-session control surface (breakpoints, execution control, inspection, lifecycle). One implementation today (Delve via rpc2), so callers hold the concrete *DelveDebugger rather than a single-impl interface. Constructed via NewDelveDebugger; callers hold the handle for the duration of a session.
Service — the package's behavioral seam: load, save, and clear the persisted SessionInfo on disk. Tests intercept the on-disk session file by injecting a mock Service.
The data carriers (SessionInfo, StopState, Variable, BreakpointInfo, StackFrame, GoroutineInfo) remain plain types — they are not behavior to mock.
Code generated by forge. DO NOT EDIT. forge:hash=5215c89baa6fc4776dbe8dc62d9ba7bbfb26f238611507058bf6ddb71e26332a forge-owned: regenerated every run — do not edit (forge disown to take ownership) Source: contract.go in this package.
To customize: edit contract.go (the interface IS the public surface) and re-run "forge generate". This file is regenerated unconditionally.
Index ¶
- type BreakpointInfo
- type DelveDebugger
- func (d *DelveDebugger) Addr() string
- func (d *DelveDebugger) Args() ([]Variable, error)
- func (d *DelveDebugger) ClearBreakpoint(id int) error
- func (d *DelveDebugger) Connect(addr string) error
- func (d *DelveDebugger) Continue() (*StopState, error)
- func (d *DelveDebugger) Disconnect()
- func (d *DelveDebugger) DlvPID() int
- func (d *DelveDebugger) Eval(expr string) (*Variable, error)
- func (d *DelveDebugger) Goroutines() ([]GoroutineInfo, error)
- func (d *DelveDebugger) ListBreakpoints() ([]BreakpointInfo, error)
- func (d *DelveDebugger) Locals() ([]Variable, error)
- func (d *DelveDebugger) PID() int
- func (d *DelveDebugger) SetBreakpoint(file string, line int, condition string) (*BreakpointInfo, error)
- func (d *DelveDebugger) SetFunctionBreakpoint(funcName string, condition string) (*BreakpointInfo, error)
- func (d *DelveDebugger) Stacktrace(depth int) ([]StackFrame, error)
- func (d *DelveDebugger) Start(ctx context.Context, binary string, args []string, listenPort int) error
- func (d *DelveDebugger) StartAttach(ctx context.Context, pid int) error
- func (d *DelveDebugger) StartWithEnv(ctx context.Context, binary string, args []string, extraEnv []string, ...) error
- func (d *DelveDebugger) StepInto() (*StopState, error)
- func (d *DelveDebugger) StepOut() (*StopState, error)
- func (d *DelveDebugger) StepOver() (*StopState, error)
- func (d *DelveDebugger) Stop() error
- type Deps
- type GoroutineInfo
- type MockService
- type Service
- type SessionInfo
- type StackFrame
- type StopState
- type Variable
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type BreakpointInfo ¶
type BreakpointInfo struct {
ID int `json:"id"`
File string `json:"file"`
Line int `json:"line"`
FunctionName string `json:"function_name,omitempty"`
Condition string `json:"condition,omitempty"`
HitCount uint64 `json:"hit_count"`
}
BreakpointInfo describes a breakpoint.
type DelveDebugger ¶
type DelveDebugger struct {
// contains filtered or unexported fields
}
DelveDebugger drives a running Delve server via its rpc2 client. It is the package's concrete debugger control surface (breakpoints, execution control, inspection, lifecycle); one implementation today, so callers hold the concrete *DelveDebugger rather than a single-impl interface.
func NewDelveDebugger ¶
func NewDelveDebugger() *DelveDebugger
NewDelveDebugger returns a new, unconnected DelveDebugger.
func (*DelveDebugger) Addr ¶
func (d *DelveDebugger) Addr() string
Addr returns the listen address of the Delve server.
func (*DelveDebugger) Args ¶
func (d *DelveDebugger) Args() ([]Variable, error)
Args returns the function arguments of the current stack frame.
func (*DelveDebugger) ClearBreakpoint ¶
func (d *DelveDebugger) ClearBreakpoint(id int) error
ClearBreakpoint removes the breakpoint with the given ID.
func (*DelveDebugger) Connect ¶
func (d *DelveDebugger) Connect(addr string) error
Connect connects to an already-running Delve instance at addr. It applies a timeout so the caller isn't blocked indefinitely when Delve's RPC handler is stuck (e.g. due to stale CLOSE_WAIT connections).
func (*DelveDebugger) Continue ¶
func (d *DelveDebugger) Continue() (*StopState, error)
Continue resumes execution until the next breakpoint or program exit.
func (*DelveDebugger) Disconnect ¶
func (d *DelveDebugger) Disconnect()
Disconnect closes the RPC connection without killing the debugee.
func (*DelveDebugger) DlvPID ¶
func (d *DelveDebugger) DlvPID() int
DlvPID returns the PID of the dlv server process forge spawned, or 0 when this debugger merely connected to an existing dlv. Tracked so `stop` can reap the dlv server even after the session has been reconnected from disk.
func (*DelveDebugger) Eval ¶
func (d *DelveDebugger) Eval(expr string) (*Variable, error)
Eval evaluates an expression in the current goroutine's scope.
func (*DelveDebugger) Goroutines ¶
func (d *DelveDebugger) Goroutines() ([]GoroutineInfo, error)
Goroutines lists every goroutine known to the debugger.
func (*DelveDebugger) ListBreakpoints ¶
func (d *DelveDebugger) ListBreakpoints() ([]BreakpointInfo, error)
ListBreakpoints returns every breakpoint currently set in the debugger.
func (*DelveDebugger) Locals ¶
func (d *DelveDebugger) Locals() ([]Variable, error)
Locals returns the local variables of the current stack frame.
func (*DelveDebugger) PID ¶
func (d *DelveDebugger) PID() int
PID returns the PID of the debugged (target) process.
func (*DelveDebugger) SetBreakpoint ¶
func (d *DelveDebugger) SetBreakpoint(file string, line int, condition string) (*BreakpointInfo, error)
SetBreakpoint sets a source-line breakpoint with an optional condition.
func (*DelveDebugger) SetFunctionBreakpoint ¶
func (d *DelveDebugger) SetFunctionBreakpoint(funcName string, condition string) (*BreakpointInfo, error)
SetFunctionBreakpoint sets a breakpoint on a function entry by name.
func (*DelveDebugger) Stacktrace ¶
func (d *DelveDebugger) Stacktrace(depth int) ([]StackFrame, error)
Stacktrace returns up to depth stack frames for the current goroutine.
func (*DelveDebugger) Start ¶
func (d *DelveDebugger) Start(ctx context.Context, binary string, args []string, listenPort int) error
Start launches dlv exec in headless mode for the given binary and connects. If listenPort > 0, it is used as the debugger listen port; otherwise a free port is chosen.
func (*DelveDebugger) StartAttach ¶
func (d *DelveDebugger) StartAttach(ctx context.Context, pid int) error
StartAttach launches dlv attach in headless mode for the given PID.
func (*DelveDebugger) StartWithEnv ¶
func (d *DelveDebugger) StartWithEnv(ctx context.Context, binary string, args []string, extraEnv []string, listenPort int) error
StartWithEnv is Start with extra environment variables layered onto the debugged process's environment (os.Environ() + extraEnv, extraEnv wins). Used to inject the SERVICE_NAME / PORT a forge service binary needs to actually serve.
func (*DelveDebugger) StepInto ¶
func (d *DelveDebugger) StepInto() (*StopState, error)
StepInto steps into the call on the current line.
func (*DelveDebugger) StepOut ¶
func (d *DelveDebugger) StepOut() (*StopState, error)
StepOut runs until the current function returns.
func (*DelveDebugger) StepOver ¶
func (d *DelveDebugger) StepOver() (*StopState, error)
StepOver advances to the next source line in the current function.
func (*DelveDebugger) Stop ¶
func (d *DelveDebugger) Stop() error
Stop detaches and kills the debugger process.
type Deps ¶
type Deps struct{}
Deps is the dependency set for the debug Service. Empty today — Delve is invoked via process exec / rpc2 and needs no injected collaborators.
type GoroutineInfo ¶
type GoroutineInfo struct {
ID int64 `json:"id"`
Status string `json:"status"`
Function string `json:"function"`
CurrentFile string `json:"current_file"`
CurrentLine int `json:"current_line"`
}
GoroutineInfo describes a goroutine.
type MockService ¶
type MockService struct {
contractkit.Recorder
LoadSessionFunc func(string) (*SessionInfo, error)
SaveSessionFunc func(string, *SessionInfo) error
ClearSessionFunc func(string) error
}
MockService is a test mock for the Service interface.
The embedded contractkit.Recorder records every call so tests can assert call counts and captured arguments. Set XxxFunc fields to override per-method behaviour; unset methods return the canonical "MockService.<Method>Func not set" error.
func (*MockService) ClearSession ¶
func (m *MockService) ClearSession(dir string) error
func (*MockService) LoadSession ¶
func (m *MockService) LoadSession(dir string) (*SessionInfo, error)
func (*MockService) SaveSession ¶
func (m *MockService) SaveSession(dir string, session *SessionInfo) error
type Service ¶
type Service interface {
// LoadSession reads .forge/debug-session.json from dir. Returns
// (nil, nil) when no session file exists.
LoadSession(dir string) (*SessionInfo, error)
// SaveSession writes session to dir/.forge/debug-session.json.
SaveSession(dir string, session *SessionInfo) error
// ClearSession removes the session file from dir.
ClearSession(dir string) error
}
Service is the behavioral surface of the debug package.
Session helpers (Load/Save/Clear) hang off this interface so tests can intercept the on-disk session file without touching the filesystem.
type SessionInfo ¶
type SessionInfo struct {
Type string `json:"type"` // "delve"
Addr string `json:"addr"` // e.g. "127.0.0.1:2345"
PID int `json:"pid"` // debugged (target) process PID
DlvPID int `json:"dlv_pid"` // the dlv server process PID forge spawned (0 if unknown)
Binary string `json:"binary"` // binary path or service name
TmpDir string `json:"tmp_dir"` // temp build directory for cleanup
Docker bool `json:"docker"` // true if session is running in a Docker container
// Owned reports whether forge launched the target process itself
// (`forge debug start <service>` / `--docker`). When false the session
// is an ATTACH (`forge debug --attach <pid>`) onto a process forge does
// not own: `stop` MUST detach the debugger and leave the target alive.
// Killing an attached target is a data-loss-class bug — it terminated a
// live admin-server in the field.
Owned bool `json:"owned"`
Started time.Time `json:"started"`
}
SessionInfo is persisted to .forge/debug-session.json so subsequent debug commands can reconnect to the same debugger.
type StackFrame ¶
type StackFrame struct {
Function string `json:"function"`
File string `json:"file"`
Line int `json:"line"`
Args []Variable `json:"args,omitempty"`
Locals []Variable `json:"locals,omitempty"`
}
StackFrame describes one frame in a stack trace.
type StopState ¶
type StopState struct {
File string `json:"file"`
Line int `json:"line"`
Function string `json:"function"`
Reason string `json:"reason"` // "breakpoint", "step", "next", etc.
GoroutineID int64 `json:"goroutine_id"`
Args []Variable `json:"args,omitempty"`
Locals []Variable `json:"locals,omitempty"`
}
StopState describes where the debugger stopped after a continue/step.