mirror of
https://github.com/golang/go
synced 2024-11-23 08:20:05 -07:00
runtime: save LR to stack when panicking to handle leaf function traceback
R=golang-dev, rsc CC=golang-dev https://golang.org/cl/7289047
This commit is contained in:
parent
4360ef8de2
commit
7de3d71797
@ -68,11 +68,17 @@ runtime·sighandler(int32 sig, Siginfo *info, void *context, G *gp)
|
||||
gp->sigcode1 = r->fault_address;
|
||||
gp->sigpc = r->arm_pc;
|
||||
|
||||
// If this is a leaf function, we do smash LR,
|
||||
// but we're not going back there anyway.
|
||||
// Don't bother smashing if r->arm_pc is 0,
|
||||
// which is probably a call to a nil func: the
|
||||
// old link register is more useful in the stack trace.
|
||||
// We arrange lr, and pc to pretend the panicking
|
||||
// function calls sigpanic directly.
|
||||
// Always save LR to stack so that panics in leaf
|
||||
// functions are correctly handled. This smashes
|
||||
// the stack frame but we're not going back there
|
||||
// anyway.
|
||||
r->arm_sp -= 4;
|
||||
*(uint32 *)r->arm_sp = r->arm_lr;
|
||||
// Don't bother saving PC if it's zero, which is
|
||||
// probably a call to a nil func: the old link register
|
||||
// is more useful in the stack trace.
|
||||
if(r->arm_pc != 0)
|
||||
r->arm_lr = r->arm_pc;
|
||||
// In case we are panicking from external C code
|
||||
|
@ -182,6 +182,12 @@ runtime·gentraceback(byte *pc0, byte *sp, byte *lr0, G *gp, int32 skip, uintptr
|
||||
// If this was deferproc or newproc, the caller had an extra 12.
|
||||
if(f->entry == (uintptr)runtime·deferproc || f->entry == (uintptr)runtime·newproc)
|
||||
sp += 12;
|
||||
|
||||
// sighandler saves the lr on stack before fake a call to sigpanic
|
||||
if(waspanic) {
|
||||
pc = *(uintptr *)sp;
|
||||
sp += 4;
|
||||
}
|
||||
}
|
||||
|
||||
if(pcbuf == nil && (pc = gp->gopc) != 0 && (f = runtime·findfunc(pc)) != nil
|
||||
|
Loading…
Reference in New Issue
Block a user