summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorRuss Cox <rsc@golang.org>2014-09-17 16:12:17 -0400
committerRuss Cox <rsc@golang.org>2014-09-17 16:12:17 -0400
commit022dacba94475cb76d850c8cfd61b38ce7e0cc8f (patch)
treebacc837544628a336fcdc12f873ebfa38f5672cc /src
parent5af41f590262c5e82f275e07054eee9107b85132 (diff)
downloadgo-022dacba94475cb76d850c8cfd61b38ce7e0cc8f.tar.gz
runtime: print more detail in adjustframe crash
The logic here is copied from mgc0.c's scanframe. Mostly it is messages although the minsize code is new (and I believe necessary). I am hoping to get more information about the current arm build failures (or, if it's the minsize thing, fix them). TBR=khr R=khr CC=golang-codereviews https://codereview.appspot.com/143180043
Diffstat (limited to 'src')
-rw-r--r--src/runtime/stack.c46
1 files changed, 33 insertions, 13 deletions
diff --git a/src/runtime/stack.c b/src/runtime/stack.c
index 143b645e4..b38ee31d4 100644
--- a/src/runtime/stack.c
+++ b/src/runtime/stack.c
@@ -463,7 +463,7 @@ adjustframe(Stkframe *frame, void *arg)
StackMap *stackmap;
int32 pcdata;
BitVector bv;
- uintptr targetpc;
+ uintptr targetpc, size, minsize;
adjinfo = arg;
targetpc = frame->continpc;
@@ -486,27 +486,47 @@ adjustframe(Stkframe *frame, void *arg)
if(pcdata == -1)
pcdata = 0; // in prologue
- // adjust local pointers
- if((byte*)frame->varp != (byte*)frame->sp) {
+ // Adjust local variables if stack frame has been allocated.
+ size = frame->varp - frame->sp;
+ if(thechar != '6' && thechar != '8')
+ minsize = sizeof(uintptr);
+ else
+ minsize = 0;
+ if(size > minsize) {
stackmap = runtime·funcdata(f, FUNCDATA_LocalsPointerMaps);
- if(stackmap == nil)
- runtime·throw("no locals info");
- if(stackmap->n <= 0)
- runtime·throw("locals size info only");
+ if(stackmap == nil || stackmap->n <= 0) {
+ runtime·printf("runtime: frame %s untyped locals %p+%p\n", runtime·funcname(f), (byte*)(frame->varp-size), size);
+ runtime·throw("missing stackmap");
+ }
+ // Locals bitmap information, scan just the pointers in locals.
+ if(pcdata < 0 || pcdata >= stackmap->n) {
+ // don't know where we are
+ runtime·printf("runtime: pcdata is %d and %d locals stack map entries for %s (targetpc=%p)\n",
+ pcdata, stackmap->n, runtime·funcname(f), targetpc);
+ runtime·throw("bad symbol table");
+ }
bv = runtime·stackmapdata(stackmap, pcdata);
+ size = (bv.n * PtrSize) / BitsPerPointer;
if(StackDebug >= 3)
runtime·printf(" locals\n");
- adjustpointers((byte**)frame->varp - bv.n / BitsPerPointer, &bv, adjinfo, f);
+ adjustpointers((byte**)(frame->varp - size), &bv, adjinfo, f);
}
- // adjust inargs and outargs
- if(frame->arglen != 0) {
+
+ // Adjust arguments.
+ if(frame->arglen > 0) {
if(frame->argmap != nil) {
bv = *frame->argmap;
} else {
stackmap = runtime·funcdata(f, FUNCDATA_ArgsPointerMaps);
- if(stackmap == nil) {
- runtime·printf("size %d\n", (int32)frame->arglen);
- runtime·throw("no arg info");
+ if(stackmap == nil || stackmap->n <= 0) {
+ runtime·printf("runtime: frame %s untyped args %p+%p\n", runtime·funcname(f), frame->argp, (uintptr)frame->arglen);
+ runtime·throw("missing stackmap");
+ }
+ if(pcdata < 0 || pcdata >= stackmap->n) {
+ // don't know where we are
+ runtime·printf("runtime: pcdata is %d and %d args stack map entries for %s (targetpc=%p)\n",
+ pcdata, stackmap->n, runtime·funcname(f), targetpc);
+ runtime·throw("bad symbol table");
}
bv = runtime·stackmapdata(stackmap, pcdata);
}