debug: print interfaces. Add InterfaceType to DWARF parser.
Change-Id: I9d5943463bea905c7ce11e5d91acd9f74b3b031f
Reviewed-on: https://go-review.googlesource.com/2791
Reviewed-by: Nigel Tao <nigeltao@golang.org>
diff --git a/dwarf/type.go b/dwarf/type.go
index 4f58b74..d61cfa9 100644
--- a/dwarf/type.go
+++ b/dwarf/type.go
@@ -217,6 +217,18 @@
return "string"
}
+// An InterfaceType represents a Go interface.
+type InterfaceType struct {
+ TypedefType
+}
+
+func (t *InterfaceType) String() string {
+ if t.Name != "" {
+ return t.Name
+ }
+ return "Interface"
+}
+
// An EnumType represents an enumerated type.
// The only indication of its native integer type is its ByteSize
// (inside CommonType).
@@ -743,6 +755,10 @@
c.ElemType = typeOf(e, AttrGoElem)
t = &c.TypedefType
typ = c
+ case reflect.Interface:
+ it := new(InterfaceType)
+ t = &it.TypedefType
+ typ = it
default:
typ = t
}
diff --git a/ogle/demo/ogler/ogler_test.go b/ogle/demo/ogler/ogler_test.go
index 9b02f96..65483ee 100644
--- a/ogle/demo/ogler/ogler_test.go
+++ b/ogle/demo/ogler/ogler_test.go
@@ -38,9 +38,9 @@
`main.Z_int32`: `-1987654321`,
`main.Z_int64`: `-9012345678987654321`,
`main.Z_int8`: `-121`,
- `main.Z_interface`: `struct runtime.iface {0xX, 0xX}`,
- `main.Z_interface_nil`: `struct runtime.iface {0x0, 0x0}`,
- `main.Z_interface_typed_nil`: `struct runtime.iface {0xX, 0x0}`,
+ `main.Z_interface`: `("*main.FooStruct", 0xX)`,
+ `main.Z_interface_nil`: `(<nil>, <nil>)`,
+ `main.Z_interface_typed_nil`: `("*main.FooStruct", <nil>)`,
`main.Z_map`: `{-21:3.54321}`,
`main.Z_map_2`: `{1024:1}`,
`main.Z_map_empty`: `{}`,
diff --git a/ogle/program/server/print.go b/ogle/program/server/print.go
index 8d93b3a..4b9c3c7 100644
--- a/ogle/program/server/print.go
+++ b/ogle/program/server/print.go
@@ -327,6 +327,8 @@
p.printf("}")
case *dwarf.ArrayType:
p.printArrayAt(typ, a)
+ case *dwarf.InterfaceType:
+ p.printInterfaceAt(typ, a)
case *dwarf.MapType:
p.printMapAt(typ, a)
case *dwarf.ChanType:
@@ -342,7 +344,6 @@
case *dwarf.VoidType:
p.printf("void")
default:
- // TODO: interface
p.errorf("unimplemented type %v", typ)
}
}
@@ -372,6 +373,114 @@
p.printf("}")
}
+func (p *Printer) printInterfaceAt(t *dwarf.InterfaceType, a address) {
+ // t should be a typedef binding a typedef binding a struct.
+ tt, ok := t.TypedefType.Type.(*dwarf.TypedefType)
+ if !ok {
+ p.errorf("bad interface type: not a typedef")
+ return
+ }
+ st, ok := tt.Type.(*dwarf.StructType)
+ if !ok {
+ p.errorf("bad interface type: not a typedef of a struct")
+ return
+ }
+ p.printf("(")
+ tab, ok := p.peekPtrStructField(st, a, "tab")
+ if ok {
+ f, err := getField(st, "tab")
+ if err != nil {
+ p.errorf("%s", err)
+ } else {
+ p.printTypeOfInterface(f.Type, tab)
+ }
+ } else {
+ p.errorf("couldn't read interface type")
+ }
+ p.printf(", ")
+ data, ok := p.peekPtrStructField(st, a, "data")
+ if !ok {
+ p.errorf("couldn't read interface value")
+ } else if data == 0 {
+ p.printf("<nil>")
+ } else {
+ p.printf("%#x", data)
+ }
+ p.printf(")")
+}
+
+// printTypeOfInterface prints the type of the given tab pointer.
+func (p *Printer) printTypeOfInterface(t dwarf.Type, a address) {
+ if a == 0 {
+ p.printf("<nil>")
+ return
+ }
+ // t should be a pointer to a typedef binding a struct which contains a field _type.
+ // _type should be a pointer to a typedef binding a struct which contains a field _string.
+ // _string is the name of the type.
+ t1, ok := t.(*dwarf.PtrType)
+ if !ok {
+ p.errorf("bad type")
+ return
+ }
+ t2, ok := t1.Type.(*dwarf.TypedefType)
+ if !ok {
+ p.errorf("bad type")
+ return
+ }
+ t3, ok := t2.Type.(*dwarf.StructType)
+ if !ok {
+ p.errorf("bad type")
+ return
+ }
+ typeField, err := getField(t3, "_type")
+ if err != nil {
+ p.errorf("%s", err)
+ return
+ }
+ t4, ok := typeField.Type.(*dwarf.PtrType)
+ if !ok {
+ p.errorf("bad type")
+ return
+ }
+ t5, ok := t4.Type.(*dwarf.TypedefType)
+ if !ok {
+ p.errorf("bad type")
+ return
+ }
+ t6, ok := t5.Type.(*dwarf.StructType)
+ if !ok {
+ p.errorf("bad type")
+ return
+ }
+ stringField, err := getField(t6, "_string")
+ if err != nil {
+ p.errorf("%s", err)
+ return
+ }
+ t7, ok := stringField.Type.(*dwarf.PtrType)
+ if !ok {
+ p.errorf("bad type")
+ return
+ }
+ stringType, ok := t7.Type.(*dwarf.StringType)
+ if !ok {
+ p.errorf("bad type")
+ return
+ }
+ typeAddr, ok := p.peekPtrStructField(t3, a, "_type")
+ if !ok {
+ p.errorf("couldn't read type structure pointer")
+ return
+ }
+ stringAddr, ok := p.peekPtrStructField(t6, typeAddr, "_string")
+ if !ok {
+ p.errorf("couldn't read type name")
+ return
+ }
+ p.printStringAt(stringType, stringAddr)
+}
+
// maxMapValuesToPrint values are printed for each map; any remaining values are
// truncated to "...".
const maxMapValuesToPrint = 8