diff options
| author | Keith Randall <khr@golang.org> | 2014-04-07 17:35:44 -0700 |
|---|---|---|
| committer | Keith Randall <khr@golang.org> | 2014-04-07 17:35:44 -0700 |
| commit | af923df89ee65428b0a8cba7323e9397926ea0e6 (patch) | |
| tree | 1348f2a7fcbcfafc155a8386f07d376e996a3b86 /src/pkg/runtime | |
| parent | a2a351478bb223891ebe8c1ae09c6ad09648f138 (diff) | |
| download | go-af923df89ee65428b0a8cba7323e9397926ea0e6.tar.xz | |
runtime: fix heapdump bugs.
Iterate the right number of times in arrays and channels.
Handle channels with zero-sized objects in them.
Output longer type names if we have them.
Compute argument offset correctly.
LGTM=rsc
R=golang-codereviews, rsc
CC=golang-codereviews
https://golang.org/cl/82980043
Diffstat (limited to 'src/pkg/runtime')
| -rw-r--r-- | src/pkg/runtime/heapdump.c | 17 |
1 files changed, 13 insertions, 4 deletions
diff --git a/src/pkg/runtime/heapdump.c b/src/pkg/runtime/heapdump.c index f9bc4e559f..e66dd6a7ae 100644 --- a/src/pkg/runtime/heapdump.c +++ b/src/pkg/runtime/heapdump.c @@ -186,7 +186,14 @@ dumptype(Type *t) dumpint(TagType); dumpint((uintptr)t); dumpint(t->size); - dumpstr(*t->string); + if(t->x == nil || t->x->pkgPath == nil || t->x->name == nil) { + dumpstr(*t->string); + } else { + dumpint(t->x->pkgPath->len + 1 + t->x->name->len); + write(t->x->pkgPath->str, t->x->pkgPath->len); + write((byte*)".", 1); + write(t->x->name->str, t->x->name->len); + } dumpbool(t->size > PtrSize || (t->kind & KindNoPointers) == 0); dumpfields((uintptr*)t->gc + 1); } @@ -375,7 +382,7 @@ dumpframe(Stkframe *s, void *arg) dumpint(FieldKindEol); // Record arg info for parent. - child->argoff = s->argp - (byte*)s->sp; + child->argoff = s->argp - (byte*)s->fp; child->arglen = s->arglen; child->sp = (byte*)s->sp; child->depth++; @@ -853,11 +860,13 @@ dumpefacetypes(void *obj, uintptr size, Type *type, uintptr kind) playgcprog(0, (uintptr*)type->gc + 1, dumpeface_callback, obj); break; case TypeInfo_Array: - for(i = 0; i < size; i += type->size) + for(i = 0; i <= size - type->size; i += type->size) playgcprog(i, (uintptr*)type->gc + 1, dumpeface_callback, obj); break; case TypeInfo_Chan: - for(i = runtime·Hchansize; i < size; i += type->size) + if(type->size == 0) // channels may have zero-sized objects in them + break; + for(i = runtime·Hchansize; i <= size - type->size; i += type->size) playgcprog(i, (uintptr*)type->gc + 1, dumpeface_callback, obj); break; } |
