gocore: work around bad sudog dwarf

Detect when the sudog's elem field type isn't a pointer like it should
be, and overwrite it with a new Type.

Change-Id: Iea9497326358361c688c49c60a33108d434a8d95
Reviewed-on: https://go-review.googlesource.com/98996
Reviewed-by: Keith Randall <khr@golang.org>
diff --git a/gocore/dwarf.go b/gocore/dwarf.go
index 19a10ac..fffe950 100644
--- a/gocore/dwarf.go
+++ b/gocore/dwarf.go
@@ -38,6 +38,8 @@
 		}
 	}
 
+	p.runtimeNameMap = map[string][]*Type{}
+
 	// Fill in fields of types. Postponed until now so we're sure
 	// we have all the Types allocated and available.
 	for dt, t := range p.dwarfMap {
@@ -55,7 +57,18 @@
 		case *dwarf.StructType:
 			t.Kind = KindStruct
 			for _, f := range x.Field {
-				t.Fields = append(t.Fields, Field{Name: f.Name, Type: p.dwarfMap[f.Type], Off: f.ByteOffset})
+				fType := p.dwarfMap[f.Type]
+
+				// Work around issue 21094. There's no guarantee that the
+				// pointer type is in the DWARF, so just invent a Type.
+				if strings.HasPrefix(t.Name, "sudog<") && f.Name == "elem" &&
+					strings.Count(t.Name, "*")+1 != strings.Count(gocoreName(f.Type), "*") {
+					ptrName := "*" + gocoreName(f.Type)
+					fType = &Type{Name: ptrName, Kind: KindPtr, Size: p.proc.PtrSize(), Elem: fType}
+					p.runtimeNameMap[ptrName] = []*Type{fType}
+				}
+
+				t.Fields = append(t.Fields, Field{Name: f.Name, Type: fType, Off: f.ByteOffset})
 			}
 		case *dwarf.BoolType:
 			t.Kind = KindBool
@@ -134,7 +147,6 @@
 	}
 
 	// Make a runtime name -> Type map for existing DWARF types.
-	p.runtimeNameMap = map[string][]*Type{}
 	for dt, t := range p.dwarfMap {
 		name := runtimeName(dt)
 		p.runtimeNameMap[name] = append(p.runtimeNameMap[name], t)