Skip to content

Commit 0e1d767

Browse files
committed
addressed comments.
1 parent 0f81fd8 commit 0e1d767

File tree

1 file changed

+31
-11
lines changed

1 file changed

+31
-11
lines changed

internal/gocore/type.go

Lines changed: 31 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,7 @@ func (p *Process) DynamicType(t *Type, a core.Address) *Type {
111111
}
112112

113113
// Convert the address of a runtime._type to a *Type.
114+
// The "d" is the address of the second field of an interface.
114115
// Guaranteed to return a non-nil *Type.
115116
func (p *Process) runtimeType2Type(a core.Address, d core.Address) *Type {
116117
if t := p.runtimeMap[a]; t != nil {
@@ -176,16 +177,27 @@ func (p *Process) runtimeType2Type(a core.Address, d core.Address) *Type {
176177
// in the same package name, but in the different package paths. eg. path-1/pkg.Foo and path-2/pkg.Foo.
177178
// Match the object size may be a proper choice, just for try best, since we have no other choices.
178179
if len(candidates) > 1 && nptrs == 1 && candidates[0].Size == ptrSize {
179-
o := p.proc.ReadPtr(d)
180-
sz := p.Size(Object(o))
181-
var tmp []*Type
182-
for _, t := range candidates {
183-
if t.Elem != nil && t.Elem.Size == sz {
184-
tmp = append(tmp, t)
185-
}
180+
ptr := p.proc.ReadPtr(d)
181+
if ifaceIndir(a, p) {
182+
// Indirect interface: the interface introduced a new
183+
// level of indirection, not reflected in the type.
184+
// Read through it.
185+
ptr = p.proc.ReadPtr(ptr)
186186
}
187-
if len(tmp) > 0 {
188-
candidates = tmp
187+
obj, off := p.FindObject(ptr)
188+
// only usefull while it point to the head of an object,
189+
// otherwise, the GC object size should bigger than t.Elem.Size.
190+
if obj != 0 && off == 0 {
191+
sz := p.Size(obj)
192+
var tmp []*Type
193+
for _, t := range candidates {
194+
if t.Elem != nil && t.Elem.Size == sz {
195+
tmp = append(tmp, t)
196+
}
197+
}
198+
if len(tmp) > 0 {
199+
candidates = tmp
200+
}
189201
}
190202
}
191203
var t *Type
@@ -541,6 +553,15 @@ func (fr *frameReader) ReadInt(a core.Address) int64 {
541553
return fr.p.proc.ReadInt(a)
542554
}
543555

556+
// ifaceIndir reports whether t is stored indirectly in an interface value.
557+
func ifaceIndir(t core.Address, p *Process) bool {
558+
typr := region{p: p, a: t, typ: p.findType("runtime._type")}
559+
if typr.Field("kind").Uint8()&uint8(p.rtConstants["kindDirectIface"]) == 0 {
560+
return true
561+
}
562+
return false
563+
}
564+
544565
// typeObject takes an address and a type for the data at that address.
545566
// For each pointer it finds in the memory at that address, it calls add with the pointer
546567
// and the type + repeat count of the thing that it points to.
@@ -564,8 +585,7 @@ func (p *Process) typeObject(a core.Address, t *Type, r reader, add func(core.Ad
564585
// TODO: for KindEface, type typPtr. It might point to the heap
565586
// if the type was allocated with reflect.
566587
typ := p.runtimeType2Type(typPtr, data)
567-
typr := region{p: p, a: typPtr, typ: p.findType("runtime._type")}
568-
if typr.Field("kind").Uint8()&uint8(p.rtConstants["kindDirectIface"]) == 0 {
588+
if ifaceIndir(typPtr, p) {
569589
// Indirect interface: the interface introduced a new
570590
// level of indirection, not reflected in the type.
571591
// Read through it.

0 commit comments

Comments
 (0)