x/debug: support getting values of string type. The returned strings are truncated; some future code will allow getting more of the string. Change-Id: Ie4f4be081a521f90142754bbf475d7c4e020a9e9 Reviewed-on: https://go-review.googlesource.com/13788 Reviewed-by: Rob Pike <r@golang.org>
diff --git a/ogle/demo/ogler/ogler_test.go b/ogle/demo/ogler/ogler_test.go index 4660ec4..e5803dd 100644 --- a/ogle/demo/ogler/ogler_test.go +++ b/ogle/demo/ogler/ogler_test.go
@@ -501,4 +501,19 @@ } return nil }) + + checkValue("main.Z_string", func(val program.Value) error { + s, ok := val.(program.String) + if !ok { + return fmt.Errorf("got %T(%v) expected String", val, val) + } + if s.Length != 12 { + return fmt.Errorf("got string length %d expected 12", s.Length) + } + expected := "I'm a string" + if s.String != expected { + return fmt.Errorf("got %s expected %s", s.String, expected) + } + return nil + }) }
diff --git a/ogle/program/program.go b/ogle/program/program.go index 367c7d7..f80efe1 100644 --- a/ogle/program/program.go +++ b/ogle/program/program.go
@@ -133,6 +133,15 @@ Capacity uint64 } +// String is a Var representing a string. +// TODO: a method to access more of a truncated string. +type String struct { + // Length contains the length of the remote string, in bytes. + Length uint64 + // String contains the string itself; it may be truncated to fewer bytes than the value of the Length field. + String string +} + // Map is a Var representing a map. type Map struct { TypeID uint64
diff --git a/ogle/program/proxyrpc/proxyrpc.go b/ogle/program/proxyrpc/proxyrpc.go index dc2de15..1a76110 100644 --- a/ogle/program/proxyrpc/proxyrpc.go +++ b/ogle/program/proxyrpc/proxyrpc.go
@@ -19,6 +19,7 @@ gob.Register(program.Struct{}) gob.Register(program.Slice{}) gob.Register(program.Map{}) + gob.Register(program.String{}) } // 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 dea3b85..d53e5a8 100644 --- a/ogle/program/server/value.go +++ b/ogle/program/server/value.go
@@ -180,6 +180,27 @@ Address: addr, Length: length, }, nil + case *dwarf.StringType: + ptr, err := s.peekPtrStructField(&t.StructType, addr, "str") + if err != nil { + return nil, fmt.Errorf("reading string location: %s", err) + } + length, err := s.peekUintOrIntStructField(&t.StructType, addr, "len") + if err != nil { + return nil, fmt.Errorf("reading string length: %s", err) + } + + const maxStringSize = 256 + + n := length + if n > maxStringSize { + n = maxStringSize + } + tmp := make([]byte, n) + if err := s.peekBytes(ptr, tmp); err != nil { + return nil, fmt.Errorf("reading string contents: %s", err) + } + return program.String{Length: length, String: string(tmp)}, nil // TODO: more types } return nil, fmt.Errorf("Unsupported type %T", t)