// Starting from scanp, scans words corresponding to set bits.
static void
-scanbitvector(byte *scanp, BitVector *bv, bool afterprologue, void *wbufp)
+scanbitvector(Func *f, bool precise, byte *scanp, BitVector *bv, bool afterprologue, void *wbufp)
{
uintptr word, bits;
uint32 *wordp;
break;
case BitsPointer:
p = *(byte**)scanp;
- if(p != nil)
+ if(p != nil) {
+ if(precise && p < (byte*)PageSize) {
+ // Looks like a junk value in a pointer slot.
+ // Liveness analysis wrong?
+ m->traceback = 2;
+ runtime·printf("bad pointer in frame %s at %p: %p\n", runtime·funcname(f), scanp, p);
+ runtime·throw("bad pointer in scanbitvector");
+ }
enqueue1(wbufp, (Obj){scanp, PtrSize, 0});
+ }
break;
case BitsMultiWord:
p = *(byte**)scanp;
markonly(p);
break;
case BitsSlice:
- if(((Slice*)(scanp - PtrSize))->cap < ((Slice*)(scanp - PtrSize))->len)
+ if(((Slice*)(scanp - PtrSize))->cap < ((Slice*)(scanp - PtrSize))->len) {
+ m->traceback = 2;
+ runtime·printf("bad slice in frame %s at %p: %p/%p/%p\n", runtime·funcname(f), scanp, ((byte**)scanp)[0], ((byte**)scanp)[1], ((byte**)scanp)[2]);
runtime·throw("slice capacity smaller than length");
+ }
if(((Slice*)(scanp - PtrSize))->cap != 0)
enqueue1(wbufp, (Obj){scanp - PtrSize, PtrSize, 0});
break;
uintptr targetpc;
int32 pcdata;
bool afterprologue;
+ bool precise;
f = frame->fn;
targetpc = frame->pc;
// Scan local variables if stack frame has been allocated.
// Use pointer information if known.
afterprologue = (frame->varp > (byte*)frame->sp);
+ precise = false;
if(afterprologue) {
stackmap = runtime·funcdata(f, FUNCDATA_LocalsPointerMaps);
if(stackmap == nil) {
}
bv = runtime·stackmapdata(stackmap, pcdata);
size = (bv->n * PtrSize) / BitsPerPointer;
- scanbitvector(frame->varp - size, bv, afterprologue, wbufp);
+ precise = true;
+ scanbitvector(f, true, frame->varp - size, bv, afterprologue, wbufp);
}
}
stackmap = runtime·funcdata(f, FUNCDATA_ArgsPointerMaps);
if(stackmap != nil) {
bv = runtime·stackmapdata(stackmap, pcdata);
- scanbitvector(frame->argp, bv, true, wbufp);
+ scanbitvector(f, precise, frame->argp, bv, true, wbufp);
} else
enqueue1(wbufp, (Obj){frame->argp, frame->arglen, 0});
return true;
int32
runtime·gentraceback(uintptr pc0, uintptr sp0, uintptr lr0, G *gp, int32 skip, uintptr *pcbuf, int32 max, bool (*callback)(Stkframe*, void*), void *v, bool printall)
{
- int32 i, n, nprint, line;
+ int32 i, n, nprint, line, gotraceback;
uintptr x, tracepc;
bool waspanic, printing;
Func *f, *flr;
Stkframe frame;
Stktop *stk;
String file;
+
+ gotraceback = runtime·gotraceback(nil);
if(pc0 == ~(uintptr)0 && sp0 == ~(uintptr)0) { // Signal to fetch saved values from gp.
if(gp->syscallstack != (uintptr)nil) {
runtime·printf("\t%S:%d", file, line);
if(frame.pc > f->entry)
runtime·printf(" +%p", (uintptr)(frame.pc - f->entry));
- if(m->throwing > 0 && gp == m->curg)
+ if(m->throwing > 0 && gp == m->curg || gotraceback >= 2)
runtime·printf(" fp=%p", frame.fp);
runtime·printf("\n");
nprint++;
int32
runtime·gentraceback(uintptr pc0, uintptr sp0, uintptr lr0, G *gp, int32 skip, uintptr *pcbuf, int32 max, bool (*callback)(Stkframe*, void*), void *v, bool printall)
{
- int32 i, n, nprint, line;
+ int32 i, n, nprint, line, gotraceback;
uintptr tracepc;
bool waspanic, printing;
Func *f, *flr;
USED(lr0);
+ gotraceback = runtime·gotraceback(nil);
+
if(pc0 == ~(uintptr)0 && sp0 == ~(uintptr)0) { // Signal to fetch saved values from gp.
if(gp->syscallstack != (uintptr)nil) {
pc0 = gp->syscallpc;
runtime·printf("\t%S:%d", file, line);
if(frame.pc > f->entry)
runtime·printf(" +%p", (uintptr)(frame.pc - f->entry));
- if(m->throwing > 0 && gp == m->curg)
+ if(m->throwing > 0 && gp == m->curg || gotraceback >= 2)
runtime·printf(" fp=%p", frame.fp);
runtime·printf("\n");
nprint++;