forked from go-delve/delve
-
Notifications
You must be signed in to change notification settings - Fork 0
/
types.go
368 lines (316 loc) · 11.7 KB
/
types.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
package api
import (
"bytes"
"errors"
"fmt"
"reflect"
"strconv"
"unicode"
"github.com/derekparker/delve/pkg/proc"
)
var NotExecutableErr = proc.NotExecutableErr
// DebuggerState represents the current context of the debugger.
type DebuggerState struct {
// CurrentThread is the currently selected debugger thread.
CurrentThread *Thread `json:"currentThread,omitempty"`
// SelectedGoroutine is the currently selected goroutine
SelectedGoroutine *Goroutine `json:"currentGoroutine,omitempty"`
// List of all the process threads
Threads []*Thread
// 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
// Exited indicates whether the debugged process has exited.
Exited bool `json:"exited"`
ExitStatus int `json:"exitStatus"`
// When contains a description of the current position in a recording
When string
// Filled by RPCClient.Continue, indicates an error
Err error `json:"-"`
}
// Breakpoint addresses a location at which process execution may be
// suspended.
type Breakpoint struct {
// ID is a unique identifier for the breakpoint.
ID int `json:"id"`
// User defined name of the breakpoint
Name string `json:"name"`
// 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"`
// Breakpoint condition
Cond string
// tracepoint flag
Tracepoint bool `json:"continue"`
// retrieve goroutine information
Goroutine bool `json:"goroutine"`
// number of stack frames to retrieve
Stacktrace int `json:"stacktrace"`
// expressions to evaluate
Variables []string `json:"variables,omitempty"`
// LoadArgs requests loading function arguments when the breakpoint is hit
LoadArgs *LoadConfig
// LoadLocals requests loading function locals when the breakpoint is hit
LoadLocals *LoadConfig
// 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"`
}
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
}
// 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"`
// 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
BreakpointInfo *BreakpointInfo `json:"breakPointInfo,omitrempty"`
}
type Location struct {
PC uint64 `json:"pc"`
File string `json:"file"`
Line int `json:"line"`
Function *Function `json:"function,omitempty"`
}
type Stackframe struct {
Location
Locals []Variable
Arguments []Variable
FrameOffset int64
FramePointerOffset int64
Err string
}
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
}
// Function represents thread-scoped function information.
type Function struct {
// Name is the function name.
Name string `json:"name"`
Value uint64 `json:"value"`
Type byte `json:"type"`
GoType uint64 `json:"goType"`
// Optimized is true if the function was optimized
Optimized bool `json:"optimized"`
}
// VariableFlags is the type of the Flags field of Variable.
type VariableFlags uint16
const (
// VariableEscaped is set for local variables that escaped to the heap
//
// 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.
VariableEscaped = VariableFlags(proc.VariableEscaped)
// VariableShadowed is set for local variables that are shadowed by a
// variable with the same name in another scope
VariableShadowed = VariableFlags(proc.VariableShadowed)
// VariableConstant means this variable is a constant value
VariableConstant
)
// Variable describes a variable.
type Variable struct {
// Name of the variable or struct member
Name string `json:"name"`
// Address of the variable or struct member
Addr uintptr `json:"addr"`
// Only the address field is filled (result of evaluating expressions like &<expr>)
OnlyAddr bool `json:"onlyAddr"`
// Go type of the variable
Type string `json:"type"`
// Type of the variable after resolving any typedefs
RealType string `json:"realType"`
Flags VariableFlags `json:"flags"`
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
Value string `json:"value"`
// 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
// This field's length is capped at proc.maxArrayValues for slices and arrays and 2*proc.maxArrayValues for maps, in the circumnstances where the cap takes effect len(Children) != Len
// 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)
Children []Variable `json:"children"`
// 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"`
// Unreadable addresses will have this field set
Unreadable string `json:"unreadable"`
// LocationExpr describes the location expression of this variable's address
LocationExpr string
}
// 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
}
// 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"`
// Current location of the goroutine
CurrentLoc Location `json:"currentLoc"`
// Current location of the goroutine, excluding calls inside runtime
UserCurrentLoc Location `json:"userCurrentLoc"`
// Location of the go instruction that started this goroutine
GoStatementLoc Location `json:"goStatementLoc"`
// ID of the associated thread for running goroutines
ThreadID int `json:"threadID"`
}
// 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"`
// GoroutineID is used to specify which thread to use with the SwitchGoroutine
// command.
GoroutineID int `json:"goroutineID,omitempty"`
}
// Informations about the current breakpoint
type BreakpointInfo struct {
Stacktrace []Stackframe `json:"stacktrace,omitempty"`
Goroutine *Goroutine `json:"goroutine,omitempty"`
Variables []Variable `json:"variables,omitempty"`
Arguments []Variable `json:"arguments,omitempty"`
Locals []Variable `json:"locals,omitempty"`
}
type EvalScope struct {
GoroutineID int
Frame int
}
const (
// Continue resumes process execution.
Continue = "continue"
// Rewind resumes process execution backwards (target must be a recording).
Rewind = "rewind"
// Step continues to next source line, entering function calls.
Step = "step"
// StepOut continues to the return address of the current function
StepOut = "stepOut"
// SingleStep continues for exactly 1 cpu instruction.
StepInstruction = "stepInstruction"
// Next continues to the next source line, not entering function calls.
Next = "next"
// SwitchThread switches the debugger's current thread context.
SwitchThread = "switchThread"
// SwitchGoroutine switches the debugger's current thread context to the thread running the specified goroutine
SwitchGoroutine = "switchGoroutine"
// Halt suspends the process.
Halt = "halt"
)
type AssemblyFlavour int
const (
GNUFlavour = AssemblyFlavour(proc.GNUFlavour)
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
}
type AsmInstructions []AsmInstruction
type GetVersionIn struct {
}
type GetVersionOut struct {
DelveVersion string
APIVersion int
}
type SetAPIVersionIn struct {
APIVersion int
}
type SetAPIVersionOut struct {
}
type Register struct {
Name string
Value string
}
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()
}
type DiscardedBreakpoint struct {
Breakpoint *Breakpoint
Reason string
}
type Checkpoint struct {
ID int
When string
Where string
}