x/debug: support changes to the internal representation of interfaces' types. There are now typedefs in different places in the DWARF type data, and the type name is now stored as a string instead of a *string. This supports both. Change-Id: I6f963d34a0157f76a8b3d92ef998712066806c3f Reviewed-on: https://go-review.googlesource.com/20720 Reviewed-by: Dave Day <djd@golang.org>
diff --git a/server/print.go b/server/print.go index 927988a..e370498 100644 --- a/server/print.go +++ b/server/print.go
@@ -274,15 +274,11 @@ } func (p *Printer) printInterfaceAt(t *dwarf.InterfaceType, a uint64) { - // t should be a typedef binding a typedef binding a struct. - tt, ok := t.TypedefType.Type.(*dwarf.TypedefType) + // t embeds a TypedefType, which may point to another typedef. + // The underlying type should be a struct. + st, ok := followTypedefs(&t.TypedefType).(*dwarf.StructType) 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") + p.errorf("bad interface type: not a struct") return } p.printf("(") @@ -315,70 +311,71 @@ 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) + // t should be a pointer to a struct containing _type, which is a pointer to a + // struct containing _string, which is the name of the type. + // Depending on the compiler version, some of these types can be typedefs, and + // _string may be a string or a *string. + t1, ok := followTypedefs(t).(*dwarf.PtrType) if !ok { - p.errorf("bad type") + p.errorf("interface's tab is not a pointer") return } - t2, ok := t1.Type.(*dwarf.TypedefType) + t2, ok := followTypedefs(t1.Type).(*dwarf.StructType) if !ok { - p.errorf("bad type") + p.errorf("interface's tab is not a pointer to struct") return } - t3, ok := t2.Type.(*dwarf.StructType) - if !ok { - p.errorf("bad type") - return - } - typeField, err := getField(t3, "_type") + typeField, err := getField(t2, "_type") if err != nil { p.errorf("%s", err) return } - t4, ok := typeField.Type.(*dwarf.PtrType) + t3, ok := followTypedefs(typeField.Type).(*dwarf.PtrType) if !ok { - p.errorf("bad type") + p.errorf("interface's _type is not a pointer") return } - t5, ok := t4.Type.(*dwarf.TypedefType) + t4, ok := followTypedefs(t3.Type).(*dwarf.StructType) if !ok { - p.errorf("bad type") + p.errorf("interface's _type is not a pointer to struct") return } - t6, ok := t5.Type.(*dwarf.StructType) - if !ok { - p.errorf("bad type") - return - } - stringField, err := getField(t6, "_string") + stringField, err := getField(t4, "_string") if err != nil { p.errorf("%s", err) return } - t7, ok := stringField.Type.(*dwarf.PtrType) - if !ok { - p.errorf("bad type") - return + if t5, ok := stringField.Type.(*dwarf.PtrType); ok { + stringType, ok := t5.Type.(*dwarf.StringType) + if !ok { + p.errorf("interface _string is a pointer to %T, want string or *string", t5.Type) + return + } + typeAddr, err := p.server.peekPtrStructField(t2, a, "_type") + if err != nil { + p.errorf("reading interface type: %s", err) + return + } + stringAddr, err := p.server.peekPtrStructField(t4, typeAddr, "_string") + if err != nil { + p.errorf("reading interface type: %s", err) + return + } + p.printStringAt(stringType, stringAddr) + } else { + stringType, ok := stringField.Type.(*dwarf.StringType) + if !ok { + p.errorf("interface _string is a %T, want string or *string", stringField.Type) + return + } + typeAddr, err := p.server.peekPtrStructField(t2, a, "_type") + if err != nil { + p.errorf("reading interface type: %s", err) + return + } + stringAddr := typeAddr + uint64(stringField.ByteOffset) + p.printStringAt(stringType, stringAddr) } - stringType, ok := t7.Type.(*dwarf.StringType) - if !ok { - p.errorf("bad type") - return - } - typeAddr, err := p.server.peekPtrStructField(t3, a, "_type") - if err != nil { - p.errorf("reading interface type: %s", err) - return - } - stringAddr, err := p.server.peekPtrStructField(t6, typeAddr, "_string") - if err != nil { - p.errorf("reading interface type: %s", err) - return - } - p.printStringAt(stringType, stringAddr) } // maxMapValuesToPrint values are printed for each map; any remaining values are