aboutsummaryrefslogtreecommitdiff
path: root/src/pkg/runtime
diff options
context:
space:
mode:
authorKeith Randall <khr@golang.org>2014-04-07 17:35:44 -0700
committerKeith Randall <khr@golang.org>2014-04-07 17:35:44 -0700
commitaf923df89ee65428b0a8cba7323e9397926ea0e6 (patch)
tree1348f2a7fcbcfafc155a8386f07d376e996a3b86 /src/pkg/runtime
parenta2a351478bb223891ebe8c1ae09c6ad09648f138 (diff)
downloadgo-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.c17
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;
}