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

import (
	"bytes"
	"encoding/binary"
6
	"errors"
7
	"fmt"
8
	"go/constant"
9 10
	"go/parser"
	"go/token"
11
	"math"
12
	"reflect"
13 14 15
	"strings"
	"unsafe"

D
Derek Parker 已提交
16 17
	"github.com/derekparker/delve/pkg/dwarf/op"
	"github.com/derekparker/delve/pkg/dwarf/reader"
18
	"golang.org/x/debug/dwarf"
19 20
)

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

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

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

	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
31 32
)

33 34 35 36 37 38 39 40 41
type FloatSpecial uint8

const (
	FloatIsNormal FloatSpecial = iota
	FloatIsNaN
	FloatIsPosInf
	FloatIsNegInf
)

D
Derek Parker 已提交
42 43 44 45
// 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.
46
type Variable struct {
47
	Addr      uintptr
A
aarzilli 已提交
48
	OnlyAddr  bool
49
	Name      string
50 51 52
	DwarfType dwarf.Type
	RealType  dwarf.Type
	Kind      reflect.Kind
53 54
	mem       memoryReadWriter
	dbp       *Process
55

56 57
	Value        constant.Value
	FloatSpecial FloatSpecial
58 59 60 61

	Len int64
	Cap int64

62 63
	// 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 已提交
64
	// address of the struct backing chan and map variables
A
aarzilli 已提交
65
	// address of the function entry point for function variables (0 for nil function pointers)
66
	Base      uintptr
67 68
	stride    int64
	fieldType dwarf.Type
69

A
aarzilli 已提交
70 71 72
	// number of elements to skip when loading a map
	mapSkip int

73 74 75 76
	Children []Variable

	loaded     bool
	Unreadable error
77 78
}

79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94
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 已提交
95
// M represents a runtime M (OS thread) structure.
96
type M struct {
97 98 99 100
	procid   int     // Thread ID or port.
	spinning uint8   // Busy looping.
	blocked  uint8   // Waiting on futex / semaphore.
	curg     uintptr // Current G running on this thread.
101 102
}

D
Derek Parker 已提交
103
// G status, from: src/runtime/runtime2.go
104
const (
D
Derek Parker 已提交
105 106 107 108 109 110 111 112 113
	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
114 115
)

D
Derek Parker 已提交
116
// G represents a runtime G (goroutine) structure (at least the
117
// fields that Delve is interested in).
D
Derek Parker 已提交
118
type G struct {
D
Derek Parker 已提交
119
	ID         int    // Goroutine ID
120 121 122 123
	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.
124
	Status     uint64
A
Alessandro Arzilli 已提交
125 126
	stkbarVar  *Variable // stkbar field of g struct
	stkbarPos  int       // stkbarPos field of g struct
127

128
	// Information on goroutine location
129
	CurrentLoc Location
130

A
aarzilli 已提交
131 132
	// Thread that this goroutine is currently allocated to
	thread *Thread
133

A
Alessandro Arzilli 已提交
134 135
	variable *Variable
	dbp      *Process
136 137
}

D
Derek Parker 已提交
138 139
// EvalScope is the scope for variable evaluation. Contains the thread,
// current location (PC), and canonical frame address.
140 141 142 143 144 145
type EvalScope struct {
	Thread *Thread
	PC     uint64
	CFA    int64
}

D
Derek Parker 已提交
146
// IsNilErr is returned when a variable is nil.
147 148 149 150 151 152 153 154
type IsNilErr struct {
	name string
}

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

155 156 157 158
func (scope *EvalScope) newVariable(name string, addr uintptr, dwarfType dwarf.Type) *Variable {
	return newVariable(name, addr, dwarfType, scope.Thread.dbp, scope.Thread)
}

159 160 161 162
func (t *Thread) newVariable(name string, addr uintptr, dwarfType dwarf.Type) *Variable {
	return newVariable(name, addr, dwarfType, t.dbp, t)
}

163 164 165 166 167
func (v *Variable) newVariable(name string, addr uintptr, dwarfType dwarf.Type) *Variable {
	return newVariable(name, addr, dwarfType, v.dbp, v.mem)
}

func newVariable(name string, addr uintptr, dwarfType dwarf.Type, dbp *Process, mem memoryReadWriter) *Variable {
168 169 170
	v := &Variable{
		Name:      name,
		Addr:      addr,
171
		DwarfType: dwarfType,
172 173
		mem:       mem,
		dbp:       dbp,
174 175
	}

176
	v.RealType = resolveTypedef(v.DwarfType)
177 178 179

	switch t := v.RealType.(type) {
	case *dwarf.PtrType:
180 181 182
		v.Kind = reflect.Ptr
		if _, isvoid := t.Type.(*dwarf.VoidType); isvoid {
			v.Kind = reflect.UnsafePointer
183
		}
184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203
	case *dwarf.ChanType:
		v.Kind = reflect.Chan
	case *dwarf.MapType:
		v.Kind = reflect.Map
	case *dwarf.StringType:
		v.Kind = reflect.String
		v.stride = 1
		v.fieldType = &dwarf.UintType{BasicType: dwarf.BasicType{CommonType: dwarf.CommonType{ByteSize: 1, Name: "byte"}, BitSize: 8, BitOffset: 0}}
		if v.Addr != 0 {
			v.Base, v.Len, v.Unreadable = readStringInfo(v.mem, v.dbp.arch, v.Addr)
		}
	case *dwarf.SliceType:
		v.Kind = reflect.Slice
		if v.Addr != 0 {
			v.loadSliceInfo(t)
		}
	case *dwarf.InterfaceType:
		v.Kind = reflect.Interface
	case *dwarf.StructType:
		v.Kind = reflect.Struct
204
	case *dwarf.ArrayType:
205
		v.Kind = reflect.Array
206
		v.Base = v.Addr
207 208 209 210 211 212 213 214
		v.Len = t.Count
		v.Cap = -1
		v.fieldType = t.Type
		v.stride = 0

		if t.Count > 0 {
			v.stride = t.ByteSize / t.Count
		}
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
	case *dwarf.ComplexType:
		switch t.ByteSize {
		case 8:
			v.Kind = reflect.Complex64
		case 16:
			v.Kind = reflect.Complex128
		}
	case *dwarf.IntType:
		v.Kind = reflect.Int
	case *dwarf.UintType:
		v.Kind = reflect.Uint
	case *dwarf.FloatType:
		switch t.ByteSize {
		case 4:
			v.Kind = reflect.Float32
		case 8:
			v.Kind = reflect.Float64
		}
	case *dwarf.BoolType:
		v.Kind = reflect.Bool
	case *dwarf.FuncType:
		v.Kind = reflect.Func
	case *dwarf.VoidType:
		v.Kind = reflect.Invalid
	case *dwarf.UnspecifiedType:
		v.Kind = reflect.Invalid
	default:
		v.Unreadable = fmt.Errorf("Unknown type: %T", t)
243 244
	}

245 246 247
	return v
}

248 249 250 251 252 253 254 255 256 257
func resolveTypedef(typ dwarf.Type) dwarf.Type {
	for {
		if tt, ok := typ.(*dwarf.TypedefType); ok {
			typ = tt.Type
		} else {
			return typ
		}
	}
}

258 259
func newConstant(val constant.Value, mem memoryReadWriter) *Variable {
	v := &Variable{Value: val, mem: mem, loaded: true}
A
aarzilli 已提交
260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276
	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{
277
	Name:     "nil",
A
aarzilli 已提交
278
	Addr:     0,
279
	Base:     0,
A
aarzilli 已提交
280 281 282 283
	Kind:     reflect.Ptr,
	Children: []Variable{{Addr: 0, OnlyAddr: true}},
}

284 285 286
func (v *Variable) clone() *Variable {
	r := *v
	return &r
287 288
}

D
Derek Parker 已提交
289 290
// TypeString returns the string representation
// of the type of this variable.
291 292 293 294 295
func (v *Variable) TypeString() string {
	if v == nilVariable {
		return "nil"
	}
	if v.DwarfType != nil {
296
		return v.DwarfType.Common().Name
297 298 299 300
	}
	return v.Kind.String()
}

301
func (v *Variable) toField(field *dwarf.StructField) (*Variable, error) {
302 303 304
	if v.Unreadable != nil {
		return v.clone(), nil
	}
D
Derek Parker 已提交
305
	if v.Addr == 0 {
306
		return nil, &IsNilErr{v.Name}
D
Derek Parker 已提交
307 308
	}

309 310
	name := ""
	if v.Name != "" {
311 312 313 314
		parts := strings.Split(field.Name, ".")
		if len(parts) > 1 {
			name = fmt.Sprintf("%s.%s", v.Name, parts[1])
		} else {
D
Derek Parker 已提交
315
			name = fmt.Sprintf("%s.%s", v.Name, field.Name)
316
		}
317
	}
318
	return v.newVariable(name, uintptr(int64(v.Addr)+field.ByteOffset), field.Type), nil
319 320
}

D
Derek Parker 已提交
321 322
// DwarfReader returns the DwarfReader containing the
// Dwarf information for the target process.
323 324 325 326
func (scope *EvalScope) DwarfReader() *reader.Reader {
	return scope.Thread.dbp.DwarfReader()
}

D
Derek Parker 已提交
327
// Type returns the Dwarf type entry at `offset`.
328 329 330 331
func (scope *EvalScope) Type(offset dwarf.Offset) (dwarf.Type, error) {
	return scope.Thread.dbp.dwarf.Type(offset)
}

D
Derek Parker 已提交
332
// PtrSize returns the size of a pointer.
333 334 335 336
func (scope *EvalScope) PtrSize() int {
	return scope.Thread.dbp.arch.PtrSize()
}

A
aarzilli 已提交
337
// ChanRecvBlocked returns whether the goroutine is blocked on
338
// a channel read operation.
339
func (g *G) ChanRecvBlocked() bool {
A
aarzilli 已提交
340
	return (g.thread == nil) && (g.WaitReason == chanRecv)
341 342 343
}

// chanRecvReturnAddr returns the address of the return from a channel read.
D
Derek Parker 已提交
344
func (g *G) chanRecvReturnAddr(dbp *Process) (uint64, error) {
A
aarzilli 已提交
345
	locs, err := g.Stacktrace(4)
346 347 348 349
	if err != nil {
		return 0, err
	}
	topLoc := locs[len(locs)-1]
350
	return topLoc.Current.PC, nil
D
Derek Parker 已提交
351 352
}

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

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

363 364 365 366 367 368
func (gvar *Variable) parseG() (*G, error) {
	mem := gvar.mem
	dbp := gvar.dbp
	gaddr := uint64(gvar.Addr)
	_, deref := gvar.RealType.(*dwarf.PtrType)

369
	if deref {
370
		gaddrbytes, err := mem.readMemory(uintptr(gaddr), dbp.arch.PtrSize())
371 372 373 374
		if err != nil {
			return nil, fmt.Errorf("error derefing *G %s", err)
		}
		gaddr = binary.LittleEndian.Uint64(gaddrbytes)
375
	}
D
Derek Parker 已提交
376
	if gaddr == 0 {
377 378 379 380
		id := 0
		if thread, ok := mem.(*Thread); ok {
			id = thread.ID
		}
A
Alessandro Arzilli 已提交
381
		return nil, NoGError{tid: id}
382
	}
A
Alessandro Arzilli 已提交
383 384 385 386 387 388 389
	for {
		if _, isptr := gvar.RealType.(*dwarf.PtrType); !isptr {
			break
		}
		gvar = gvar.maybeDereference()
	}
	gvar.loadValue(LoadConfig{false, 1, 64, 0, -1})
D
Derek Parker 已提交
390 391
	if gvar.Unreadable != nil {
		return nil, gvar.Unreadable
392
	}
A
Alessandro Arzilli 已提交
393 394 395 396 397 398
	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)
	waitReason := constant.StringVal(gvar.fieldVariable("waitreason").Value)
A
Alessandro Arzilli 已提交
399 400
	stkbarVar, _ := gvar.structMember("stkbar")
	stkbarPos, _ := constant.Int64Val(gvar.fieldVariable("stkbarPos").Value)
A
Alessandro Arzilli 已提交
401
	status, _ := constant.Int64Val(gvar.fieldVariable("atomicstatus").Value)
D
Derek Parker 已提交
402 403 404 405 406 407 408 409 410
	f, l, fn := gvar.dbp.goSymTable.PCToLine(uint64(pc))
	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 已提交
411
		variable:   gvar,
A
Alessandro Arzilli 已提交
412 413
		stkbarVar:  stkbarVar,
		stkbarPos:  int(stkbarPos),
D
Derek Parker 已提交
414
		dbp:        gvar.dbp,
415
	}
D
Derek Parker 已提交
416 417
	return g, nil
}
418

A
Alessandro Arzilli 已提交
419
func (v *Variable) loadFieldNamed(name string) *Variable {
D
Derek Parker 已提交
420
	v, err := v.structMember(name)
421
	if err != nil {
D
Derek Parker 已提交
422
		return nil
423
	}
424
	v.loadValue(loadFullValue)
D
Derek Parker 已提交
425 426
	if v.Unreadable != nil {
		return nil
427
	}
D
Derek Parker 已提交
428
	return v
429 430
}

A
Alessandro Arzilli 已提交
431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464
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)
}

465 466 467 468 469 470 471 472
// 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 已提交
473 474
// UserCurrent returns the location the users code is at,
// or was at before entering a runtime function.
475
func (g *G) UserCurrent() Location {
A
aarzilli 已提交
476 477 478
	it, err := g.stackIterator()
	if err != nil {
		return g.CurrentLoc
479 480 481
	}
	for it.Next() {
		frame := it.Frame()
482 483 484 485 486
		if frame.Call.Fn != nil {
			name := frame.Call.Fn.Name
			if (strings.Index(name, ".") >= 0) && (!strings.HasPrefix(name, "runtime.") || isExportedRuntime(name)) {
				return frame.Call
			}
487 488
		}
	}
489
	return g.CurrentLoc
490 491
}

D
Derek Parker 已提交
492 493
// Go returns the location of the 'go' statement
// that spawned this goroutine.
494 495 496 497 498
func (g *G) Go() Location {
	f, l, fn := g.dbp.goSymTable.PCToLine(g.GoPC)
	return Location{PC: g.GoPC, File: f, Line: l, Fn: fn}
}

A
Alessandro Arzilli 已提交
499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520
// Returns the list of saved return addresses used by stack barriers
func (g *G) stkbar() ([]savedLR, error) {
	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 已提交
521
// EvalVariable returns the value of the given expression (backwards compatibility).
522 523
func (scope *EvalScope) EvalVariable(name string, cfg LoadConfig) (*Variable, error) {
	return scope.EvalExpression(name, cfg)
A
aarzilli 已提交
524
}
525

D
Derek Parker 已提交
526
// SetVariable sets the value of the named variable
A
aarzilli 已提交
527 528
func (scope *EvalScope) SetVariable(name, value string) error {
	t, err := parser.ParseExpr(name)
529
	if err != nil {
A
aarzilli 已提交
530
		return err
531 532
	}

A
aarzilli 已提交
533
	xv, err := scope.evalAST(t)
534
	if err != nil {
A
aarzilli 已提交
535
		return err
536
	}
537

A
aarzilli 已提交
538 539 540 541 542 543 544 545 546
	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)
547 548 549
	if err != nil {
		return err
	}
A
aarzilli 已提交
550 551 552 553 554 555

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

556
	yv.loadValue(loadSingleValue)
A
aarzilli 已提交
557 558 559

	if err := yv.isType(xv.RealType, xv.Kind); err != nil {
		return err
560
	}
A
aarzilli 已提交
561 562 563 564 565 566

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

	return xv.setValue(yv)
567 568
}

569
func (scope *EvalScope) extractVariableFromEntry(entry *dwarf.Entry, cfg LoadConfig) (*Variable, error) {
570
	rdr := scope.DwarfReader()
571
	v, err := scope.extractVarInfoFromEntry(entry, rdr)
572
	if err != nil {
D
Derek Parker 已提交
573 574
		return nil, err
	}
575
	return v, nil
576
}
D
Derek Parker 已提交
577

578 579
func (scope *EvalScope) extractVarInfo(varName string) (*Variable, error) {
	reader := scope.DwarfReader()
A
Alessandro Arzilli 已提交
580
	off, err := scope.Thread.dbp.findFunctionDebugInfo(scope.PC)
581 582
	if err != nil {
		return nil, err
583
	}
A
Alessandro Arzilli 已提交
584 585
	reader.Seek(off)
	reader.Next()
586

587
	for entry, err := reader.NextScopeVariable(); entry != nil; entry, err = reader.NextScopeVariable() {
D
Derek Parker 已提交
588
		if err != nil {
589
			return nil, err
D
Derek Parker 已提交
590
		}
A
Alessandro Arzilli 已提交
591 592 593
		if entry.Tag == 0 {
			break
		}
D
Derek Parker 已提交
594 595 596 597 598 599

		n, ok := entry.Val(dwarf.AttrName).(string)
		if !ok {
			continue
		}

600
		if n == varName {
601
			return scope.extractVarInfoFromEntry(entry, reader)
D
Derek Parker 已提交
602 603
		}
	}
604
	return nil, fmt.Errorf("could not find symbol value for %s", varName)
D
Derek Parker 已提交
605
}
606

607
// LocalVariables returns all local variables from the current function scope.
608 609
func (scope *EvalScope) LocalVariables(cfg LoadConfig) ([]*Variable, error) {
	return scope.variablesByTag(dwarf.TagVariable, cfg)
610 611 612
}

// FunctionArguments returns the name, value, and type of all current function arguments.
613 614
func (scope *EvalScope) FunctionArguments(cfg LoadConfig) ([]*Variable, error) {
	return scope.variablesByTag(dwarf.TagFormalParameter, cfg)
615 616 617
}

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

622 623 624 625 626 627
	var utypoff dwarf.Offset
	utypentry, err := reader.SeekToTypeNamed("<unspecified>")
	if err == nil {
		utypoff = utypentry.Offset
	}

628 629 630 631 632
	for entry, err := reader.NextPackageVariable(); entry != nil; entry, err = reader.NextPackageVariable() {
		if err != nil {
			return nil, err
		}

633 634 635 636
		if typoff, ok := entry.Val(dwarf.AttrType).(dwarf.Offset); !ok || typoff == utypoff {
			continue
		}

637
		// Ignore errors trying to extract values
638
		val, err := scope.extractVariableFromEntry(entry, cfg)
639 640 641
		if err != nil {
			continue
		}
A
Alessandro Arzilli 已提交
642
		val.loadValue(cfg)
643 644 645 646 647 648
		vars = append(vars, val)
	}

	return vars, nil
}

D
Derek Parker 已提交
649 650
// EvalPackageVariable will evaluate the package level variable
// specified by 'name'.
651
func (dbp *Process) EvalPackageVariable(name string, cfg LoadConfig) (*Variable, error) {
D
Derek Parker 已提交
652
	scope := &EvalScope{Thread: dbp.currentThread, PC: 0, CFA: 0}
653

654
	v, err := scope.packageVarAddr(name)
655 656 657
	if err != nil {
		return nil, err
	}
658
	v.loadValue(cfg)
659
	return v, nil
660 661 662 663
}

func (scope *EvalScope) packageVarAddr(name string) (*Variable, error) {
	reader := scope.DwarfReader()
664 665 666 667 668 669 670 671 672 673 674
	for entry, err := reader.NextPackageVariable(); entry != nil; entry, err = reader.NextPackageVariable() {
		if err != nil {
			return nil, err
		}

		n, ok := entry.Val(dwarf.AttrName).(string)
		if !ok {
			continue
		}

		if n == name {
675
			return scope.extractVarInfoFromEntry(entry, reader)
676 677 678 679 680
		}
	}
	return nil, fmt.Errorf("could not find symbol value for %s", name)
}

681
func (v *Variable) structMember(memberName string) (*Variable, error) {
682 683 684 685
	if v.Unreadable != nil {
		return v.clone(), nil
	}
	structVar := v.maybeDereference()
686
	structVar.Name = v.Name
687 688
	if structVar.Unreadable != nil {
		return structVar, nil
689
	}
690 691

	switch t := structVar.RealType.(type) {
692 693 694 695
	case *dwarf.StructType:
		for _, field := range t.Field {
			if field.Name != memberName {
				continue
696
			}
L
Luke Hoban 已提交
697
			return structVar.toField(field)
698 699 700 701 702
		}
		// Check for embedded field only if field was
		// not a regular struct member
		for _, field := range t.Field {
			isEmbeddedStructMember :=
703
				(field.Type.Common().Name == field.Name) ||
D
Derek Parker 已提交
704 705
					(len(field.Name) > 1 &&
						field.Name[0] == '*' &&
706
						field.Type.Common().Name[1:] == field.Name[1:])
707 708 709 710 711 712
			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 已提交
713
				embeddedVar, err := structVar.toField(field)
714 715 716 717 718 719
				if err != nil {
					return nil, err
				}
				return embeddedVar, nil
			}
			// Recursively check for promoted fields on the embedded field
L
Luke Hoban 已提交
720
			embeddedVar, err := structVar.toField(field)
721 722 723 724 725 726 727
			if err != nil {
				return nil, err
			}
			embeddedVar.Name = structVar.Name
			embeddedField, err := embeddedVar.structMember(memberName)
			if embeddedField != nil {
				return embeddedField, nil
728 729
			}
		}
730 731
		return nil, fmt.Errorf("%s has no member %s", v.Name, memberName)
	default:
732 733 734
		if v.Name == "" {
			return nil, fmt.Errorf("type %s is not a struct", structVar.TypeString())
		}
D
Derek Parker 已提交
735
		return nil, fmt.Errorf("%s (type %s) is not a struct", v.Name, structVar.TypeString())
736
	}
737 738
}

739 740 741
// 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
func (scope *EvalScope) extractVarInfoFromEntry(entry *dwarf.Entry, rdr *reader.Reader) (*Variable, error) {
E
epipho 已提交
742
	if entry == nil {
D
Derek Parker 已提交
743
		return nil, fmt.Errorf("invalid entry")
E
epipho 已提交
744 745 746 747 748 749 750 751
	}

	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 已提交
752
		return nil, fmt.Errorf("type assertion failed")
E
epipho 已提交
753 754 755 756
	}

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

760
	t, err := scope.Type(offset)
E
epipho 已提交
761 762 763 764 765 766
	if err != nil {
		return nil, err
	}

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

770
	addr, err := op.ExecuteStackProgram(scope.CFA, instructions)
E
epipho 已提交
771 772 773 774
	if err != nil {
		return nil, err
	}

775
	return scope.newVariable(n, uintptr(addr), t), nil
E
epipho 已提交
776 777
}

778
// If v is a pointer a new variable is returned containing the value pointed by v.
779 780 781 782
func (v *Variable) maybeDereference() *Variable {
	if v.Unreadable != nil {
		return v
	}
783

784
	switch t := v.RealType.(type) {
785
	case *dwarf.PtrType:
786 787
		ptrval, err := readUintRaw(v.mem, uintptr(v.Addr), t.ByteSize)
		r := v.newVariable("", uintptr(ptrval), t.Type)
788
		if err != nil {
789
			r.Unreadable = err
790 791
		}

792
		return r
793
	default:
794
		return v
795 796
	}
}
797

798
// Extracts the value of the variable at the given address.
799 800
func (v *Variable) loadValue(cfg LoadConfig) {
	v.loadValueInternal(0, cfg)
801 802
}

803
func (v *Variable) loadValueInternal(recurseLevel int, cfg LoadConfig) {
804
	if v.Unreadable != nil || v.loaded || (v.Addr == 0 && v.Base == 0) {
805 806
		return
	}
807

808 809
	v.loaded = true
	switch v.Kind {
A
aarzilli 已提交
810
	case reflect.Ptr, reflect.UnsafePointer:
811 812
		v.Len = 1
		v.Children = []Variable{*v.maybeDereference()}
813 814 815 816 817 818
		if cfg.FollowPointers {
			// Don't increase the recursion level when dereferencing pointers
			v.Children[0].loadValueInternal(recurseLevel, cfg)
		} else {
			v.Children[0].OnlyAddr = true
		}
819

A
aarzilli 已提交
820
	case reflect.Chan:
821 822 823
		sv := v.clone()
		sv.RealType = resolveTypedef(&(sv.RealType.(*dwarf.ChanType).TypedefType))
		sv = sv.maybeDereference()
824
		sv.loadValueInternal(0, loadFullValue)
A
aarzilli 已提交
825 826
		v.Children = sv.Children
		v.Len = sv.Len
827
		v.Base = sv.Addr
A
aarzilli 已提交
828

A
aarzilli 已提交
829
	case reflect.Map:
830 831
		if recurseLevel <= cfg.MaxVariableRecurse {
			v.loadMap(recurseLevel, cfg)
A
aarzilli 已提交
832
		}
A
aarzilli 已提交
833

834
	case reflect.String:
835
		var val string
836
		val, v.Unreadable = readStringValue(v.mem, v.Base, v.Len, cfg)
837
		v.Value = constant.MakeString(val)
838 839

	case reflect.Slice, reflect.Array:
840
		v.loadArrayValues(recurseLevel, cfg)
841 842

	case reflect.Struct:
843
		v.mem = cacheMemory(v.mem, v.Addr, int(v.RealType.Size()))
844 845 846 847
		t := v.RealType.(*dwarf.StructType)
		v.Len = int64(len(t.Field))
		// Recursively call extractValue to grab
		// the value of all the members of the struct.
848
		if recurseLevel <= cfg.MaxVariableRecurse {
849 850
			v.Children = make([]Variable, 0, len(t.Field))
			for i, field := range t.Field {
851 852 853
				if cfg.MaxStructFields >= 0 && len(v.Children) >= cfg.MaxStructFields {
					break
				}
854 855 856
				f, _ := v.toField(field)
				v.Children = append(v.Children, *f)
				v.Children[i].Name = field.Name
857
				v.Children[i].loadValueInternal(recurseLevel+1, cfg)
858
			}
859 860
		}

861
	case reflect.Interface:
862
		v.loadInterface(recurseLevel, true, cfg)
863

864 865 866
	case reflect.Complex64, reflect.Complex128:
		v.readComplex(v.RealType.(*dwarf.ComplexType).ByteSize)
	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
867
		var val int64
868
		val, v.Unreadable = readIntRaw(v.mem, v.Addr, v.RealType.(*dwarf.IntType).ByteSize)
869
		v.Value = constant.MakeInt64(val)
870
	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
871
		var val uint64
872
		val, v.Unreadable = readUintRaw(v.mem, v.Addr, v.RealType.(*dwarf.UintType).ByteSize)
873 874
		v.Value = constant.MakeUint64(val)

875
	case reflect.Bool:
876
		val, err := v.mem.readMemory(v.Addr, 1)
877 878
		v.Unreadable = err
		if err == nil {
879
			v.Value = constant.MakeBool(val[0] != 0)
880
		}
881
	case reflect.Float32, reflect.Float64:
882 883 884
		var val float64
		val, v.Unreadable = v.readFloatRaw(v.RealType.(*dwarf.FloatType).ByteSize)
		v.Value = constant.MakeFloat64(val)
885 886 887 888 889 890 891 892
		switch {
		case math.IsInf(val, +1):
			v.FloatSpecial = FloatIsPosInf
		case math.IsInf(val, -1):
			v.FloatSpecial = FloatIsNegInf
		case math.IsNaN(val):
			v.FloatSpecial = FloatIsNaN
		}
893 894
	case reflect.Func:
		v.readFunctionPtr()
895
	default:
896
		v.Unreadable = fmt.Errorf("unknown or unsupported kind: \"%s\"", v.Kind.String())
897 898 899
	}
}

A
aarzilli 已提交
900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917
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())
918
	default:
919 920
		if t, isptr := v.RealType.(*dwarf.PtrType); isptr {
			err = v.writeUint(uint64(y.Children[0].Addr), int64(t.ByteSize))
A
aarzilli 已提交
921 922 923
		} else {
			return fmt.Errorf("can not set variables of type %s (not implemented)", v.Kind.String())
		}
924
	}
A
aarzilli 已提交
925 926

	return err
927 928
}

929
func readStringInfo(mem memoryReadWriter, arch Arch, addr uintptr) (uintptr, int64, error) {
930 931 932
	// string data structure is always two ptrs in size. Addr, followed by len
	// http://research.swtch.com/godata

933 934
	mem = cacheMemory(mem, addr, arch.PtrSize()*2)

935
	// read len
936
	val, err := mem.readMemory(addr+uintptr(arch.PtrSize()), arch.PtrSize())
937
	if err != nil {
A
aarzilli 已提交
938
		return 0, 0, fmt.Errorf("could not read string len %s", err)
939
	}
940
	strlen := int64(binary.LittleEndian.Uint64(val))
941
	if strlen < 0 {
A
aarzilli 已提交
942
		return 0, 0, fmt.Errorf("invalid length: %d", strlen)
943
	}
944 945

	// read addr
946
	val, err = mem.readMemory(addr, arch.PtrSize())
947
	if err != nil {
A
aarzilli 已提交
948
		return 0, 0, fmt.Errorf("could not read string pointer %s", err)
949 950
	}
	addr = uintptr(binary.LittleEndian.Uint64(val))
D
Derek Parker 已提交
951
	if addr == 0 {
A
aarzilli 已提交
952
		return 0, 0, nil
D
Derek Parker 已提交
953
	}
D
Derek Parker 已提交
954

A
aarzilli 已提交
955 956 957
	return addr, strlen, nil
}

958
func readStringValue(mem memoryReadWriter, addr uintptr, strlen int64, cfg LoadConfig) (string, error) {
A
aarzilli 已提交
959
	count := strlen
960 961
	if count > int64(cfg.MaxStringLen) {
		count = int64(cfg.MaxStringLen)
A
aarzilli 已提交
962 963
	}

964
	val, err := mem.readMemory(addr, int(count))
965
	if err != nil {
A
aarzilli 已提交
966
		return "", fmt.Errorf("could not read string at %#v due to %s", addr, err)
967 968
	}

969 970
	retstr := *(*string)(unsafe.Pointer(&val))

A
aarzilli 已提交
971 972 973
	return retstr, nil
}

974
func (v *Variable) loadSliceInfo(t *dwarf.SliceType) {
975 976
	v.mem = cacheMemory(v.mem, v.Addr, int(t.Size()))

977
	var err error
E
epipho 已提交
978 979 980
	for _, f := range t.Field {
		switch f.Name {
		case "array":
981
			var base uint64
982
			base, err = readUintRaw(v.mem, uintptr(int64(v.Addr)+f.ByteOffset), f.Type.Size())
983
			if err == nil {
984
				v.Base = uintptr(base)
985 986 987
				// Dereference array type to get value type
				ptrType, ok := f.Type.(*dwarf.PtrType)
				if !ok {
988 989
					v.Unreadable = fmt.Errorf("Invalid type %s in slice array", f.Type)
					return
990 991
				}
				v.fieldType = ptrType.Type
E
epipho 已提交
992 993
			}
		case "len":
994
			lstrAddr, _ := v.toField(f)
995
			lstrAddr.loadValue(loadSingleValue)
996
			err = lstrAddr.Unreadable
997
			if err == nil {
998
				v.Len, _ = constant.Int64Val(lstrAddr.Value)
E
epipho 已提交
999 1000
			}
		case "cap":
1001
			cstrAddr, _ := v.toField(f)
1002
			cstrAddr.loadValue(loadSingleValue)
1003
			err = cstrAddr.Unreadable
1004
			if err == nil {
1005
				v.Cap, _ = constant.Int64Val(cstrAddr.Value)
E
epipho 已提交
1006 1007
			}
		}
1008 1009 1010 1011
		if err != nil {
			v.Unreadable = err
			return
		}
1012 1013
	}

1014
	v.stride = v.fieldType.Size()
1015 1016
	if t, ok := v.fieldType.(*dwarf.PtrType); ok {
		v.stride = t.ByteSize
1017
	}
1018

1019
	return
1020 1021
}

1022
func (v *Variable) loadArrayValues(recurseLevel int, cfg LoadConfig) {
1023 1024 1025
	if v.Unreadable != nil {
		return
	}
1026 1027 1028 1029
	if v.Len < 0 {
		v.Unreadable = errors.New("Negative array length")
		return
	}
1030

1031 1032
	count := v.Len
	// Cap number of elements
1033 1034
	if count > int64(cfg.MaxArrayValues) {
		count = int64(cfg.MaxArrayValues)
1035
	}
1036

1037
	if v.stride < maxArrayStridePrefetch {
1038
		v.mem = cacheMemory(v.mem, v.Base, int(v.stride*count))
1039
	}
1040

1041 1042 1043
	errcount := 0

	for i := int64(0); i < count; i++ {
1044
		fieldvar := v.newVariable("", uintptr(int64(v.Base)+(i*v.stride)), v.fieldType)
1045
		fieldvar.loadValueInternal(recurseLevel+1, cfg)
1046 1047

		if fieldvar.Unreadable != nil {
1048
			errcount++
E
epipho 已提交
1049
		}
1050

1051
		v.Children = append(v.Children, *fieldvar)
1052 1053 1054
		if errcount > maxErrCount {
			break
		}
1055 1056 1057
	}
}

1058
func (v *Variable) readComplex(size int64) {
1059 1060 1061 1062 1063 1064 1065
	var fs int64
	switch size {
	case 8:
		fs = 4
	case 16:
		fs = 8
	default:
1066 1067
		v.Unreadable = fmt.Errorf("invalid size (%d) for complex type", size)
		return
1068
	}
1069 1070 1071

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

1072 1073
	realvar := v.newVariable("real", v.Addr, ftyp)
	imagvar := v.newVariable("imaginary", v.Addr+uintptr(fs), ftyp)
1074 1075
	realvar.loadValue(loadSingleValue)
	imagvar.loadValue(loadSingleValue)
A
aarzilli 已提交
1076
	v.Value = constant.BinaryOp(realvar.Value, token.ADD, constant.MakeImag(imagvar.Value))
1077 1078
}

A
aarzilli 已提交
1079 1080
func (v *Variable) writeComplex(real, imag float64, size int64) error {
	err := v.writeFloatRaw(real, int64(size/2))
1081 1082 1083 1084 1085 1086 1087 1088
	if err != nil {
		return err
	}
	imagaddr := *v
	imagaddr.Addr += uintptr(size / 2)
	return imagaddr.writeFloatRaw(imag, int64(size/2))
}

1089
func readIntRaw(mem memoryReadWriter, addr uintptr, size int64) (int64, error) {
E
epipho 已提交
1090
	var n int64
1091

1092
	val, err := mem.readMemory(addr, int(size))
1093
	if err != nil {
D
Derek Parker 已提交
1094
		return 0, err
1095 1096
	}

1097 1098
	switch size {
	case 1:
1099
		n = int64(int8(val[0]))
1100
	case 2:
1101
		n = int64(int16(binary.LittleEndian.Uint16(val)))
1102
	case 4:
1103
		n = int64(int32(binary.LittleEndian.Uint32(val)))
1104
	case 8:
E
epipho 已提交
1105
		n = int64(binary.LittleEndian.Uint64(val))
1106
	}
1107

D
Derek Parker 已提交
1108
	return n, nil
E
epipho 已提交
1109 1110
}

A
aarzilli 已提交
1111
func (v *Variable) writeUint(value uint64, size int64) error {
1112 1113 1114 1115
	val := make([]byte, size)

	switch size {
	case 1:
A
aarzilli 已提交
1116
		val[0] = byte(value)
1117
	case 2:
A
aarzilli 已提交
1118
		binary.LittleEndian.PutUint16(val, uint16(value))
1119
	case 4:
A
aarzilli 已提交
1120
		binary.LittleEndian.PutUint32(val, uint32(value))
1121
	case 8:
A
aarzilli 已提交
1122
		binary.LittleEndian.PutUint64(val, uint64(value))
1123 1124
	}

1125
	_, err := v.mem.writeMemory(v.Addr, val)
1126 1127 1128
	return err
}

1129
func readUintRaw(mem memoryReadWriter, addr uintptr, size int64) (uint64, error) {
E
epipho 已提交
1130 1131
	var n uint64

1132
	val, err := mem.readMemory(addr, int(size))
E
epipho 已提交
1133
	if err != nil {
D
Derek Parker 已提交
1134
		return 0, err
E
epipho 已提交
1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147
	}

	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 已提交
1148
	return n, nil
1149 1150
}

1151
func (v *Variable) readFloatRaw(size int64) (float64, error) {
1152
	val, err := v.mem.readMemory(v.Addr, int(size))
1153
	if err != nil {
1154
		return 0.0, err
1155 1156 1157
	}
	buf := bytes.NewBuffer(val)

D
Derek Parker 已提交
1158 1159 1160 1161
	switch size {
	case 4:
		n := float32(0)
		binary.Read(buf, binary.LittleEndian, &n)
1162
		return float64(n), nil
D
Derek Parker 已提交
1163 1164 1165
	case 8:
		n := float64(0)
		binary.Read(buf, binary.LittleEndian, &n)
1166
		return n, nil
D
Derek Parker 已提交
1167 1168
	}

1169
	return 0.0, fmt.Errorf("could not read float")
1170 1171
}

1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183
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)
	}

1184
	_, err := v.mem.writeMemory(v.Addr, buf.Bytes())
1185 1186 1187
	return err
}

A
aarzilli 已提交
1188
func (v *Variable) writeBool(value bool) error {
1189
	val := []byte{0}
A
aarzilli 已提交
1190
	val[0] = *(*byte)(unsafe.Pointer(&value))
1191
	_, err := v.mem.writeMemory(v.Addr, val)
1192 1193 1194
	return err
}

1195
func (v *Variable) readFunctionPtr() {
1196
	val, err := v.mem.readMemory(v.Addr, v.dbp.arch.PtrSize())
1197
	if err != nil {
1198 1199
		v.Unreadable = err
		return
1200 1201 1202
	}

	// dereference pointer to find function pc
1203 1204
	fnaddr := uintptr(binary.LittleEndian.Uint64(val))
	if fnaddr == 0 {
1205
		v.Base = 0
A
aarzilli 已提交
1206
		v.Value = constant.MakeString("")
1207
		return
1208
	}
1209

1210
	val, err = v.mem.readMemory(fnaddr, v.dbp.arch.PtrSize())
1211
	if err != nil {
1212 1213
		v.Unreadable = err
		return
1214 1215
	}

1216 1217
	v.Base = uintptr(binary.LittleEndian.Uint64(val))
	fn := v.dbp.goSymTable.PCToFunc(uint64(v.Base))
1218
	if fn == nil {
1219
		v.Unreadable = fmt.Errorf("could not find function for %#v", v.Base)
1220
		return
1221 1222
	}

1223
	v.Value = constant.MakeString(fn.Name)
1224 1225
}

1226
func (v *Variable) loadMap(recurseLevel int, cfg LoadConfig) {
A
aarzilli 已提交
1227 1228 1229 1230 1231 1232 1233
	it := v.mapIterator()
	if it == nil {
		return
	}

	for skip := 0; skip < v.mapSkip; skip++ {
		if ok := it.next(); !ok {
1234
			v.Unreadable = fmt.Errorf("map index out of bounds")
A
aarzilli 已提交
1235 1236 1237 1238 1239 1240 1241
			return
		}
	}

	count := 0
	errcount := 0
	for it.next() {
1242
		if count >= cfg.MaxArrayValues {
A
aarzilli 已提交
1243 1244 1245 1246
			break
		}
		key := it.key()
		val := it.value()
1247 1248
		key.loadValueInternal(recurseLevel+1, cfg)
		val.loadValueInternal(recurseLevel+1, cfg)
A
aarzilli 已提交
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 1274 1275 1276 1277 1278 1279
		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 {
1280 1281 1282
	sv := v.clone()
	sv.RealType = resolveTypedef(&(sv.RealType.(*dwarf.MapType).TypedefType))
	sv = sv.maybeDereference()
1283
	v.Base = sv.Addr
A
aarzilli 已提交
1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297

	maptype, ok := sv.RealType.(*dwarf.StructType)
	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
	}

1298
	v.mem = cacheMemory(v.mem, v.Base, int(v.RealType.Size()))
1299

A
aarzilli 已提交
1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321
	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
		}
	}

1322 1323 1324 1325 1326
	if it.buckets.Kind != reflect.Struct || it.oldbuckets.Kind != reflect.Struct {
		v.Unreadable = mapBucketsNotStructErr
		return nil
	}

A
aarzilli 已提交
1327 1328 1329
	return it
}

1330 1331 1332 1333
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 已提交
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 1379 1380 1381 1382 1383 1384
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
	}

1385 1386
	it.b.mem = cacheMemory(it.b.mem, it.b.Addr, int(it.b.RealType.Size()))

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 1416 1417 1418 1419 1420 1421
	it.tophashes = nil
	it.keys = nil
	it.values = nil
	it.overflow = nil

	for _, f := range it.b.DwarfType.(*dwarf.StructType).Field {
		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 {
1422
		it.v.Unreadable = mapBucketContentsNotArrayErr
A
aarzilli 已提交
1423 1424 1425 1426
		return false
	}

	if it.tophashes.Len != it.keys.Len || it.tophashes.Len != it.values.Len {
1427 1428 1429 1430 1431 1432
		it.v.Unreadable = mapBucketContentsInconsistentLenErr
		return false
	}

	if it.overflow.Kind != reflect.Struct {
		it.v.Unreadable = mapBucketsNotStructErr
A
aarzilli 已提交
1433 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 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489
		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
	}
	for _, f := range b.DwarfType.(*dwarf.StructType).Field {
		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
}

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

A
Alessandro Arzilli 已提交
1496 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
	// 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

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

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

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

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

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

1578 1579
	var kind int64

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

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

1592
		typ, err = v.dbp.findType(typename)
A
Alessandro Arzilli 已提交
1593
		if err != nil {
1594
			v.Unreadable = fmt.Errorf("interface type %q not found for %#x: %v", typename, data.Addr, err)
1595
			return
A
Alessandro Arzilli 已提交
1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607
		}
	} 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
		}

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

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

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

1623 1624 1625 1626 1627
	if kind&kindDirectIface == 0 {
		realtyp := resolveTypedef(typ)
		if _, isptr := realtyp.(*dwarf.PtrType); !isptr {
			typ = v.dbp.pointerTo(typ)
		}
1628 1629
	}

1630
	data = data.newVariable("data", data.Addr, typ)
1631 1632 1633

	v.Children = []Variable{*data}
	if loadData {
1634 1635 1636
		v.Children[0].loadValueInternal(recurseLevel, cfg)
	} else {
		v.Children[0].OnlyAddr = true
1637 1638 1639 1640
	}
	return
}

E
epipho 已提交
1641
// Fetches all variables of a specific type in the current function scope
1642
func (scope *EvalScope) variablesByTag(tag dwarf.Tag, cfg LoadConfig) ([]*Variable, error) {
1643
	reader := scope.DwarfReader()
A
Alessandro Arzilli 已提交
1644
	off, err := scope.Thread.dbp.findFunctionDebugInfo(scope.PC)
1645
	if err != nil {
E
epipho 已提交
1646 1647
		return nil, err
	}
A
Alessandro Arzilli 已提交
1648 1649
	reader.Seek(off)
	reader.Next()
E
epipho 已提交
1650

D
Derek Parker 已提交
1651
	var vars []*Variable
1652
	for entry, err := reader.NextScopeVariable(); entry != nil; entry, err = reader.NextScopeVariable() {
E
epipho 已提交
1653 1654 1655
		if err != nil {
			return nil, err
		}
A
Alessandro Arzilli 已提交
1656 1657 1658
		if entry.Tag == 0 {
			break
		}
E
epipho 已提交
1659 1660

		if entry.Tag == tag {
1661
			val, err := scope.extractVariableFromEntry(entry, cfg)
E
epipho 已提交
1662
			if err != nil {
E
epipho 已提交
1663 1664
				// skip variables that we can't parse yet
				continue
E
epipho 已提交
1665 1666 1667 1668 1669
			}

			vars = append(vars, val)
		}
	}
A
Alessandro Arzilli 已提交
1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705 1706
	if len(vars) <= 0 {
		return vars, nil
	}

	// 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
		}
	}

	for _, v := range vars {
		v.loadValue(cfg)
	}
E
epipho 已提交
1707 1708 1709

	return vars, nil
}