dap

package
v1.22.1 Latest Latest
Warning

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

Go to latest
Published: Feb 21, 2024 License: MIT Imports: 33 Imported by: 2

Documentation

Overview

Package dap implements VSCode's Debug Adaptor Protocol (DAP). This allows delve to communicate with frontends using DAP without a separate adaptor. The frontend will run the debugger (which now doubles as an adaptor) in server mode listening on a port and communicating over TCP. This is work in progress, so for now Delve in dap mode only supports synchronous request-response communication, blocking while processing each request. For DAP details see https://microsoft.github.io/debug-adapter-protocol.

Index

Constants

View Source
const (
	UnsupportedCommand int = 9999
	InternalError      int = 8888
	NotYetImplemented  int = 7777

	FailedToLaunch             = 3000
	FailedToAttach             = 3001
	FailedToInitialize         = 3002
	UnableToSetBreakpoints     = 2002
	UnableToDisplayThreads     = 2003
	UnableToProduceStackTrace  = 2004
	UnableToListLocals         = 2005
	UnableToListArgs           = 2006
	UnableToListGlobals        = 2007
	UnableToLookupVariable     = 2008
	UnableToEvaluateExpression = 2009
	UnableToHalt               = 2010
	UnableToGetExceptionInfo   = 2011
	UnableToSetVariable        = 2012
	UnableToDisassemble        = 2013
	UnableToListRegisters      = 2014
	UnableToRunDlvCommand      = 2015

	NoDebugIsRunning  = 3000
	DebuggeeIsRunning = 4000
	DisconnectError   = 5000
)

Unique identifiers for messages returned for errors from requests. These values are not mandated by DAP (other than the uniqueness requirement), so each implementation is free to choose their own.

View Source
const BetterBadAccessError = `` /* 211-byte string literal not displayed */
View Source
const BetterNextWhileNextingError = `Unable to step while the previous step is interrupted by a breakpoint.
Use 'Continue' to resume the original step command.`

Variables

View Source
var DefaultLoadConfig = proc.LoadConfig{
	FollowPointers:     true,
	MaxVariableRecurse: 1,

	MaxStringLen:    512,
	MaxArrayValues:  64,
	MaxStructFields: -1,
}

DefaultLoadConfig controls how variables are loaded from the target's memory. These limits are conservative to minimize performance overhead for bulk loading. With dlv-dap, users do not have a way to adjust these. Instead, we are focusing in interactive loading with nested reloads, array/map paging and context-specific string limits.

Functions

This section is empty.

Types

type AttachConfig added in v1.7.2

type AttachConfig struct {
	// Acceptable values are:
	//   "local": attaches to the local process with the given ProcessID.
	//   "remote": expects the debugger to already be running to "attach" to an in-progress debug session.
	//
	// Default is "local".
	Mode string `json:"mode"`

	// The numeric ID of the process to be debugged.
	ProcessID int `json:"processId,omitempty"`

	// Wait for a process with a name beginning with this prefix.
	AttachWaitFor string `json:"waitFor,omitempty"`

	LaunchAttachCommonConfig
}

AttachConfig is the collection of attach request attributes recognized by DAP implementation. 'processId' and 'waitFor' are mutually exclusive, and can't be specified at the same time.

type BuildFlags added in v1.21.1

type BuildFlags struct {
	// contains filtered or unexported fields
}

BuildFlags is either string or []string.

func (*BuildFlags) UnmarshalJSON added in v1.21.1

func (s *BuildFlags) UnmarshalJSON(b []byte) error

type Config added in v1.7.3

type Config struct {
	*service.Config

	// StopTriggered is closed when the server is Stop()-ed.
	// Can be used to safeguard against duplicate shutdown sequences.
	StopTriggered chan struct{}
	// contains filtered or unexported fields
}

Config is all the information needed to start the debugger, handle DAP connection traffic and signal to the server when it is time to stop.

type LaunchAttachCommonConfig added in v1.7.2

type LaunchAttachCommonConfig struct {
	// Automatically stop program after launch or attach.
	StopOnEntry bool `json:"stopOnEntry,omitempty"`

	// Backend used for debugging. See `dlv backend` for allowed values.
	// Default is "default".
	Backend string `json:"backend,omitempty"`

	// Maximum depth of stack trace to return.
	// Default is 50.
	StackTraceDepth int `json:"stackTraceDepth,omitempty"`

	// Boolean value to indicate whether global package variables
	// should be shown in the variables pane or not.
	ShowGlobalVariables bool `json:"showGlobalVariables,omitempty"`

	// Boolean value to indicate whether registers should be shown
	// in the variables pane or not.
	ShowRegisters bool `json:"showRegisters,omitempty"`

	// Boolean value to indicate whether system goroutines
	// should be hidden from the call stack view.
	HideSystemGoroutines bool `json:"hideSystemGoroutines,omitempty"`

	// String value to indicate which system goroutines should be
	// shown in the call stack view. See filtering documentation:
	// https://github.com/go-delve/delve/blob/master/Documentation/cli/README.md#goroutines
	GoroutineFilters string `json:"goroutineFilters,omitempty"`

	// Array of string values indicating the keys of pprof labels to show as a
	// goroutine name in the threads view. If the array has one element, only
	// that label's value will be shown; otherwise, each of the labels will be
	// shown as "key:value". To show all labels, specify the single element "*".
	ShowPprofLabels []string `json:"showPprofLabels,omitempty"`

	// An array of mappings from a local path (client) to the remote path (debugger).
	// This setting is useful when working in a file system with symbolic links,
	// running remote debugging, or debugging an executable compiled externally.
	// The debug adapter will replace the local path with the remote path in all of the calls.
	// See also Documentation/cli/substitutepath.md.
	SubstitutePath []SubstitutePath `json:"substitutePath,omitempty"`
}

LaunchAttachCommonConfig is the attributes common in both launch/attach requests.

type LaunchConfig added in v1.7.2

type LaunchConfig struct {
	// Acceptable values are:
	//   "debug": compiles your program with optimizations disabled, starts and attaches to it.
	//   "test": compiles your unit test program with optimizations disabled, starts and attaches to it.
	//   "exec": executes a precompiled binary and begins a debug session.
	//   "replay": replays an rr trace.
	//   "core": examines a core dump.
	//
	// Default is "debug".
	Mode string `json:"mode,omitempty"`

	// Path to the program folder (or any go file within that folder)
	// when in `debug` or `test` mode, and to the pre-built binary file
	// to debug in `exec` mode.
	// If it is not an absolute path, it will be interpreted as a path
	// relative to Delve's working directory.
	// Required when mode is `debug`, `test`, `exec`, and `core`.
	Program string `json:"program,omitempty"`

	// Command line arguments passed to the debugged program.
	// Relative paths used in Args will be interpreted as paths relative
	// to `cwd`.
	Args []string `json:"args,omitempty"`

	// Working directory of the program being debugged.
	// If a relative path is provided, it will be interpreted as
	// a relative path to Delve's working directory. This is
	// similar to `dlv --wd` flag.
	//
	// If not specified or empty, Delve's working directory is
	// used by default. But for `test` mode, Delve tries to find
	// the test's package source directory and run tests from there.
	// This matches the behavior of `dlv test` and `go test`.
	Cwd string `json:"cwd,omitempty"`

	// Build flags, to be passed to the Go compiler.
	// Relative paths used in BuildFlags will be interpreted as paths
	// relative to Delve's current working directory.
	//
	// It should be a string like `dlv --build-flags`, or
	// an array of strings that is augmented when invoking the go build or
	// test command through os/exec.Command API.
	// For example, both forms are acceptable.
	//    "buildFlags": "-tags=integration -ldflags='-X main.Hello=World'"
	// or
	//    "buildFlags": ["-tags=integration", "-ldflags=-X main.Hello=World"]
	// Using other types is an error.
	BuildFlags BuildFlags `json:"buildFlags,omitempty"`

	// Output path for the binary of the debuggee.
	// Relative path is interpreted as the path relative to
	// the Delve's current working directory.
	// This is deleted after the debug session ends.
	Output string `json:"output,omitempty"`

	// NoDebug is used to run the program without debugging.
	NoDebug bool `json:"noDebug,omitempty"`

	// TraceDirPath is the trace directory path for replay mode.
	// Relative path is interpreted as a path relative to Delve's
	// current working directory.
	// This is required for "replay" mode but unused in other modes.
	TraceDirPath string `json:"traceDirPath,omitempty"`

	// CoreFilePath is the core file path for core mode.
	//
	// This is required for "core" mode but unused in other modes.
	CoreFilePath string `json:"coreFilePath,omitempty"`

	// DlvCwd is the new working directory for Delve server.
	// If specified, the server will change its working
	// directory to the specified directory using os.Chdir.
	// Any other launch attributes with relative paths interpreted
	// using Delve's working directory will use this new directory.
	// When Delve needs to build the program (in debug/test modes),
	// it will run the go command from this directory as well.
	//
	// If a relative path is provided as DlvCwd, it will be
	// interpreted as a path relative to Delve's current working
	// directory.
	DlvCwd string `json:"dlvCwd,omitempty"`

	// Env specifies optional environment variables for Delve server
	// in addition to the environment variables Delve initially
	// started with.
	// Variables with 'nil' values can be used to unset the named
	// environment variables.
	// Values are interpreted verbatim. Variable substitution or
	// reference to other environment variables is not supported.
	Env map[string]*string `json:"env,omitempty"`

	// The output mode specifies how to handle the program's output.
	OutputMode string `json:"outputMode,omitempty"`

	LaunchAttachCommonConfig
}

LaunchConfig is the collection of launch request attributes recognized by DAP implementation.

type Server

type Server struct {
	// contains filtered or unexported fields
}

Server implements a DAP server that can accept a single client for a single debug session (for now). It does not yet support restarting. That means that in addition to explicit shutdown requests, program termination and failed or closed client connection would also result in stopping this single-use server.

The DAP server operates via the following goroutines:

(1) Main goroutine where the server is created via NewServer(), started via Run() and stopped via Stop(). Once the server is started, this goroutine blocks until it receives a stop-server signal that can come from an OS interrupt (such as Ctrl-C) or config.DisconnectChan (passed to NewServer()) as a result of client connection failure or closure or a DAP disconnect request.

(2) Run goroutine started from Run() that serves as both a listener and a client goroutine. It accepts a client connection, reads, decodes and dispatches each request from the client. For synchronous requests, it issues commands to the underlying debugger and sends back events and responses. These requests block while the debuggee is running, so, where applicable, the handlers need to check if debugging state is running, so there is a need for a halt request or a dummy/error response to avoid blocking.

This is the only goroutine that sends a stop-server signal via config.DisconnectChan when encountering a client connection error or responding to a (synchronous) DAP disconnect request. Once stop is triggered, the goroutine exits.

Unlike rpccommon, there is not another layer of per-client goroutines here because the dap server does not support multiple clients.

(3) Per-request goroutine is started for each asynchronous request that resumes execution. We check if target is running already, so there should be no more than one pending asynchronous request at a time. This goroutine issues commands to the underlying debugger and sends back events and responses. It takes a setup-done channel as an argument and temporarily blocks the request loop until setup for asynchronous execution is complete and target is running. Once done, it unblocks processing of parallel requests unblocks (e.g. disconnecting while the program is running).

These per-request goroutines never send a stop-server signal. They block on running debugger commands that are interrupted when halt is issued while stopping. At that point these goroutines wrap-up and exit.

func NewServer

func NewServer(config *service.Config) *Server

NewServer creates a new DAP Server. It takes an opened Listener via config and assumes its ownership. config.DisconnectChan has to be set; it will be closed by the server when the client fails to connect, disconnects or requests shutdown. Once config.DisconnectChan is closed, Server.Stop() must be called to shutdown this single-user server.

NewServer can be used to create a special DAP Server that works only with a predetermined client. In that case, config.Listener is nil and its RunWithClient must be used instead of Run.

func (*Server) Run

func (s *Server) Run()

Run launches a new goroutine where it accepts a client connection and starts processing requests from it. Use Stop() to close connection. The server does not support multiple clients, serially or in parallel. The server should be restarted for every new debug session. The debugger won't be started until launch/attach request is received. TODO(polina): allow new client connections for new debug sessions, so the editor needs to launch dap server only once? Note that some requests may change the server's environment (e.g. see dlvCwd of launch configuration). So if we want to reuse this server for multiple independent debugging sessions we need to take that into consideration.

func (*Server) RunWithClient added in v1.7.3

func (s *Server) RunWithClient(conn net.Conn)

RunWithClient is similar to Run but works only with an already established connection instead of waiting on the listener to accept a new client. RunWithClient takes ownership of conn. Debugger won't be started until a launch/attach request is received over the connection.

func (*Server) Stop

func (s *Server) Stop()

Stop stops the DAP debugger service, closes the listener and the client connection. It shuts down the underlying debugger and kills the target process if it was launched by it or stops the noDebug process. This method mustn't be called more than once. StopTriggered notifies other goroutines that stop is in progress.

type Session added in v1.7.3

type Session struct {
	// contains filtered or unexported fields
}

Session is an abstraction for serving and shutting down a DAP debug session with a pre-connected client. TODO(polina): move this to a different file/package

func NewSession added in v1.7.3

func NewSession(conn io.ReadWriteCloser, config *Config, debugger *debugger.Debugger) *Session

NewSession creates a new client session that can handle DAP traffic. It takes an open connection and provides a Close() method to shut it down when the DAP session disconnects or a connection error occurs.

func (*Session) Close added in v1.7.3

func (s *Session) Close()

Close closes the underlying debugger/process and connection. May be called more than once.

func (*Session) ServeDAPCodec added in v1.7.3

func (s *Session) ServeDAPCodec()

ServeDAPCodec reads and decodes requests from the client until it encounters an error or EOF, when it sends a disconnect signal and returns.

type SubstitutePath added in v1.7.2

type SubstitutePath struct {
	// The local path to be replaced when passing paths to the debugger.
	From string `json:"from,omitempty"`
	// The remote path to be replaced when passing paths back to the client.
	To string `json:"to,omitempty"`
}

SubstitutePath defines a mapping from a local path to the remote path. Both 'from' and 'to' must be specified and non-null. Empty values can be used to add or remove absolute path prefixes when mapping. For example, mapping with empty 'to' can be used to work with binaries with trimmed paths.

func (*SubstitutePath) UnmarshalJSON added in v1.7.2

func (m *SubstitutePath) UnmarshalJSON(data []byte) error

Directories

Path Synopsis
Package daptest provides a sample client with utilities for DAP mode testing.
Package daptest provides a sample client with utilities for DAP mode testing.
gen
Binary gen generates service/dap/daptest/responses.go.
Binary gen generates service/dap/daptest/responses.go.

Jump to

Keyboard shortcuts

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