x/debug: support getting values of slice type. The type program.Slice that the user gets for slice variables just embeds a program.Array and adds a capacity field. The DWARF information for slices doesn't include stride, so the stride is computed with the size of the element type. Change-Id: I69c60998abd1b48b1986522f60f93ddcad0c155e Reviewed-on: https://go-review.googlesource.com/12831 Reviewed-by: Rob Pike <r@golang.org>
diff --git a/ogle/demo/ogler/ogler_test.go b/ogle/demo/ogler/ogler_test.go index 3b9e35b..b2ba5d7 100644 --- a/ogle/demo/ogler/ogler_test.go +++ b/ogle/demo/ogler/ogler_test.go
@@ -414,4 +414,23 @@ } return nil }) + + checkValue("main.Z_slice", func(val program.Value) error { + s, ok := val.(program.Slice) + if !ok { + return fmt.Errorf("got %T(%v) expected Slice", val, val) + } + if s.Len() != 5 { + return fmt.Errorf("got slice length %d expected 5", s.Len()) + } + expected := []uint8{115, 108, 105, 99, 101} + for i := uint64(0); i < 5; i++ { + if v, err := prog.Value(s.Element(i)); err != nil { + return fmt.Errorf("reading element %d: %s", i, err) + } else if v != expected[i] { + return fmt.Errorf("element %d: got %T(%v) want %T(%d)", i, v, v, expected[i], expected[i]) + } + } + return nil + }) }
diff --git a/ogle/program/program.go b/ogle/program/program.go index 24619aa..9e45c26 100644 --- a/ogle/program/program.go +++ b/ogle/program/program.go
@@ -123,6 +123,12 @@ } } +// Slice is a Var representing a slice. +type Slice struct { + Array + Capacity uint64 +} + // Struct is a Var representing a struct. type Struct struct { Fields []StructField
diff --git a/ogle/program/proxyrpc/proxyrpc.go b/ogle/program/proxyrpc/proxyrpc.go index 91bb49e..568fdea 100644 --- a/ogle/program/proxyrpc/proxyrpc.go +++ b/ogle/program/proxyrpc/proxyrpc.go
@@ -17,6 +17,7 @@ gob.Register(program.Pointer{}) gob.Register(program.Array{}) gob.Register(program.Struct{}) + gob.Register(program.Slice{}) } // For regularity, each method has a unique Request and a Response type even
diff --git a/ogle/program/server/value.go b/ogle/program/server/value.go index d457b92..bbb1e4e 100644 --- a/ogle/program/server/value.go +++ b/ogle/program/server/value.go
@@ -118,6 +118,32 @@ TypeID: uint64(t.Type.Common().Offset), Address: uint64(s.arch.Uintptr(buf)), }, nil + case *dwarf.SliceType: + ptr, err := s.peekPtrStructField(&t.StructType, addr, "array") + if err != nil { + return nil, fmt.Errorf("reading slice location: %s", err) + } + length, err := s.peekUintOrIntStructField(&t.StructType, addr, "len") + if err != nil { + return nil, fmt.Errorf("reading slice length: %s", err) + } + capacity, err := s.peekUintOrIntStructField(&t.StructType, addr, "cap") + if err != nil { + return nil, fmt.Errorf("reading slice capacity: %s", err) + } + if capacity < length { + return nil, fmt.Errorf("slice's capacity %d is less than its length %d", capacity, length) + } + + return program.Slice{ + program.Array{ + ElementTypeID: uint64(t.ElemType.Common().Offset), + Address: uint64(ptr), + Length: length, + StrideBits: uint64(t.ElemType.Common().ByteSize) * 8, + }, + capacity, + }, nil case *dwarf.ArrayType: length := t.Count stride := t.StrideBitSize