variables.go 44.4 KB
Newer Older
D
Derek Parker 已提交
1
package proc
2 3 4

import (
	"bytes"
5
	"debug/dwarf"
6
	"encoding/binary"
7
	"errors"
8
	"fmt"
9
	"go/constant"
10 11
	"go/parser"
	"go/token"
12
	"math"
13
	"reflect"
A
aarzilli 已提交
14
	"sort"
15 16 17
	"strings"
	"unsafe"

18
	"github.com/derekparker/delve/pkg/dwarf/godwarf"
D
Derek Parker 已提交
19 20
	"github.com/derekparker/delve/pkg/dwarf/op"
	"github.com/derekparker/delve/pkg/dwarf/reader"
21 22
)

23
const (
24
	maxErrCount = 3 // Max number of read errors to accept while evaluating slices, arrays and structs
25

26
	maxArrayStridePrefetch = 1024 // Maximum size of array stride for which we will prefetch the array contents
27

D
Derek Parker 已提交
28 29
	chanRecv = "chan receive"
	chanSend = "chan send"
A
aarzilli 已提交
30 31 32

	hashTophashEmpty = 0 // used by map reading code, indicates an empty bucket
	hashMinTopHash   = 4 // used by map reading code, indicates minimum value of tophash that isn't empty or evacuated
33 34
)

35 36 37 38 39 40 41 42 43
type FloatSpecial uint8

const (
	FloatIsNormal FloatSpecial = iota
	FloatIsNaN
	FloatIsPosInf
	FloatIsNegInf
)

44 45 46 47
type VariableFlags uint16

const (
	// VariableEscaped is set for local variables that escaped to the heap
48 49 50 51 52
	//
	// 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.
53
	VariableEscaped VariableFlags = (1 << iota)
A
aarzilli 已提交
54 55 56
	// VariableShadowed is set for local variables that are shadowed by a
	// variable with the same name in another scope
	VariableShadowed
57 58
)

D
Derek Parker 已提交
59 60 61 62
// Variable represents a variable. It contains the address, name,
// type and other information parsed from both the Dwarf information
// and the memory of the debugged process.
// If OnlyAddr is true, the variables value has not been loaded.
63
type Variable struct {
64
	Addr      uintptr
A
aarzilli 已提交
65
	OnlyAddr  bool
66
	Name      string
67 68
	DwarfType godwarf.Type
	RealType  godwarf.Type
69
	Kind      reflect.Kind
70
	mem       MemoryReadWriter
71
	bi        *BinaryInfo
72

73 74
	Value        constant.Value
	FloatSpecial FloatSpecial
75 76 77 78

	Len int64
	Cap int64

79 80
	Flags VariableFlags

81 82
	// 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
A
aarzilli 已提交
83
	// address of the struct backing chan and map variables
A
aarzilli 已提交
84
	// address of the function entry point for function variables (0 for nil function pointers)
85
	Base      uintptr
86
	stride    int64
87
	fieldType godwarf.Type
88

A
aarzilli 已提交
89 90 91
	// number of elements to skip when loading a map
	mapSkip int

92 93 94 95
	Children []Variable

	loaded     bool
	Unreadable error
96 97
}

98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113
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
}

var loadSingleValue = LoadConfig{false, 0, 64, 0, 0}
var loadFullValue = LoadConfig{true, 1, 64, 64, -1}

D
Derek Parker 已提交
114
// G status, from: src/runtime/runtime2.go
115
const (
D
Derek Parker 已提交
116 117 118 119 120 121 122 123 124
	Gidle           uint64 = iota // 0
	Grunnable                     // 1 runnable and on a run queue
	Grunning                      // 2
	Gsyscall                      // 3
	Gwaiting                      // 4
	GmoribundUnused               // 5 currently unused, but hardcoded in gdb scripts
	Gdead                         // 6
	Genqueue                      // 7 Only the Gscanenqueue is used.
	Gcopystack                    // 8 in this state when newstack is moving the stack
125 126
)

D
Derek Parker 已提交
127
// G represents a runtime G (goroutine) structure (at least the
128
// fields that Delve is interested in).
D
Derek Parker 已提交
129
type G struct {
D
Derek Parker 已提交
130
	ID         int    // Goroutine ID
131 132 133 134
	PC         uint64 // PC of goroutine when it was parked.
	SP         uint64 // SP of goroutine when it was parked.
	GoPC       uint64 // PC of 'go' statement that created this goroutine.
	WaitReason string // Reason for goroutine being parked.
135
	Status     uint64
A
Alessandro Arzilli 已提交
136 137
	stkbarVar  *Variable // stkbar field of g struct
	stkbarPos  int       // stkbarPos field of g struct
138
	stackhi    uint64    // value of stack.hi
139

140
	// Information on goroutine location
141
	CurrentLoc Location
142

A
aarzilli 已提交
143
	// Thread that this goroutine is currently allocated to
144
	Thread Thread
145

A
Alessandro Arzilli 已提交
146
	variable *Variable
147 148
}

D
Derek Parker 已提交
149 150
// EvalScope is the scope for variable evaluation. Contains the thread,
// current location (PC), and canonical frame address.
151
type EvalScope struct {
152 153 154 155 156
	PC      uint64           // Current instruction of the evaluation frame
	CFA     int64            // Stack address of the evaluation frame
	Mem     MemoryReadWriter // Target's memory
	Gvar    *Variable
	BinInfo *BinaryInfo
157
	StackHi uint64
158 159
}

D
Derek Parker 已提交
160
// IsNilErr is returned when a variable is nil.
161 162 163 164 165 166 167 168
type IsNilErr struct {
	name string
}

func (err *IsNilErr) Error() string {
	return fmt.Sprintf("%s is nil", err.name)
}

169
func (scope *EvalScope) newVariable(name string, addr uintptr, dwarfType godwarf.Type) *Variable {
170
	return newVariable(name, addr, dwarfType, scope.BinInfo, scope.Mem)
171 172
}

173
func newVariableFromThread(t Thread, name string, addr uintptr, dwarfType godwarf.Type) *Variable {
174
	return newVariable(name, addr, dwarfType, t.BinInfo(), t)
175 176
}

177
func (v *Variable) newVariable(name string, addr uintptr, dwarfType godwarf.Type) *Variable {
178
	return newVariable(name, addr, dwarfType, v.bi, v.mem)
179 180
}

181
func newVariable(name string, addr uintptr, dwarfType godwarf.Type, bi *BinaryInfo, mem MemoryReadWriter) *Variable {
182 183 184
	v := &Variable{
		Name:      name,
		Addr:      addr,
185
		DwarfType: dwarfType,
186
		mem:       mem,
187
		bi:        bi,
188 189
	}

190
	v.RealType = resolveTypedef(v.DwarfType)
191 192

	switch t := v.RealType.(type) {
193
	case *godwarf.PtrType:
194
		v.Kind = reflect.Ptr
195
		if _, isvoid := t.Type.(*godwarf.VoidType); isvoid {
196
			v.Kind = reflect.UnsafePointer
197
		}
198
	case *godwarf.ChanType:
199
		v.Kind = reflect.Chan
200
	case *godwarf.MapType:
201
		v.Kind = reflect.Map
202
	case *godwarf.StringType:
203 204
		v.Kind = reflect.String
		v.stride = 1
205
		v.fieldType = &godwarf.UintType{BasicType: godwarf.BasicType{CommonType: godwarf.CommonType{ByteSize: 1, Name: "byte"}, BitSize: 8, BitOffset: 0}}
206
		if v.Addr != 0 {
207
			v.Base, v.Len, v.Unreadable = readStringInfo(v.mem, v.bi.Arch, v.Addr)
208
		}
209
	case *godwarf.SliceType:
210 211 212 213
		v.Kind = reflect.Slice
		if v.Addr != 0 {
			v.loadSliceInfo(t)
		}
214
	case *godwarf.InterfaceType:
215
		v.Kind = reflect.Interface
216
	case *godwarf.StructType:
217
		v.Kind = reflect.Struct
218
	case *godwarf.ArrayType:
219
		v.Kind = reflect.Array
220
		v.Base = v.Addr
221 222 223 224 225 226 227 228
		v.Len = t.Count
		v.Cap = -1
		v.fieldType = t.Type
		v.stride = 0

		if t.Count > 0 {
			v.stride = t.ByteSize / t.Count
		}
229
	case *godwarf.ComplexType:
230 231 232 233 234 235
		switch t.ByteSize {
		case 8:
			v.Kind = reflect.Complex64
		case 16:
			v.Kind = reflect.Complex128
		}
236
	case *godwarf.IntType:
237
		v.Kind = reflect.Int
238
	case *godwarf.UintType:
239
		v.Kind = reflect.Uint
240
	case *godwarf.FloatType:
241 242 243 244 245 246
		switch t.ByteSize {
		case 4:
			v.Kind = reflect.Float32
		case 8:
			v.Kind = reflect.Float64
		}
247
	case *godwarf.BoolType:
248
		v.Kind = reflect.Bool
249
	case *godwarf.FuncType:
250
		v.Kind = reflect.Func
251
	case *godwarf.VoidType:
252
		v.Kind = reflect.Invalid
253
	case *godwarf.UnspecifiedType:
254 255 256
		v.Kind = reflect.Invalid
	default:
		v.Unreadable = fmt.Errorf("Unknown type: %T", t)
257 258
	}

259 260 261
	return v
}

262
func resolveTypedef(typ godwarf.Type) godwarf.Type {
263
	for {
264
		if tt, ok := typ.(*godwarf.TypedefType); ok {
265 266 267 268 269 270 271
			typ = tt.Type
		} else {
			return typ
		}
	}
}

272
func newConstant(val constant.Value, mem MemoryReadWriter) *Variable {
273
	v := &Variable{Value: val, mem: mem, loaded: true}
A
aarzilli 已提交
274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290
	switch val.Kind() {
	case constant.Int:
		v.Kind = reflect.Int
	case constant.Float:
		v.Kind = reflect.Float64
	case constant.Bool:
		v.Kind = reflect.Bool
	case constant.Complex:
		v.Kind = reflect.Complex128
	case constant.String:
		v.Kind = reflect.String
		v.Len = int64(len(constant.StringVal(val)))
	}
	return v
}

var nilVariable = &Variable{
291
	Name:     "nil",
A
aarzilli 已提交
292
	Addr:     0,
293
	Base:     0,
A
aarzilli 已提交
294 295 296 297
	Kind:     reflect.Ptr,
	Children: []Variable{{Addr: 0, OnlyAddr: true}},
}

298 299 300
func (v *Variable) clone() *Variable {
	r := *v
	return &r
301 302
}

D
Derek Parker 已提交
303 304
// TypeString returns the string representation
// of the type of this variable.
305 306 307 308 309
func (v *Variable) TypeString() string {
	if v == nilVariable {
		return "nil"
	}
	if v.DwarfType != nil {
310
		return v.DwarfType.Common().Name
311 312 313 314
	}
	return v.Kind.String()
}

315
func (v *Variable) toField(field *godwarf.StructField) (*Variable, error) {
316 317 318
	if v.Unreadable != nil {
		return v.clone(), nil
	}
D
Derek Parker 已提交
319
	if v.Addr == 0 {
320
		return nil, &IsNilErr{v.Name}
D
Derek Parker 已提交
321 322
	}

323 324
	name := ""
	if v.Name != "" {
325 326 327 328
		parts := strings.Split(field.Name, ".")
		if len(parts) > 1 {
			name = fmt.Sprintf("%s.%s", v.Name, parts[1])
		} else {
D
Derek Parker 已提交
329
			name = fmt.Sprintf("%s.%s", v.Name, field.Name)
330
		}
331
	}
332
	return v.newVariable(name, uintptr(int64(v.Addr)+field.ByteOffset), field.Type), nil
333 334
}

D
Derek Parker 已提交
335 336
// DwarfReader returns the DwarfReader containing the
// Dwarf information for the target process.
337
func (scope *EvalScope) DwarfReader() *reader.Reader {
338
	return scope.BinInfo.DwarfReader()
339 340
}

D
Derek Parker 已提交
341
// Type returns the Dwarf type entry at `offset`.
342 343
func (scope *EvalScope) Type(offset dwarf.Offset) (godwarf.Type, error) {
	return godwarf.ReadType(scope.BinInfo.dwarf, offset, scope.BinInfo.typeCache)
344 345
}

D
Derek Parker 已提交
346
// PtrSize returns the size of a pointer.
347
func (scope *EvalScope) PtrSize() int {
348
	return scope.BinInfo.Arch.PtrSize()
349 350
}

A
aarzilli 已提交
351
// ChanRecvBlocked returns whether the goroutine is blocked on
352
// a channel read operation.
353
func (g *G) ChanRecvBlocked() bool {
354
	return (g.Thread == nil) && (g.WaitReason == chanRecv)
D
Derek Parker 已提交
355 356
}

D
Derek Parker 已提交
357 358
// NoGError returned when a G could not be found
// for a specific thread.
359 360 361 362 363 364 365 366
type NoGError struct {
	tid int
}

func (ng NoGError) Error() string {
	return fmt.Sprintf("no G executing on thread %d", ng.tid)
}

367 368 369
func (gvar *Variable) parseG() (*G, error) {
	mem := gvar.mem
	gaddr := uint64(gvar.Addr)
370
	_, deref := gvar.RealType.(*godwarf.PtrType)
371

372
	if deref {
373
		gaddrbytes := make([]byte, gvar.bi.Arch.PtrSize())
374
		_, err := mem.ReadMemory(gaddrbytes, uintptr(gaddr))
375 376 377 378
		if err != nil {
			return nil, fmt.Errorf("error derefing *G %s", err)
		}
		gaddr = binary.LittleEndian.Uint64(gaddrbytes)
379
	}
D
Derek Parker 已提交
380
	if gaddr == 0 {
381
		id := 0
382
		if thread, ok := mem.(Thread); ok {
383
			id = thread.ThreadID()
384
		}
A
Alessandro Arzilli 已提交
385
		return nil, NoGError{tid: id}
386
	}
A
Alessandro Arzilli 已提交
387
	for {
388
		if _, isptr := gvar.RealType.(*godwarf.PtrType); !isptr {
A
Alessandro Arzilli 已提交
389 390 391 392
			break
		}
		gvar = gvar.maybeDereference()
	}
393
	gvar.loadValue(LoadConfig{false, 2, 64, 0, -1})
D
Derek Parker 已提交
394 395
	if gvar.Unreadable != nil {
		return nil, gvar.Unreadable
396
	}
A
Alessandro Arzilli 已提交
397 398 399 400 401
	schedVar := gvar.fieldVariable("sched")
	pc, _ := constant.Int64Val(schedVar.fieldVariable("pc").Value)
	sp, _ := constant.Int64Val(schedVar.fieldVariable("sp").Value)
	id, _ := constant.Int64Val(gvar.fieldVariable("goid").Value)
	gopc, _ := constant.Int64Val(gvar.fieldVariable("gopc").Value)
402 403 404 405
	waitReason := ""
	if wrvar := gvar.fieldVariable("waitreason"); wrvar.Value != nil {
		waitReason = constant.StringVal(wrvar.Value)
	}
406 407 408 409 410 411
	var stackhi uint64
	if stackVar := gvar.fieldVariable("stack"); stackVar != nil {
		if stackhiVar := stackVar.fieldVariable("hi"); stackhiVar != nil {
			stackhi, _ = constant.Uint64Val(stackhiVar.Value)
		}
	}
412

A
Alessandro Arzilli 已提交
413
	stkbarVar, _ := gvar.structMember("stkbar")
414 415 416 417 418 419
	stkbarVarPosFld := gvar.fieldVariable("stkbarPos")
	var stkbarPos int64
	if stkbarVarPosFld != nil { // stack barriers were removed in Go 1.9
		stkbarPos, _ = constant.Int64Val(stkbarVarPosFld.Value)
	}

A
Alessandro Arzilli 已提交
420
	status, _ := constant.Int64Val(gvar.fieldVariable("atomicstatus").Value)
421
	f, l, fn := gvar.bi.PCToLine(uint64(pc))
D
Derek Parker 已提交
422 423 424 425 426 427 428 429
	g := &G{
		ID:         int(id),
		GoPC:       uint64(gopc),
		PC:         uint64(pc),
		SP:         uint64(sp),
		WaitReason: waitReason,
		Status:     uint64(status),
		CurrentLoc: Location{PC: uint64(pc), File: f, Line: l, Fn: fn},
A
Alessandro Arzilli 已提交
430
		variable:   gvar,
A
Alessandro Arzilli 已提交
431 432
		stkbarVar:  stkbarVar,
		stkbarPos:  int(stkbarPos),
433
		stackhi:    stackhi,
434
	}
D
Derek Parker 已提交
435 436
	return g, nil
}
437

A
Alessandro Arzilli 已提交
438
func (v *Variable) loadFieldNamed(name string) *Variable {
D
Derek Parker 已提交
439
	v, err := v.structMember(name)
440
	if err != nil {
D
Derek Parker 已提交
441
		return nil
442
	}
443
	v.loadValue(loadFullValue)
D
Derek Parker 已提交
444 445
	if v.Unreadable != nil {
		return nil
446
	}
D
Derek Parker 已提交
447
	return v
448 449
}

A
Alessandro Arzilli 已提交
450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483
func (v *Variable) fieldVariable(name string) *Variable {
	for i := range v.Children {
		if child := &v.Children[i]; child.Name == name {
			return child
		}
	}
	return nil
}

// PC of entry to top-most deferred function.
func (g *G) DeferPC() uint64 {
	if g.variable.Unreadable != nil {
		return 0
	}
	d := g.variable.fieldVariable("_defer").maybeDereference()
	if d.Addr == 0 {
		return 0
	}
	d.loadValue(LoadConfig{false, 1, 64, 0, -1})
	if d.Unreadable != nil {
		return 0
	}
	fnvar := d.fieldVariable("fn").maybeDereference()
	if fnvar.Addr == 0 {
		return 0
	}
	fnvar.loadValue(LoadConfig{false, 1, 64, 0, -1})
	if fnvar.Unreadable != nil {
		return 0
	}
	deferPC, _ := constant.Int64Val(fnvar.fieldVariable("fn").Value)
	return uint64(deferPC)
}

484 485 486 487 488 489 490 491
// From $GOROOT/src/runtime/traceback.go:597
// isExportedRuntime reports whether name is an exported runtime function.
// It is only for runtime functions, so ASCII A-Z is fine.
func isExportedRuntime(name string) bool {
	const n = len("runtime.")
	return len(name) > n && name[:n] == "runtime." && 'A' <= name[n] && name[n] <= 'Z'
}

D
Derek Parker 已提交
492 493
// UserCurrent returns the location the users code is at,
// or was at before entering a runtime function.
494
func (g *G) UserCurrent() Location {
A
aarzilli 已提交
495 496 497
	it, err := g.stackIterator()
	if err != nil {
		return g.CurrentLoc
498 499 500
	}
	for it.Next() {
		frame := it.Frame()
501 502
		if frame.Call.Fn != nil {
			name := frame.Call.Fn.Name
503
			if strings.Contains(name, ".") && (!strings.HasPrefix(name, "runtime.") || isExportedRuntime(name)) {
504 505
				return frame.Call
			}
506 507
		}
	}
508
	return g.CurrentLoc
509 510
}

D
Derek Parker 已提交
511 512
// Go returns the location of the 'go' statement
// that spawned this goroutine.
513
func (g *G) Go() Location {
514
	f, l, fn := g.variable.bi.goSymTable.PCToLine(g.GoPC)
515 516 517
	return Location{PC: g.GoPC, File: f, Line: l, Fn: fn}
}

A
Alessandro Arzilli 已提交
518 519
// Returns the list of saved return addresses used by stack barriers
func (g *G) stkbar() ([]savedLR, error) {
520 521 522
	if g.stkbarVar == nil { // stack barriers were removed in Go 1.9
		return nil, nil
	}
A
Alessandro Arzilli 已提交
523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542
	g.stkbarVar.loadValue(LoadConfig{false, 1, 0, int(g.stkbarVar.Len), 3})
	if g.stkbarVar.Unreadable != nil {
		return nil, fmt.Errorf("unreadable stkbar: %v\n", g.stkbarVar.Unreadable)
	}
	r := make([]savedLR, len(g.stkbarVar.Children))
	for i, child := range g.stkbarVar.Children {
		for _, field := range child.Children {
			switch field.Name {
			case "savedLRPtr":
				ptr, _ := constant.Int64Val(field.Value)
				r[i].ptr = uint64(ptr)
			case "savedLRVal":
				val, _ := constant.Int64Val(field.Value)
				r[i].val = uint64(val)
			}
		}
	}
	return r, nil
}

D
Derek Parker 已提交
543
// EvalVariable returns the value of the given expression (backwards compatibility).
544 545
func (scope *EvalScope) EvalVariable(name string, cfg LoadConfig) (*Variable, error) {
	return scope.EvalExpression(name, cfg)
A
aarzilli 已提交
546
}
547

D
Derek Parker 已提交
548
// SetVariable sets the value of the named variable
A
aarzilli 已提交
549 550
func (scope *EvalScope) SetVariable(name, value string) error {
	t, err := parser.ParseExpr(name)
551
	if err != nil {
A
aarzilli 已提交
552
		return err
553 554
	}

A
aarzilli 已提交
555
	xv, err := scope.evalAST(t)
556
	if err != nil {
A
aarzilli 已提交
557
		return err
558
	}
559

A
aarzilli 已提交
560 561 562 563 564 565 566 567 568
	if xv.Addr == 0 {
		return fmt.Errorf("Can not assign to \"%s\"", name)
	}

	if xv.Unreadable != nil {
		return fmt.Errorf("Expression \"%s\" is unreadable: %v", name, xv.Unreadable)
	}

	t, err = parser.ParseExpr(value)
569 570 571
	if err != nil {
		return err
	}
A
aarzilli 已提交
572 573 574 575 576 577

	yv, err := scope.evalAST(t)
	if err != nil {
		return err
	}

578
	yv.loadValue(loadSingleValue)
A
aarzilli 已提交
579 580 581

	if err := yv.isType(xv.RealType, xv.Kind); err != nil {
		return err
582
	}
A
aarzilli 已提交
583 584 585 586 587 588

	if yv.Unreadable != nil {
		return fmt.Errorf("Expression \"%s\" is unreadable: %v", value, yv.Unreadable)
	}

	return xv.setValue(yv)
589 590
}

A
aarzilli 已提交
591 592
func (scope *EvalScope) extractVariableFromEntry(entry *dwarf.Entry) (*Variable, error) {
	v, err := scope.extractVarInfoFromEntry(entry)
593
	if err != nil {
D
Derek Parker 已提交
594 595
		return nil, err
	}
596
	return v, nil
597
}
D
Derek Parker 已提交
598

599
// LocalVariables returns all local variables from the current function scope.
600
func (scope *EvalScope) LocalVariables(cfg LoadConfig) ([]*Variable, error) {
A
aarzilli 已提交
601
	return scope.variablesByTag(dwarf.TagVariable, &cfg)
602 603 604
}

// FunctionArguments returns the name, value, and type of all current function arguments.
605
func (scope *EvalScope) FunctionArguments(cfg LoadConfig) ([]*Variable, error) {
A
aarzilli 已提交
606
	return scope.variablesByTag(dwarf.TagFormalParameter, &cfg)
607 608 609
}

// PackageVariables returns the name, value, and type of all package variables in the application.
610
func (scope *EvalScope) PackageVariables(cfg LoadConfig) ([]*Variable, error) {
D
Derek Parker 已提交
611
	var vars []*Variable
612
	reader := scope.DwarfReader()
613

614 615 616 617 618 619
	var utypoff dwarf.Offset
	utypentry, err := reader.SeekToTypeNamed("<unspecified>")
	if err == nil {
		utypoff = utypentry.Offset
	}

620 621 622 623 624
	for entry, err := reader.NextPackageVariable(); entry != nil; entry, err = reader.NextPackageVariable() {
		if err != nil {
			return nil, err
		}

625 626 627 628
		if typoff, ok := entry.Val(dwarf.AttrType).(dwarf.Offset); !ok || typoff == utypoff {
			continue
		}

629
		// Ignore errors trying to extract values
A
aarzilli 已提交
630
		val, err := scope.extractVariableFromEntry(entry)
631 632 633
		if err != nil {
			continue
		}
A
Alessandro Arzilli 已提交
634
		val.loadValue(cfg)
635 636 637 638 639 640
		vars = append(vars, val)
	}

	return vars, nil
}

641
func (scope *EvalScope) packageVarAddr(name string) (*Variable, error) {
642
	for n, off := range scope.BinInfo.packageVars {
643
		if n == name || strings.HasSuffix(n, "/"+name) {
644 645 646 647 648 649
			reader := scope.DwarfReader()
			reader.Seek(off)
			entry, err := reader.Next()
			if err != nil {
				return nil, err
			}
A
aarzilli 已提交
650
			return scope.extractVarInfoFromEntry(entry)
651 652 653 654 655
		}
	}
	return nil, fmt.Errorf("could not find symbol value for %s", name)
}

656
func (v *Variable) structMember(memberName string) (*Variable, error) {
657 658 659 660
	if v.Unreadable != nil {
		return v.clone(), nil
	}
	structVar := v.maybeDereference()
661
	structVar.Name = v.Name
662 663
	if structVar.Unreadable != nil {
		return structVar, nil
664
	}
665 666

	switch t := structVar.RealType.(type) {
667
	case *godwarf.StructType:
668 669 670
		for _, field := range t.Field {
			if field.Name != memberName {
				continue
671
			}
L
Luke Hoban 已提交
672
			return structVar.toField(field)
673 674 675 676 677
		}
		// Check for embedded field only if field was
		// not a regular struct member
		for _, field := range t.Field {
			isEmbeddedStructMember :=
678 679
				field.Embedded ||
					(field.Type.Common().Name == field.Name) ||
D
Derek Parker 已提交
680 681
					(len(field.Name) > 1 &&
						field.Name[0] == '*' &&
682
						field.Type.Common().Name[1:] == field.Name[1:])
683 684 685 686 687 688
			if !isEmbeddedStructMember {
				continue
			}
			// Check for embedded field referenced by type name
			parts := strings.Split(field.Name, ".")
			if len(parts) > 1 && parts[1] == memberName {
L
Luke Hoban 已提交
689
				embeddedVar, err := structVar.toField(field)
690 691 692 693 694 695
				if err != nil {
					return nil, err
				}
				return embeddedVar, nil
			}
			// Recursively check for promoted fields on the embedded field
L
Luke Hoban 已提交
696
			embeddedVar, err := structVar.toField(field)
697 698 699 700
			if err != nil {
				return nil, err
			}
			embeddedVar.Name = structVar.Name
701
			embeddedField, _ := embeddedVar.structMember(memberName)
702 703
			if embeddedField != nil {
				return embeddedField, nil
704 705
			}
		}
706 707
		return nil, fmt.Errorf("%s has no member %s", v.Name, memberName)
	default:
708 709 710
		if v.Name == "" {
			return nil, fmt.Errorf("type %s is not a struct", structVar.TypeString())
		}
D
Derek Parker 已提交
711
		return nil, fmt.Errorf("%s (type %s) is not a struct", v.Name, structVar.TypeString())
712
	}
713 714
}

715 716
// Extracts the name and type of a variable from a dwarf entry
// then executes the instructions given in the  DW_AT_location attribute to grab the variable's address
A
aarzilli 已提交
717
func (scope *EvalScope) extractVarInfoFromEntry(entry *dwarf.Entry) (*Variable, error) {
E
epipho 已提交
718
	if entry == nil {
D
Derek Parker 已提交
719
		return nil, fmt.Errorf("invalid entry")
E
epipho 已提交
720 721 722 723 724 725 726 727
	}

	if entry.Tag != dwarf.TagFormalParameter && entry.Tag != dwarf.TagVariable {
		return nil, fmt.Errorf("invalid entry tag, only supports FormalParameter and Variable, got %s", entry.Tag.String())
	}

	n, ok := entry.Val(dwarf.AttrName).(string)
	if !ok {
D
Derek Parker 已提交
728
		return nil, fmt.Errorf("type assertion failed")
E
epipho 已提交
729 730 731 732
	}

	offset, ok := entry.Val(dwarf.AttrType).(dwarf.Offset)
	if !ok {
D
Derek Parker 已提交
733
		return nil, fmt.Errorf("type assertion failed")
E
epipho 已提交
734 735
	}

736
	t, err := scope.Type(offset)
E
epipho 已提交
737 738 739 740 741 742
	if err != nil {
		return nil, err
	}

	instructions, ok := entry.Val(dwarf.AttrLocation).([]byte)
	if !ok {
D
Derek Parker 已提交
743
		return nil, fmt.Errorf("type assertion failed")
E
epipho 已提交
744 745
	}

746
	addr, err := op.ExecuteStackProgram(scope.CFA, instructions)
E
epipho 已提交
747 748 749 750
	if err != nil {
		return nil, err
	}

751
	return scope.newVariable(n, uintptr(addr), t), nil
E
epipho 已提交
752 753
}

754
// If v is a pointer a new variable is returned containing the value pointed by v.
755 756 757 758
func (v *Variable) maybeDereference() *Variable {
	if v.Unreadable != nil {
		return v
	}
759

760
	switch t := v.RealType.(type) {
761
	case *godwarf.PtrType:
762 763
		ptrval, err := readUintRaw(v.mem, uintptr(v.Addr), t.ByteSize)
		r := v.newVariable("", uintptr(ptrval), t.Type)
764
		if err != nil {
765
			r.Unreadable = err
766 767
		}

768
		return r
769
	default:
770
		return v
771 772
	}
}
773

774
// Extracts the value of the variable at the given address.
775 776
func (v *Variable) loadValue(cfg LoadConfig) {
	v.loadValueInternal(0, cfg)
777 778
}

779
func (v *Variable) loadValueInternal(recurseLevel int, cfg LoadConfig) {
780
	if v.Unreadable != nil || v.loaded || (v.Addr == 0 && v.Base == 0) {
781 782
		return
	}
783

784 785
	v.loaded = true
	switch v.Kind {
A
aarzilli 已提交
786
	case reflect.Ptr, reflect.UnsafePointer:
787 788
		v.Len = 1
		v.Children = []Variable{*v.maybeDereference()}
789 790
		if cfg.FollowPointers {
			// Don't increase the recursion level when dereferencing pointers
791 792 793 794 795 796
			// unless this is a pointer to interface (which could cause an infinite loop)
			nextLvl := recurseLevel
			if v.Children[0].Kind == reflect.Interface {
				nextLvl++
			}
			v.Children[0].loadValueInternal(nextLvl, cfg)
797 798 799
		} else {
			v.Children[0].OnlyAddr = true
		}
800

A
aarzilli 已提交
801
	case reflect.Chan:
802
		sv := v.clone()
803
		sv.RealType = resolveTypedef(&(sv.RealType.(*godwarf.ChanType).TypedefType))
804
		sv = sv.maybeDereference()
805
		sv.loadValueInternal(0, loadFullValue)
A
aarzilli 已提交
806 807
		v.Children = sv.Children
		v.Len = sv.Len
808
		v.Base = sv.Addr
A
aarzilli 已提交
809

A
aarzilli 已提交
810
	case reflect.Map:
811 812
		if recurseLevel <= cfg.MaxVariableRecurse {
			v.loadMap(recurseLevel, cfg)
813 814 815
		} else {
			// loads length so that the client knows that the map isn't empty
			v.mapIterator()
A
aarzilli 已提交
816
		}
A
aarzilli 已提交
817

818
	case reflect.String:
819
		var val string
820
		val, v.Unreadable = readStringValue(v.mem, v.Base, v.Len, cfg)
821
		v.Value = constant.MakeString(val)
822 823

	case reflect.Slice, reflect.Array:
824
		v.loadArrayValues(recurseLevel, cfg)
825 826

	case reflect.Struct:
827
		v.mem = cacheMemory(v.mem, v.Addr, int(v.RealType.Size()))
828
		t := v.RealType.(*godwarf.StructType)
829 830 831
		v.Len = int64(len(t.Field))
		// Recursively call extractValue to grab
		// the value of all the members of the struct.
832
		if recurseLevel <= cfg.MaxVariableRecurse {
833 834
			v.Children = make([]Variable, 0, len(t.Field))
			for i, field := range t.Field {
835 836 837
				if cfg.MaxStructFields >= 0 && len(v.Children) >= cfg.MaxStructFields {
					break
				}
838 839 840
				f, _ := v.toField(field)
				v.Children = append(v.Children, *f)
				v.Children[i].Name = field.Name
841
				v.Children[i].loadValueInternal(recurseLevel+1, cfg)
842
			}
843 844
		}

845
	case reflect.Interface:
846
		v.loadInterface(recurseLevel, true, cfg)
847

848
	case reflect.Complex64, reflect.Complex128:
849
		v.readComplex(v.RealType.(*godwarf.ComplexType).ByteSize)
850
	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
851
		var val int64
852
		val, v.Unreadable = readIntRaw(v.mem, v.Addr, v.RealType.(*godwarf.IntType).ByteSize)
853
		v.Value = constant.MakeInt64(val)
854
	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
855
		var val uint64
856
		val, v.Unreadable = readUintRaw(v.mem, v.Addr, v.RealType.(*godwarf.UintType).ByteSize)
857 858
		v.Value = constant.MakeUint64(val)

859
	case reflect.Bool:
860 861
		val := make([]byte, 1)
		_, err := v.mem.ReadMemory(val, v.Addr)
862 863
		v.Unreadable = err
		if err == nil {
864
			v.Value = constant.MakeBool(val[0] != 0)
865
		}
866
	case reflect.Float32, reflect.Float64:
867
		var val float64
868
		val, v.Unreadable = v.readFloatRaw(v.RealType.(*godwarf.FloatType).ByteSize)
869
		v.Value = constant.MakeFloat64(val)
870 871 872 873 874 875 876 877
		switch {
		case math.IsInf(val, +1):
			v.FloatSpecial = FloatIsPosInf
		case math.IsInf(val, -1):
			v.FloatSpecial = FloatIsNegInf
		case math.IsNaN(val):
			v.FloatSpecial = FloatIsNaN
		}
878 879
	case reflect.Func:
		v.readFunctionPtr()
880
	default:
881
		v.Unreadable = fmt.Errorf("unknown or unsupported kind: \"%s\"", v.Kind.String())
882 883 884
	}
}

A
aarzilli 已提交
885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902
func (v *Variable) setValue(y *Variable) error {
	var err error
	switch v.Kind {
	case reflect.Float32, reflect.Float64:
		f, _ := constant.Float64Val(y.Value)
		err = v.writeFloatRaw(f, v.RealType.Size())
	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
		n, _ := constant.Int64Val(y.Value)
		err = v.writeUint(uint64(n), v.RealType.Size())
	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
		n, _ := constant.Uint64Val(y.Value)
		err = v.writeUint(n, v.RealType.Size())
	case reflect.Bool:
		err = v.writeBool(constant.BoolVal(y.Value))
	case reflect.Complex64, reflect.Complex128:
		real, _ := constant.Float64Val(constant.Real(y.Value))
		imag, _ := constant.Float64Val(constant.Imag(y.Value))
		err = v.writeComplex(real, imag, v.RealType.Size())
903
	default:
904
		if t, isptr := v.RealType.(*godwarf.PtrType); isptr {
905
			err = v.writeUint(uint64(y.Children[0].Addr), int64(t.ByteSize))
A
aarzilli 已提交
906 907 908
		} else {
			return fmt.Errorf("can not set variables of type %s (not implemented)", v.Kind.String())
		}
909
	}
A
aarzilli 已提交
910 911

	return err
912 913
}

914
func readStringInfo(mem MemoryReadWriter, arch Arch, addr uintptr) (uintptr, int64, error) {
915 916 917
	// string data structure is always two ptrs in size. Addr, followed by len
	// http://research.swtch.com/godata

918 919
	mem = cacheMemory(mem, addr, arch.PtrSize()*2)

920
	// read len
921 922
	val := make([]byte, arch.PtrSize())
	_, err := mem.ReadMemory(val, addr+uintptr(arch.PtrSize()))
923
	if err != nil {
A
aarzilli 已提交
924
		return 0, 0, fmt.Errorf("could not read string len %s", err)
925
	}
926
	strlen := int64(binary.LittleEndian.Uint64(val))
927
	if strlen < 0 {
A
aarzilli 已提交
928
		return 0, 0, fmt.Errorf("invalid length: %d", strlen)
929
	}
930 931

	// read addr
932
	_, err = mem.ReadMemory(val, addr)
933
	if err != nil {
A
aarzilli 已提交
934
		return 0, 0, fmt.Errorf("could not read string pointer %s", err)
935 936
	}
	addr = uintptr(binary.LittleEndian.Uint64(val))
D
Derek Parker 已提交
937
	if addr == 0 {
A
aarzilli 已提交
938
		return 0, 0, nil
D
Derek Parker 已提交
939
	}
D
Derek Parker 已提交
940

A
aarzilli 已提交
941 942 943
	return addr, strlen, nil
}

944
func readStringValue(mem MemoryReadWriter, addr uintptr, strlen int64, cfg LoadConfig) (string, error) {
A
aarzilli 已提交
945
	count := strlen
946 947
	if count > int64(cfg.MaxStringLen) {
		count = int64(cfg.MaxStringLen)
A
aarzilli 已提交
948 949
	}

950 951
	val := make([]byte, int(count))
	_, err := mem.ReadMemory(val, addr)
952
	if err != nil {
A
aarzilli 已提交
953
		return "", fmt.Errorf("could not read string at %#v due to %s", addr, err)
954 955
	}

956 957
	retstr := *(*string)(unsafe.Pointer(&val))

A
aarzilli 已提交
958 959 960
	return retstr, nil
}

961
func (v *Variable) loadSliceInfo(t *godwarf.SliceType) {
962 963
	v.mem = cacheMemory(v.mem, v.Addr, int(t.Size()))

964
	var err error
E
epipho 已提交
965 966 967
	for _, f := range t.Field {
		switch f.Name {
		case "array":
968
			var base uint64
969
			base, err = readUintRaw(v.mem, uintptr(int64(v.Addr)+f.ByteOffset), f.Type.Size())
970
			if err == nil {
971
				v.Base = uintptr(base)
972
				// Dereference array type to get value type
973
				ptrType, ok := f.Type.(*godwarf.PtrType)
974
				if !ok {
975 976
					v.Unreadable = fmt.Errorf("Invalid type %s in slice array", f.Type)
					return
977 978
				}
				v.fieldType = ptrType.Type
E
epipho 已提交
979 980
			}
		case "len":
981
			lstrAddr, _ := v.toField(f)
982
			lstrAddr.loadValue(loadSingleValue)
983
			err = lstrAddr.Unreadable
984
			if err == nil {
985
				v.Len, _ = constant.Int64Val(lstrAddr.Value)
E
epipho 已提交
986 987
			}
		case "cap":
988
			cstrAddr, _ := v.toField(f)
989
			cstrAddr.loadValue(loadSingleValue)
990
			err = cstrAddr.Unreadable
991
			if err == nil {
992
				v.Cap, _ = constant.Int64Val(cstrAddr.Value)
E
epipho 已提交
993 994
			}
		}
995 996 997 998
		if err != nil {
			v.Unreadable = err
			return
		}
999 1000
	}

1001
	v.stride = v.fieldType.Size()
1002
	if t, ok := v.fieldType.(*godwarf.PtrType); ok {
1003
		v.stride = t.ByteSize
1004 1005 1006
	}
}

1007
func (v *Variable) loadArrayValues(recurseLevel int, cfg LoadConfig) {
1008 1009 1010
	if v.Unreadable != nil {
		return
	}
1011 1012 1013 1014
	if v.Len < 0 {
		v.Unreadable = errors.New("Negative array length")
		return
	}
1015

1016 1017
	count := v.Len
	// Cap number of elements
1018 1019
	if count > int64(cfg.MaxArrayValues) {
		count = int64(cfg.MaxArrayValues)
1020
	}
1021

1022
	if v.stride < maxArrayStridePrefetch {
1023
		v.mem = cacheMemory(v.mem, v.Base, int(v.stride*count))
1024
	}
1025

1026 1027 1028
	errcount := 0

	for i := int64(0); i < count; i++ {
1029
		fieldvar := v.newVariable("", uintptr(int64(v.Base)+(i*v.stride)), v.fieldType)
1030
		fieldvar.loadValueInternal(recurseLevel+1, cfg)
1031 1032

		if fieldvar.Unreadable != nil {
1033
			errcount++
E
epipho 已提交
1034
		}
1035

1036
		v.Children = append(v.Children, *fieldvar)
1037 1038 1039
		if errcount > maxErrCount {
			break
		}
1040 1041 1042
	}
}

1043
func (v *Variable) readComplex(size int64) {
1044 1045 1046 1047 1048 1049 1050
	var fs int64
	switch size {
	case 8:
		fs = 4
	case 16:
		fs = 8
	default:
1051 1052
		v.Unreadable = fmt.Errorf("invalid size (%d) for complex type", size)
		return
1053
	}
1054

1055
	ftyp := &godwarf.FloatType{BasicType: godwarf.BasicType{CommonType: godwarf.CommonType{ByteSize: fs, Name: fmt.Sprintf("float%d", fs)}, BitSize: fs * 8, BitOffset: 0}}
1056

1057 1058
	realvar := v.newVariable("real", v.Addr, ftyp)
	imagvar := v.newVariable("imaginary", v.Addr+uintptr(fs), ftyp)
1059 1060
	realvar.loadValue(loadSingleValue)
	imagvar.loadValue(loadSingleValue)
A
aarzilli 已提交
1061
	v.Value = constant.BinaryOp(realvar.Value, token.ADD, constant.MakeImag(imagvar.Value))
1062 1063
}

A
aarzilli 已提交
1064 1065
func (v *Variable) writeComplex(real, imag float64, size int64) error {
	err := v.writeFloatRaw(real, int64(size/2))
1066 1067 1068 1069 1070 1071 1072 1073
	if err != nil {
		return err
	}
	imagaddr := *v
	imagaddr.Addr += uintptr(size / 2)
	return imagaddr.writeFloatRaw(imag, int64(size/2))
}

1074
func readIntRaw(mem MemoryReadWriter, addr uintptr, size int64) (int64, error) {
E
epipho 已提交
1075
	var n int64
1076

1077 1078
	val := make([]byte, int(size))
	_, err := mem.ReadMemory(val, addr)
1079
	if err != nil {
D
Derek Parker 已提交
1080
		return 0, err
1081 1082
	}

1083 1084
	switch size {
	case 1:
1085
		n = int64(int8(val[0]))
1086
	case 2:
1087
		n = int64(int16(binary.LittleEndian.Uint16(val)))
1088
	case 4:
1089
		n = int64(int32(binary.LittleEndian.Uint32(val)))
1090
	case 8:
E
epipho 已提交
1091
		n = int64(binary.LittleEndian.Uint64(val))
1092
	}
1093

D
Derek Parker 已提交
1094
	return n, nil
E
epipho 已提交
1095 1096
}

A
aarzilli 已提交
1097
func (v *Variable) writeUint(value uint64, size int64) error {
1098 1099 1100 1101
	val := make([]byte, size)

	switch size {
	case 1:
A
aarzilli 已提交
1102
		val[0] = byte(value)
1103
	case 2:
A
aarzilli 已提交
1104
		binary.LittleEndian.PutUint16(val, uint16(value))
1105
	case 4:
A
aarzilli 已提交
1106
		binary.LittleEndian.PutUint32(val, uint32(value))
1107
	case 8:
A
aarzilli 已提交
1108
		binary.LittleEndian.PutUint64(val, uint64(value))
1109 1110
	}

1111
	_, err := v.mem.WriteMemory(v.Addr, val)
1112 1113 1114
	return err
}

1115
func readUintRaw(mem MemoryReadWriter, addr uintptr, size int64) (uint64, error) {
E
epipho 已提交
1116 1117
	var n uint64

1118 1119
	val := make([]byte, int(size))
	_, err := mem.ReadMemory(val, addr)
E
epipho 已提交
1120
	if err != nil {
D
Derek Parker 已提交
1121
		return 0, err
E
epipho 已提交
1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134
	}

	switch size {
	case 1:
		n = uint64(val[0])
	case 2:
		n = uint64(binary.LittleEndian.Uint16(val))
	case 4:
		n = uint64(binary.LittleEndian.Uint32(val))
	case 8:
		n = uint64(binary.LittleEndian.Uint64(val))
	}

D
Derek Parker 已提交
1135
	return n, nil
1136 1137
}

1138
func (v *Variable) readFloatRaw(size int64) (float64, error) {
1139 1140
	val := make([]byte, int(size))
	_, err := v.mem.ReadMemory(val, v.Addr)
1141
	if err != nil {
1142
		return 0.0, err
1143 1144 1145
	}
	buf := bytes.NewBuffer(val)

D
Derek Parker 已提交
1146 1147 1148 1149
	switch size {
	case 4:
		n := float32(0)
		binary.Read(buf, binary.LittleEndian, &n)
1150
		return float64(n), nil
D
Derek Parker 已提交
1151 1152 1153
	case 8:
		n := float64(0)
		binary.Read(buf, binary.LittleEndian, &n)
1154
		return n, nil
D
Derek Parker 已提交
1155 1156
	}

1157
	return 0.0, fmt.Errorf("could not read float")
1158 1159
}

1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171
func (v *Variable) writeFloatRaw(f float64, size int64) error {
	buf := bytes.NewBuffer(make([]byte, 0, size))

	switch size {
	case 4:
		n := float32(f)
		binary.Write(buf, binary.LittleEndian, n)
	case 8:
		n := float64(f)
		binary.Write(buf, binary.LittleEndian, n)
	}

1172
	_, err := v.mem.WriteMemory(v.Addr, buf.Bytes())
1173 1174 1175
	return err
}

A
aarzilli 已提交
1176
func (v *Variable) writeBool(value bool) error {
1177
	val := []byte{0}
A
aarzilli 已提交
1178
	val[0] = *(*byte)(unsafe.Pointer(&value))
1179
	_, err := v.mem.WriteMemory(v.Addr, val)
1180 1181 1182
	return err
}

1183
func (v *Variable) readFunctionPtr() {
1184
	val := make([]byte, v.bi.Arch.PtrSize())
1185
	_, err := v.mem.ReadMemory(val, v.Addr)
1186
	if err != nil {
1187 1188
		v.Unreadable = err
		return
1189 1190 1191
	}

	// dereference pointer to find function pc
1192 1193
	fnaddr := uintptr(binary.LittleEndian.Uint64(val))
	if fnaddr == 0 {
1194
		v.Base = 0
A
aarzilli 已提交
1195
		v.Value = constant.MakeString("")
1196
		return
1197
	}
1198

1199
	_, err = v.mem.ReadMemory(val, fnaddr)
1200
	if err != nil {
1201 1202
		v.Unreadable = err
		return
1203 1204
	}

1205
	v.Base = uintptr(binary.LittleEndian.Uint64(val))
1206
	fn := v.bi.goSymTable.PCToFunc(uint64(v.Base))
1207
	if fn == nil {
1208
		v.Unreadable = fmt.Errorf("could not find function for %#v", v.Base)
1209
		return
1210 1211
	}

1212
	v.Value = constant.MakeString(fn.Name)
1213 1214
}

1215
func (v *Variable) loadMap(recurseLevel int, cfg LoadConfig) {
A
aarzilli 已提交
1216 1217 1218 1219 1220 1221 1222
	it := v.mapIterator()
	if it == nil {
		return
	}

	for skip := 0; skip < v.mapSkip; skip++ {
		if ok := it.next(); !ok {
1223
			v.Unreadable = fmt.Errorf("map index out of bounds")
A
aarzilli 已提交
1224 1225 1226 1227 1228 1229 1230
			return
		}
	}

	count := 0
	errcount := 0
	for it.next() {
1231
		if count >= cfg.MaxArrayValues {
A
aarzilli 已提交
1232 1233 1234
			break
		}
		key := it.key()
1235 1236 1237 1238 1239 1240
		var val *Variable
		if it.values.fieldType.Size() > 0 {
			val = it.value()
		} else {
			val = v.newVariable("", it.values.Addr, it.values.fieldType)
		}
1241 1242
		key.loadValueInternal(recurseLevel+1, cfg)
		val.loadValueInternal(recurseLevel+1, cfg)
A
aarzilli 已提交
1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273
		if key.Unreadable != nil || val.Unreadable != nil {
			errcount++
		}
		v.Children = append(v.Children, *key)
		v.Children = append(v.Children, *val)
		count++
		if errcount > maxErrCount {
			break
		}
	}
}

type mapIterator struct {
	v          *Variable
	numbuckets uint64
	oldmask    uint64
	buckets    *Variable
	oldbuckets *Variable
	b          *Variable
	bidx       uint64

	tophashes *Variable
	keys      *Variable
	values    *Variable
	overflow  *Variable

	idx int64
}

// Code derived from go/src/runtime/hashmap.go
func (v *Variable) mapIterator() *mapIterator {
1274
	sv := v.clone()
1275
	sv.RealType = resolveTypedef(&(sv.RealType.(*godwarf.MapType).TypedefType))
1276
	sv = sv.maybeDereference()
1277
	v.Base = sv.Addr
A
aarzilli 已提交
1278

1279
	maptype, ok := sv.RealType.(*godwarf.StructType)
A
aarzilli 已提交
1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291
	if !ok {
		v.Unreadable = fmt.Errorf("wrong real type for map")
		return nil
	}

	it := &mapIterator{v: v, bidx: 0, b: nil, idx: 0}

	if sv.Addr == 0 {
		it.numbuckets = 0
		return it
	}

1292
	v.mem = cacheMemory(v.mem, v.Base, int(v.RealType.Size()))
1293

A
aarzilli 已提交
1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315
	for _, f := range maptype.Field {
		var err error
		field, _ := sv.toField(f)
		switch f.Name {
		case "count":
			v.Len, err = field.asInt()
		case "B":
			var b uint64
			b, err = field.asUint()
			it.numbuckets = 1 << b
			it.oldmask = (1 << (b - 1)) - 1
		case "buckets":
			it.buckets = field.maybeDereference()
		case "oldbuckets":
			it.oldbuckets = field.maybeDereference()
		}
		if err != nil {
			v.Unreadable = err
			return nil
		}
	}

1316 1317 1318 1319 1320
	if it.buckets.Kind != reflect.Struct || it.oldbuckets.Kind != reflect.Struct {
		v.Unreadable = mapBucketsNotStructErr
		return nil
	}

A
aarzilli 已提交
1321 1322 1323
	return it
}

1324 1325 1326 1327
var mapBucketContentsNotArrayErr = errors.New("malformed map type: keys, values or tophash of a bucket is not an array")
var mapBucketContentsInconsistentLenErr = errors.New("malformed map type: inconsistent array length in bucket")
var mapBucketsNotStructErr = errors.New("malformed map type: buckets, oldbuckets or overflow field not a struct")

A
aarzilli 已提交
1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378
func (it *mapIterator) nextBucket() bool {
	if it.overflow != nil && it.overflow.Addr > 0 {
		it.b = it.overflow
	} else {
		it.b = nil

		for it.bidx < it.numbuckets {
			it.b = it.buckets.clone()
			it.b.Addr += uintptr(uint64(it.buckets.DwarfType.Size()) * it.bidx)

			if it.oldbuckets.Addr <= 0 {
				break
			}

			// if oldbuckets is not nil we are iterating through a map that is in
			// the middle of a grow.
			// if the bucket we are looking at hasn't been filled in we iterate
			// instead through its corresponding "oldbucket" (i.e. the bucket the
			// elements of this bucket are coming from) but only if this is the first
			// of the two buckets being created from the same oldbucket (otherwise we
			// would print some keys twice)

			oldbidx := it.bidx & it.oldmask
			oldb := it.oldbuckets.clone()
			oldb.Addr += uintptr(uint64(it.oldbuckets.DwarfType.Size()) * oldbidx)

			if mapEvacuated(oldb) {
				break
			}

			if oldbidx == it.bidx {
				it.b = oldb
				break
			}

			// oldbucket origin for current bucket has not been evacuated but we have already
			// iterated over it so we should just skip it
			it.b = nil
			it.bidx++
		}

		if it.b == nil {
			return false
		}
		it.bidx++
	}

	if it.b.Addr <= 0 {
		return false
	}

1379 1380
	it.b.mem = cacheMemory(it.b.mem, it.b.Addr, int(it.b.RealType.Size()))

A
aarzilli 已提交
1381 1382 1383 1384 1385
	it.tophashes = nil
	it.keys = nil
	it.values = nil
	it.overflow = nil

1386
	for _, f := range it.b.DwarfType.(*godwarf.StructType).Field {
A
aarzilli 已提交
1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415
		field, err := it.b.toField(f)
		if err != nil {
			it.v.Unreadable = err
			return false
		}
		if field.Unreadable != nil {
			it.v.Unreadable = field.Unreadable
			return false
		}

		switch f.Name {
		case "tophash":
			it.tophashes = field
		case "keys":
			it.keys = field
		case "values":
			it.values = field
		case "overflow":
			it.overflow = field.maybeDereference()
		}
	}

	// sanity checks
	if it.tophashes == nil || it.keys == nil || it.values == nil {
		it.v.Unreadable = fmt.Errorf("malformed map type")
		return false
	}

	if it.tophashes.Kind != reflect.Array || it.keys.Kind != reflect.Array || it.values.Kind != reflect.Array {
1416
		it.v.Unreadable = mapBucketContentsNotArrayErr
A
aarzilli 已提交
1417 1418 1419
		return false
	}

1420 1421 1422 1423 1424 1425 1426 1427
	if it.tophashes.Len != it.keys.Len {
		it.v.Unreadable = mapBucketContentsInconsistentLenErr
		return false
	}

	if it.values.fieldType.Size() > 0 && it.tophashes.Len != it.values.Len {
		// if the type of the value is zero-sized (i.e. struct{}) then the values
		// array's length is zero.
1428 1429 1430 1431 1432 1433
		it.v.Unreadable = mapBucketContentsInconsistentLenErr
		return false
	}

	if it.overflow.Kind != reflect.Struct {
		it.v.Unreadable = mapBucketsNotStructErr
A
aarzilli 已提交
1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475
		return false
	}

	return true
}

func (it *mapIterator) next() bool {
	for {
		if it.b == nil || it.idx >= it.tophashes.Len {
			r := it.nextBucket()
			if !r {
				return false
			}
			it.idx = 0
		}
		tophash, _ := it.tophashes.sliceAccess(int(it.idx))
		h, err := tophash.asUint()
		if err != nil {
			it.v.Unreadable = fmt.Errorf("unreadable tophash: %v", err)
			return false
		}
		it.idx++
		if h != hashTophashEmpty {
			return true
		}
	}
}

func (it *mapIterator) key() *Variable {
	k, _ := it.keys.sliceAccess(int(it.idx - 1))
	return k
}

func (it *mapIterator) value() *Variable {
	v, _ := it.values.sliceAccess(int(it.idx - 1))
	return v
}

func mapEvacuated(b *Variable) bool {
	if b.Addr == 0 {
		return true
	}
1476
	for _, f := range b.DwarfType.(*godwarf.StructType).Field {
A
aarzilli 已提交
1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490
		if f.Name != "tophash" {
			continue
		}
		tophashes, _ := b.toField(f)
		tophash0var, _ := tophashes.sliceAccess(0)
		tophash0, err := tophash0var.asUint()
		if err != nil {
			return true
		}
		return tophash0 > hashTophashEmpty && tophash0 < hashMinTopHash
	}
	return true
}

1491
func (v *Variable) loadInterface(recurseLevel int, loadData bool, cfg LoadConfig) {
1492
	var _type, typestring, data *Variable
1493
	var typ godwarf.Type
A
Alessandro Arzilli 已提交
1494
	var err error
1495 1496
	isnil := false

A
Alessandro Arzilli 已提交
1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523
	// An interface variable is implemented either by a runtime.iface
	// struct or a runtime.eface struct. The difference being that empty
	// interfaces (i.e. "interface {}") are represented by runtime.eface
	// and non-empty interfaces by runtime.iface.
	//
	// For both runtime.ifaces and runtime.efaces the data is stored in v.data
	//
	// The concrete type however is stored in v.tab._type for non-empty
	// interfaces and in v._type for empty interfaces.
	//
	// For nil empty interface variables _type will be nil, for nil
	// non-empty interface variables tab will be nil
	//
	// In either case the _type field is a pointer to a runtime._type struct.
	//
	// Before go1.7 _type used to have a field named 'string' containing
	// the name of the type. Since go1.7 the field has been replaced by a
	// str field that contains an offset in the module data, the concrete
	// type must be calculated using the str address along with the value
	// of v.tab._type (v._type for empty interfaces).
	//
	// The following code works for both runtime.iface and runtime.eface
	// and sets the go17 flag when the 'string' field can not be found
	// but the str field was found

	go17 := false

1524 1525
	v.mem = cacheMemory(v.mem, v.Addr, int(v.RealType.Size()))

1526
	ityp := resolveTypedef(&v.RealType.(*godwarf.InterfaceType).TypedefType).(*godwarf.StructType)
1527 1528

	for _, f := range ityp.Field {
1529 1530 1531
		switch f.Name {
		case "tab": // for runtime.iface
			tab, _ := v.toField(f)
A
Alessandro Arzilli 已提交
1532 1533 1534 1535 1536
			tab = tab.maybeDereference()
			isnil = tab.Addr == 0
			if !isnil {
				_type, err = tab.structMember("_type")
				if err != nil {
1537 1538 1539 1540
					v.Unreadable = fmt.Errorf("invalid interface type: %v", err)
					return
				}
				typestring, err = _type.structMember("_string")
A
Alessandro Arzilli 已提交
1541 1542 1543 1544
				if err == nil {
					typestring = typestring.maybeDereference()
				} else {
					go17 = true
1545 1546 1547
				}
			}
		case "_type": // for runtime.eface
A
Alessandro Arzilli 已提交
1548 1549 1550 1551 1552 1553 1554 1555 1556
			_type, _ = v.toField(f)
			_type = _type.maybeDereference()
			isnil = _type.Addr == 0
			if !isnil {
				typestring, err = _type.structMember("_string")
				if err == nil {
					typestring = typestring.maybeDereference()
				} else {
					go17 = true
1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567
				}
			}
		case "data":
			data, _ = v.toField(f)
		}
	}

	if isnil {
		// interface to nil
		data = data.maybeDereference()
		v.Children = []Variable{*data}
A
aarzilli 已提交
1568
		if loadData {
1569
			v.Children[0].loadValueInternal(recurseLevel, cfg)
A
aarzilli 已提交
1570
		}
1571 1572 1573
		return
	}

A
Alessandro Arzilli 已提交
1574
	if data == nil {
1575 1576 1577
		v.Unreadable = fmt.Errorf("invalid interface type")
		return
	}
A
Alessandro Arzilli 已提交
1578

1579 1580
	var kind int64

A
Alessandro Arzilli 已提交
1581 1582 1583
	if go17 {
		// No 'string' field use 'str' and 'runtime.firstmoduledata' to
		// find out what the concrete type is
1584
		_type = _type.maybeDereference()
A
Alessandro Arzilli 已提交
1585

1586 1587
		var typename string
		typename, kind, err = nameOfRuntimeType(_type)
A
Alessandro Arzilli 已提交
1588 1589 1590 1591 1592
		if err != nil {
			v.Unreadable = fmt.Errorf("invalid interface type: %v", err)
			return
		}

1593
		typ, err = v.bi.findType(typename)
A
Alessandro Arzilli 已提交
1594
		if err != nil {
1595
			v.Unreadable = fmt.Errorf("interface type %q not found for %#x: %v", typename, data.Addr, err)
1596
			return
A
Alessandro Arzilli 已提交
1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608
		}
	} else {
		if typestring == nil || typestring.Addr == 0 || typestring.Kind != reflect.String {
			v.Unreadable = fmt.Errorf("invalid interface type")
			return
		}
		typestring.loadValue(LoadConfig{false, 0, 512, 0, 0})
		if typestring.Unreadable != nil {
			v.Unreadable = fmt.Errorf("invalid interface type: %v", typestring.Unreadable)
			return
		}

1609
		typename := constant.StringVal(typestring.Value)
1610

1611 1612 1613 1614 1615
		t, err := parser.ParseExpr(typename)
		if err != nil {
			v.Unreadable = fmt.Errorf("invalid interface type, unparsable data type: %v", err)
			return
		}
1616

1617
		typ, err = v.bi.findTypeExpr(t)
1618 1619 1620 1621
		if err != nil {
			v.Unreadable = fmt.Errorf("interface type %q not found for %#x: %v", typename, data.Addr, err)
			return
		}
1622 1623
	}

1624
	deref := false
1625 1626
	if kind&kindDirectIface == 0 {
		realtyp := resolveTypedef(typ)
1627
		if _, isptr := realtyp.(*godwarf.PtrType); !isptr {
1628
			typ = pointerTo(typ, v.bi.Arch)
1629
			deref = true
1630
		}
1631 1632
	}

1633
	data = data.newVariable("data", data.Addr, typ)
1634 1635 1636 1637
	if deref {
		data = data.maybeDereference()
		data.Name = "data"
	}
1638 1639

	v.Children = []Variable{*data}
1640
	if loadData && recurseLevel <= cfg.MaxVariableRecurse {
1641 1642 1643
		v.Children[0].loadValueInternal(recurseLevel, cfg)
	} else {
		v.Children[0].OnlyAddr = true
1644 1645 1646
	}
}

A
aarzilli 已提交
1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660
type variablesByDepth struct {
	vars   []*Variable
	depths []int
}

func (v *variablesByDepth) Len() int { return len(v.vars) }

func (v *variablesByDepth) Less(i int, j int) bool { return v.depths[i] < v.depths[j] }

func (v *variablesByDepth) Swap(i int, j int) {
	v.depths[i], v.depths[j] = v.depths[j], v.depths[i]
	v.vars[i], v.vars[j] = v.vars[j], v.vars[i]
}

E
epipho 已提交
1661
// Fetches all variables of a specific type in the current function scope
A
aarzilli 已提交
1662
func (scope *EvalScope) variablesByTag(tag dwarf.Tag, cfg *LoadConfig) ([]*Variable, error) {
1663
	off, err := scope.BinInfo.findFunctionDebugInfo(scope.PC)
1664
	if err != nil {
E
epipho 已提交
1665 1666 1667
		return nil, err
	}

D
Derek Parker 已提交
1668
	var vars []*Variable
A
aarzilli 已提交
1669 1670 1671 1672 1673 1674 1675 1676 1677
	var depths []int
	varReader := reader.Variables(scope.BinInfo.dwarf, off, scope.PC, tag == dwarf.TagVariable)
	hasScopes := false
	for varReader.Next() {
		entry := varReader.Entry()
		if entry.Tag != tag {
			continue
		}
		val, err := scope.extractVariableFromEntry(entry)
E
epipho 已提交
1678
		if err != nil {
A
aarzilli 已提交
1679 1680
			// skip variables that we can't parse yet
			continue
E
epipho 已提交
1681
		}
A
aarzilli 已提交
1682 1683 1684 1685 1686
		vars = append(vars, val)
		depth := varReader.Depth()
		depths = append(depths, depth)
		if depth > 1 {
			hasScopes = true
A
Alessandro Arzilli 已提交
1687
		}
A
aarzilli 已提交
1688
	}
E
epipho 已提交
1689

A
aarzilli 已提交
1690 1691
	if err := varReader.Err(); err != nil {
		return nil, err
E
epipho 已提交
1692
	}
A
aarzilli 已提交
1693

A
Alessandro Arzilli 已提交
1694 1695 1696 1697
	if len(vars) <= 0 {
		return vars, nil
	}

A
aarzilli 已提交
1698 1699 1700 1701
	if hasScopes {
		sort.Stable(&variablesByDepth{vars, depths})
	}

A
Alessandro Arzilli 已提交
1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731
	// prefetch the whole chunk of memory relative to these variables

	minaddr := vars[0].Addr
	var maxaddr uintptr
	var size int64

	for _, v := range vars {
		if v.Addr < minaddr {
			minaddr = v.Addr
		}

		size += v.DwarfType.Size()

		if end := v.Addr + uintptr(v.DwarfType.Size()); end > maxaddr {
			maxaddr = end
		}
	}

	// check that we aren't trying to cache too much memory: we shouldn't
	// exceed the real size of the variables by more than the number of
	// variables times the size of an architecture pointer (to allow for memory
	// alignment).
	if int64(maxaddr-minaddr)-size <= int64(len(vars))*int64(scope.PtrSize()) {
		mem := cacheMemory(vars[0].mem, minaddr, int(maxaddr-minaddr))

		for _, v := range vars {
			v.mem = mem
		}
	}

A
aarzilli 已提交
1732 1733
	lvn := map[string]*Variable{} // lvn[n] is the last variable we saw named n

1734 1735 1736 1737 1738 1739 1740
	for i, v := range vars {
		if name := v.Name; len(name) > 1 && name[0] == '&' {
			v = v.maybeDereference()
			v.Name = name[1:]
			v.Flags |= VariableEscaped
			vars[i] = v
		}
A
aarzilli 已提交
1741 1742 1743 1744 1745 1746 1747 1748 1749
		if hasScopes {
			if otherv := lvn[v.Name]; otherv != nil {
				otherv.Flags |= VariableShadowed
			}
			lvn[v.Name] = v
		}
		if cfg != nil {
			v.loadValue(*cfg)
		}
A
Alessandro Arzilli 已提交
1750
	}
E
epipho 已提交
1751 1752 1753

	return vars, nil
}