Help us shape the future of Go! Take the 2026 Go Developer Survey

debug

package
v1.0.7 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 30, 2026 License: Apache-2.0 Imports: 16 Imported by: 0

Documentation

Overview

Package debug wraps a Delve debugger so forge can drive a debugging session from the CLI layer.

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=eec1e5178ec2ca29b91c1fd3e567f2c5e62dfb8fd3ddf5214bcef657068a0a0d forge-owned: regenerated every run — do not edit (forge project 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

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 OTEL_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

ClearSession records the call and delegates to ClearSessionFunc when set.

func (*MockService) LoadSession

func (m *MockService) LoadSession(dir string) (*SessionInfo, error)

LoadSession records the call and delegates to LoadSessionFunc when set.

func (*MockService) SaveSession

func (m *MockService) SaveSession(dir string, session *SessionInfo) error

SaveSession records the call and delegates to SaveSessionFunc when set.

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.

func New

func New(_ Deps) Service

New constructs a debug.Service.

forge:no-observe Pure compute: empty Deps; reads and writes the local debug-session file. No injected collaborator to trace through.

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.

type Variable

type Variable struct {
	Name     string     `json:"name"`
	Type     string     `json:"type"`
	Value    string     `json:"value"`
	Children []Variable `json:"children,omitempty"`
}

Variable represents an inspectable variable with optional children.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL