types.go 16.8 KB
Newer Older
D
Dan Mace 已提交
1 2
package api

A
aarzilli 已提交
3
import (
A
aarzilli 已提交
4
	"bytes"
5 6
	"errors"
	"fmt"
A
aarzilli 已提交
7
	"reflect"
8 9
	"strconv"
	"unicode"
H
Hubert Krauze 已提交
10

11
	"github.com/go-delve/delve/pkg/proc"
A
aarzilli 已提交
12
)
13

14 15 16
// ErrNotExecutable is an error returned when trying
// to debug a non-executable file.
var ErrNotExecutable = proc.ErrNotExecutable
17

D
Dan Mace 已提交
18 19
// DebuggerState represents the current context of the debugger.
type DebuggerState struct {
20 21
	// Running is true if the process is running and no other information can be collected.
	Running bool
D
Dan Mace 已提交
22 23
	// CurrentThread is the currently selected debugger thread.
	CurrentThread *Thread `json:"currentThread,omitempty"`
24 25
	// SelectedGoroutine is the currently selected goroutine
	SelectedGoroutine *Goroutine `json:"currentGoroutine,omitempty"`
26 27
	// List of all the process threads
	Threads []*Thread
28 29 30 31 32
	// NextInProgress indicates that a next or step operation was interrupted by another breakpoint
	// or a manual stop and is waiting to complete.
	// While NextInProgress is set further requests for next or step may be rejected.
	// Either execute continue until NextInProgress is false or call CancelNext
	NextInProgress bool
D
Dan Mace 已提交
33
	// Exited indicates whether the debugged process has exited.
34 35
	Exited     bool `json:"exited"`
	ExitStatus int  `json:"exitStatus"`
36 37
	// When contains a description of the current position in a recording
	When string
A
aarzilli 已提交
38 39
	// Filled by RPCClient.Continue, indicates an error
	Err error `json:"-"`
D
Dan Mace 已提交
40 41
}

D
Derek Parker 已提交
42
// Breakpoint addresses a location at which process execution may be
D
Dan Mace 已提交
43
// suspended.
D
Derek Parker 已提交
44
type Breakpoint struct {
D
Dan Mace 已提交
45 46
	// ID is a unique identifier for the breakpoint.
	ID int `json:"id"`
47 48
	// User defined name of the breakpoint
	Name string `json:"name"`
D
Dan Mace 已提交
49 50 51 52 53 54 55 56 57
	// Addr is the address of the breakpoint.
	Addr uint64 `json:"addr"`
	// File is the source file for the breakpoint.
	File string `json:"file"`
	// Line is a line in File for the breakpoint.
	Line int `json:"line"`
	// FunctionName is the name of the function at the current breakpoint, and
	// may not always be available.
	FunctionName string `json:"functionName,omitempty"`
A
aarzilli 已提交
58

59 60 61
	// Breakpoint condition
	Cond string

D
Derek Parker 已提交
62
	// Tracepoint flag, signifying this is a tracepoint.
A
aarzilli 已提交
63
	Tracepoint bool `json:"continue"`
D
Derek Parker 已提交
64 65 66
	// TraceReturn flag signifying this is a breakpoint set at a return
	// statement in a traced function.
	TraceReturn bool `json:"traceReturn"`
A
aarzilli 已提交
67 68
	// retrieve goroutine information
	Goroutine bool `json:"goroutine"`
H
Hubert Krauze 已提交
69 70
	// number of stack frames to retrieve
	Stacktrace int `json:"stacktrace"`
71
	// expressions to evaluate
D
Derek Parker 已提交
72
	Variables []string `json:"variables,omitempty"`
73 74 75 76
	// LoadArgs requests loading function arguments when the breakpoint is hit
	LoadArgs *LoadConfig
	// LoadLocals requests loading function locals when the breakpoint is hit
	LoadLocals *LoadConfig
77 78 79 80
	// number of times a breakpoint has been reached in a certain goroutine
	HitCount map[string]uint64 `json:"hitCount"`
	// number of times a breakpoint has been reached
	TotalHitCount uint64 `json:"totalHitCount"`
D
Dan Mace 已提交
81 82
}

83 84 85 86
// ValidBreakpointName returns an error if
// the name to be chosen for a breakpoint is invalid.
// The name can not be just a number, and must contain a series
// of letters or numbers.
87 88 89 90 91 92 93 94 95 96 97 98 99 100
func ValidBreakpointName(name string) error {
	if _, err := strconv.Atoi(name); err == nil {
		return errors.New("breakpoint name can not be a number")
	}

	for _, ch := range name {
		if !(unicode.IsLetter(ch) || unicode.IsDigit(ch)) {
			return fmt.Errorf("invalid character in breakpoint name '%c'", ch)
		}
	}

	return nil
}

D
Dan Mace 已提交
101 102 103 104 105 106 107 108 109 110 111 112
// Thread is a thread within the debugged process.
type Thread struct {
	// ID is a unique identifier for the thread.
	ID int `json:"id"`
	// PC is the current program counter for the thread.
	PC uint64 `json:"pc"`
	// File is the file for the program counter.
	File string `json:"file"`
	// Line is the line number for the program counter.
	Line int `json:"line"`
	// Function is function information at the program counter. May be nil.
	Function *Function `json:"function,omitempty"`
113 114 115 116 117 118 119

	// ID of the goroutine running on this thread
	GoroutineID int `json:"goroutineID"`

	// Breakpoint this thread is stopped at
	Breakpoint *Breakpoint `json:"breakPoint,omitempty"`
	// Informations requested by the current breakpoint
J
Josh Soref 已提交
120
	BreakpointInfo *BreakpointInfo `json:"breakPointInfo,omitempty"`
121 122 123

	// ReturnValues contains the return values of the function we just stepped out of
	ReturnValues []Variable
D
Dan Mace 已提交
124 125
}

126
// Location holds program location information.
A
aarzilli 已提交
127 128 129 130 131 132 133
type Location struct {
	PC       uint64    `json:"pc"`
	File     string    `json:"file"`
	Line     int       `json:"line"`
	Function *Function `json:"function,omitempty"`
}

134
// Stackframe describes one frame in a stack trace.
135 136
type Stackframe struct {
	Location
137 138 139 140 141 142
	Locals    []Variable
	Arguments []Variable

	FrameOffset        int64
	FramePointerOffset int64

143 144
	Defers []Defer

145 146
	Bottom bool `json:"Bottom,omitempty"` // Bottom is true if this is the bottom frame of the stack

147
	Err string
148 149
}

150
// Defer describes a deferred function.
151 152 153 154 155 156 157
type Defer struct {
	DeferredLoc Location // deferred function
	DeferLoc    Location // location of the defer statement
	SP          uint64   // value of SP when the function was deferred
	Unreadable  string
}

158 159
// Var will return the variable described by 'name' within
// this stack frame.
160 161 162 163 164 165 166 167 168 169 170 171 172 173
func (frame *Stackframe) Var(name string) *Variable {
	for i := range frame.Locals {
		if frame.Locals[i].Name == name {
			return &frame.Locals[i]
		}
	}
	for i := range frame.Arguments {
		if frame.Arguments[i].Name == name {
			return &frame.Arguments[i]
		}
	}
	return nil
}

D
Dan Mace 已提交
174 175 176
// Function represents thread-scoped function information.
type Function struct {
	// Name is the function name.
177
	Name_  string `json:"name"`
D
Dan Mace 已提交
178 179 180
	Value  uint64 `json:"value"`
	Type   byte   `json:"type"`
	GoType uint64 `json:"goType"`
181 182
	// Optimized is true if the function was optimized
	Optimized bool `json:"optimized"`
D
Dan Mace 已提交
183 184
}

185
// Name will return the function name.
186 187 188 189 190 191 192
func (fn *Function) Name() string {
	if fn == nil {
		return "???"
	}
	return fn.Name_
}

A
aarzilli 已提交
193
// VariableFlags is the type of the Flags field of Variable.
194 195 196
type VariableFlags uint16

const (
A
aarzilli 已提交
197
	// VariableEscaped is set for local variables that escaped to the heap
198 199 200 201 202
	//
	// The compiler performs escape analysis on local variables, the variables
	// that may outlive the stack frame are allocated on the heap instead and
	// only the address is recorded on the stack. These variables will be
	// marked with this flag.
D
Derek Parker 已提交
203
	VariableEscaped = (1 << iota)
A
aarzilli 已提交
204 205 206

	// VariableShadowed is set for local variables that are shadowed by a
	// variable with the same name in another scope
D
Derek Parker 已提交
207
	VariableShadowed
208 209 210

	// VariableConstant means this variable is a constant value
	VariableConstant
211 212 213 214 215 216

	// VariableArgument means this variable is a function argument
	VariableArgument

	// VariableReturnArgument means this variable is a function return value
	VariableReturnArgument
217 218 219 220 221 222 223

	// VariableFakeAddress means the address of this variable is either fake
	// (i.e. the variable is partially or completely stored in a CPU register
	// and doesn't have a real address) or possibly no longer availabe (because
	// the variable is the return value of a function call and allocated on a
	// frame that no longer exists)
	VariableFakeAddress
224 225
)

D
Dan Mace 已提交
226 227
// Variable describes a variable.
type Variable struct {
228 229 230 231
	// Name of the variable or struct member
	Name string `json:"name"`
	// Address of the variable or struct member
	Addr uintptr `json:"addr"`
A
aarzilli 已提交
232 233
	// Only the address field is filled (result of evaluating expressions like &<expr>)
	OnlyAddr bool `json:"onlyAddr"`
234 235 236 237 238
	// Go type of the variable
	Type string `json:"type"`
	// Type of the variable after resolving any typedefs
	RealType string `json:"realType"`

239 240
	Flags VariableFlags `json:"flags"`

241 242 243 244
	Kind reflect.Kind `json:"kind"`

	//Strings have their length capped at proc.maxArrayValues, use Len for the real length of a string
	//Function variables will store the name of the function in this field
D
Dan Mace 已提交
245
	Value string `json:"value"`
246 247 248 249 250 251 252 253 254

	// Number of elements in an array or a slice, number of keys for a map, number of struct members for a struct, length of strings
	Len int64 `json:"len"`
	// Cap value for slices
	Cap int64 `json:"cap"`

	// Array and slice elements, member fields of structs, key/value pairs of maps, value of complex numbers
	// The Name field in this slice will always be the empty string except for structs (when it will be the field name) and for complex numbers (when it will be "real" and "imaginary")
	// For maps each map entry will have to items in this slice, even numbered items will represent map keys and odd numbered items will represent their values
J
Josh Soref 已提交
255
	// This field's length is capped at proc.maxArrayValues for slices and arrays and 2*proc.maxArrayValues for maps, in the circumstances where the cap takes effect len(Children) != Len
D
Derek Parker 已提交
256
	// The other length cap applied to this field is related to maximum recursion depth, when the maximum recursion depth is reached this field is left empty, contrary to the previous one this cap also applies to structs (otherwise structs will always have all their member fields returned)
257 258
	Children []Variable `json:"children"`

259 260 261 262 263 264
	// Base address of arrays, Base address of the backing array for slices (0 for nil slices)
	// Base address of the backing byte array for strings
	// address of the struct backing chan and map variables
	// address of the function entry point for function variables (0 for nil function pointers)
	Base uintptr `json:"base"`

265 266
	// Unreadable addresses will have this field set
	Unreadable string `json:"unreadable"`
267 268 269

	// LocationExpr describes the location expression of this variable's address
	LocationExpr string
270 271
	// DeclLine is the line number of this variable's declaration
	DeclLine int64
D
Dan Mace 已提交
272 273
}

274 275 276 277 278 279 280 281 282 283 284 285 286 287
// LoadConfig describes how to load values from target's memory
type LoadConfig struct {
	// FollowPointers requests pointers to be automatically dereferenced.
	FollowPointers bool
	// MaxVariableRecurse is how far to recurse when evaluating nested types.
	MaxVariableRecurse int
	// MaxStringLen is the maximum number of bytes read from a string
	MaxStringLen int
	// MaxArrayValues is the maximum number of elements read from an array, a slice or a map.
	MaxArrayValues int
	// MaxStructFields is the maximum number of fields read from a struct, -1 will read all fields.
	MaxStructFields int
}

D
Dan Mace 已提交
288 289 290 291 292
// Goroutine represents the information relevant to Delve from the runtime's
// internal G structure.
type Goroutine struct {
	// ID is a unique identifier for the goroutine.
	ID int `json:"id"`
293
	// Current location of the goroutine
294
	CurrentLoc Location `json:"currentLoc"`
295
	// Current location of the goroutine, excluding calls inside runtime
296
	UserCurrentLoc Location `json:"userCurrentLoc"`
297
	// Location of the go instruction that started this goroutine
298
	GoStatementLoc Location `json:"goStatementLoc"`
299 300
	// Location of the starting function
	StartLoc Location `json:"startLoc"`
301
	// ID of the associated thread for running goroutines
302 303
	ThreadID   int    `json:"threadID"`
	Unreadable string `json:"unreadable"`
D
Dan Mace 已提交
304 305 306 307 308 309 310 311 312
}

// DebuggerCommand is a command which changes the debugger's execution state.
type DebuggerCommand struct {
	// Name is the command to run.
	Name string `json:"name"`
	// ThreadID is used to specify which thread to use with the SwitchThread
	// command.
	ThreadID int `json:"threadID,omitempty"`
313
	// GoroutineID is used to specify which thread to use with the SwitchGoroutine
314
	// and Call commands.
315
	GoroutineID int `json:"goroutineID,omitempty"`
316 317 318
	// When ReturnInfoLoadConfig is not nil it will be used to load the value
	// of any return variables.
	ReturnInfoLoadConfig *LoadConfig
319 320
	// Expr is the expression argument for a Call command
	Expr string `json:"expr,omitempty"`
321 322 323 324 325 326 327 328 329 330 331 332 333 334

	// UnsafeCall disables parameter escape checking for function calls.
	// Go objects can be allocated on the stack or on the heap. Heap objects
	// can be used by any goroutine; stack objects can only be used by the
	// goroutine that owns the stack they are allocated on and can not surivive
	// the stack frame of allocation.
	// The Go compiler will use escape analysis to determine whether to
	// allocate an object on the stack or the heap.
	// When injecting a function call Delve will check that no address of a
	// stack allocated object is passed to the called function: this ensures
	// the rules for stack objects will not be violated.
	// If you are absolutely sure that the function you are calling will not
	// violate the rules about stack objects you can disable this safety check
	// by setting UnsafeCall to true.
335
	UnsafeCall bool `json:"unsafeCall,omitempty"`
D
Dan Mace 已提交
336 337
}

338
// BreakpointInfo contains informations about the current breakpoint
A
aarzilli 已提交
339
type BreakpointInfo struct {
340 341 342 343
	Stacktrace []Stackframe `json:"stacktrace,omitempty"`
	Goroutine  *Goroutine   `json:"goroutine,omitempty"`
	Variables  []Variable   `json:"variables,omitempty"`
	Arguments  []Variable   `json:"arguments,omitempty"`
344
	Locals     []Variable   `json:"locals,omitempty"`
A
aarzilli 已提交
345 346
}

347 348
// EvalScope is the scope a command should
// be evaluated in. Describes the goroutine and frame number.
349
type EvalScope struct {
350 351 352
	GoroutineID  int
	Frame        int
	DeferredCall int // when DeferredCall is n > 0 this eval scope is relative to the n-th deferred call in the current frame
353 354
}

D
Dan Mace 已提交
355 356 357
const (
	// Continue resumes process execution.
	Continue = "continue"
358 359
	// Rewind resumes process execution backwards (target must be a recording).
	Rewind = "rewind"
360
	// Step continues to next source line, entering function calls.
D
Dan Mace 已提交
361
	Step = "step"
A
aarzilli 已提交
362 363
	// StepOut continues to the return address of the current function
	StepOut = "stepOut"
364
	// StepInstruction continues for exactly 1 cpu instruction.
365
	StepInstruction = "stepInstruction"
366 367
	// ReverseStepInstruction reverses execution for exactly 1 cpu instruction.
	ReverseStepInstruction = "reverseStepInstruction"
D
Dan Mace 已提交
368 369 370 371
	// Next continues to the next source line, not entering function calls.
	Next = "next"
	// SwitchThread switches the debugger's current thread context.
	SwitchThread = "switchThread"
372 373
	// SwitchGoroutine switches the debugger's current thread context to the thread running the specified goroutine
	SwitchGoroutine = "switchGoroutine"
D
Dan Mace 已提交
374 375
	// Halt suspends the process.
	Halt = "halt"
376 377
	// Call resumes process execution injecting a function call.
	Call = "call"
D
Dan Mace 已提交
378
)
A
aarzilli 已提交
379

380 381
// AssemblyFlavour describes the output
// of disassembled code.
A
aarzilli 已提交
382 383 384
type AssemblyFlavour int

const (
385 386 387
	// GNUFlavour will disassemble using GNU assembly syntax.
	GNUFlavour = AssemblyFlavour(proc.GNUFlavour)
	// IntelFlavour will disassemble using Intel assembly syntax.
A
aarzilli 已提交
388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406
	IntelFlavour = AssemblyFlavour(proc.IntelFlavour)
)

// AsmInstruction represents one assembly instruction at some address
type AsmInstruction struct {
	// Loc is the location of this instruction
	Loc Location
	// Destination of CALL instructions
	DestLoc *Location
	// Text is the formatted representation of the instruction
	Text string
	// Bytes is the instruction as read from memory
	Bytes []byte
	// If Breakpoint is true a breakpoint is set at this instruction
	Breakpoint bool
	// In AtPC is true this is the instruction the current thread is stopped at
	AtPC bool
}

407
// AsmInstructions is a slice of single instructions.
A
aarzilli 已提交
408
type AsmInstructions []AsmInstruction
A
aarzilli 已提交
409

410
// GetVersionIn is the argument for GetVersion.
A
aarzilli 已提交
411 412 413
type GetVersionIn struct {
}

414
// GetVersionOut is the result of GetVersion.
A
aarzilli 已提交
415
type GetVersionOut struct {
416 417 418 419 420 421 422
	DelveVersion    string
	APIVersion      int
	Backend         string // backend currently in use
	TargetGoVersion string

	MinSupportedVersionOfGo string
	MaxSupportedVersionOfGo string
A
aarzilli 已提交
423 424
}

425
// SetAPIVersionIn is the input for SetAPIVersion.
A
aarzilli 已提交
426 427 428 429
type SetAPIVersionIn struct {
	APIVersion int
}

430
// SetAPIVersionOut is the output for SetAPIVersion.
A
aarzilli 已提交
431 432
type SetAPIVersionOut struct {
}
A
aarzilli 已提交
433

434
// Register holds information on a CPU register.
A
aarzilli 已提交
435 436 437 438 439
type Register struct {
	Name  string
	Value string
}

440
// Registers is a list of CPU registers.
A
aarzilli 已提交
441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456
type Registers []Register

func (regs Registers) String() string {
	maxlen := 0
	for _, reg := range regs {
		if n := len(reg.Name); n > maxlen {
			maxlen = n
		}
	}

	var buf bytes.Buffer
	for _, reg := range regs {
		fmt.Fprintf(&buf, "%*s = %s\n", maxlen, reg.Name, reg.Value)
	}
	return buf.String()
}
457

458 459
// DiscardedBreakpoint is a breakpoint that is not
// reinstated during a restart.
460 461
type DiscardedBreakpoint struct {
	Breakpoint *Breakpoint
462
	Reason     string
463
}
464

465 466
// Checkpoint is a point in the program that
// can be returned to in certain execution modes.
467 468 469 470 471
type Checkpoint struct {
	ID    int
	When  string
	Where string
}
472 473 474

// Image represents a loaded shared object (go plugin or shared library)
type Image struct {
475 476
	Path    string
	Address uint64
477
}
478 479 480 481 482 483 484 485

// Ancestor represents a goroutine ancestor
type Ancestor struct {
	ID    int64
	Stack []Stackframe

	Unreadable string
}
486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504

// StacktraceOptions is the type of the Opts field of StacktraceIn that
// configures the stacktrace.
// Tracks proc.StacktraceOptions
type StacktraceOptions uint16

const (
	// StacktraceReadDefers requests a stacktrace decorated with deferred calls
	// for each frame.
	StacktraceReadDefers StacktraceOptions = 1 << iota

	// StacktraceSimple requests a stacktrace where no stack switches will be
	// attempted.
	StacktraceSimple

	// StacktraceG requests a stacktrace starting with the register
	// values saved in the runtime.g structure.
	StacktraceG
)