1
0
mirror of https://github.com/golang/go synced 2024-11-25 20:37:56 -07:00

undo CL 12250043 / e911f94c4902

Break all 386 builders.

««« original CL description
runtime: use gcpc/gcsp during traceback of goroutines in syscalls
gcpc/gcsp are used by GC in similar situation.
gcpc/gcsp are also more stable than gp->sched,
because gp->sched is mutated by entersyscall/exitsyscall
in morestack and mcall. So it has higher chances of being inconsistent.
Also, rename gcpc/gcsp to syscallpc/syscallsp.

R=golang-dev, rsc
CC=golang-dev
https://golang.org/cl/12250043
»»»

R=rsc
CC=golang-dev
https://golang.org/cl/12424045
This commit is contained in:
Dmitriy Vyukov 2013-08-05 23:33:50 +04:00
parent 7963ba6a4a
commit f38ff9e5ea
5 changed files with 33 additions and 32 deletions

View File

@ -1457,17 +1457,17 @@ addstackroots(G *gp)
runtime·throw("can't scan our own stack"); runtime·throw("can't scan our own stack");
if((mp = gp->m) != nil && mp->helpgc) if((mp = gp->m) != nil && mp->helpgc)
runtime·throw("can't scan gchelper stack"); runtime·throw("can't scan gchelper stack");
if(gp->syscallstack != (uintptr)nil) { if(gp->gcstack != (uintptr)nil) {
// Scanning another goroutine that is about to enter or might // Scanning another goroutine that is about to enter or might
// have just exited a system call. It may be executing code such // have just exited a system call. It may be executing code such
// as schedlock and may have needed to start a new stack segment. // as schedlock and may have needed to start a new stack segment.
// Use the stack segment and stack pointer at the time of // Use the stack segment and stack pointer at the time of
// the system call instead, since that won't change underfoot. // the system call instead, since that won't change underfoot.
sp = gp->syscallsp; sp = gp->gcsp;
pc = gp->syscallpc; pc = gp->gcpc;
lr = 0; lr = 0;
stk = (Stktop*)gp->syscallstack; stk = (Stktop*)gp->gcstack;
guard = gp->syscallguard; guard = gp->gcguard;
} else { } else {
// Scanning another goroutine's stack. // Scanning another goroutine's stack.
// The goroutine is usually asleep (the world is stopped). // The goroutine is usually asleep (the world is stopped).

View File

@ -1358,6 +1358,8 @@ goexit0(G *gp)
static void static void
save(void *pc, uintptr sp) save(void *pc, uintptr sp)
{ {
g->gcpc = (uintptr)pc;
g->gcsp = sp;
g->sched.pc = (uintptr)pc; g->sched.pc = (uintptr)pc;
g->sched.sp = sp; g->sched.sp = sp;
g->sched.lr = 0; g->sched.lr = 0;
@ -1385,16 +1387,15 @@ void
if(m->profilehz > 0) if(m->profilehz > 0)
runtime·setprof(false); runtime·setprof(false);
// Leave SP around for GC and traceback. // Leave SP around for gc and traceback.
save(runtime·getcallerpc(&dummy), runtime·getcallersp(&dummy)); save(runtime·getcallerpc(&dummy), runtime·getcallersp(&dummy));
g->syscallsp = g->sched.sp;
g->syscallpc = g->sched.pc; g->gcstack = g->stackbase;
g->syscallstack = g->stackbase; g->gcguard = g->stackguard;
g->syscallguard = g->stackguard;
g->status = Gsyscall; g->status = Gsyscall;
if(g->syscallsp < g->syscallguard-StackGuard || g->syscallstack < g->syscallsp) { if(g->gcsp < g->gcguard-StackGuard || g->gcstack < g->gcsp) {
// runtime·printf("entersyscall inconsistent %p [%p,%p]\n", // runtime·printf("entersyscall inconsistent %p [%p,%p]\n",
// g->syscallsp, g->syscallguard-StackGuard, g->syscallstack); // g->gcsp, g->gcguard-StackGuard, g->gcstack);
runtime·throw("entersyscall"); runtime·throw("entersyscall");
} }
@ -1441,16 +1442,16 @@ void
if(m->profilehz > 0) if(m->profilehz > 0)
runtime·setprof(false); runtime·setprof(false);
// Leave SP around for GC and traceback. // Leave SP around for gc and traceback.
save(runtime·getcallerpc(&dummy), runtime·getcallersp(&dummy)); save(runtime·getcallerpc(&dummy), runtime·getcallersp(&dummy));
g->syscallsp = g->sched.sp; g->gcsp = g->sched.sp;
g->syscallpc = g->sched.pc; g->gcpc = g->sched.pc;
g->syscallstack = g->stackbase; g->gcstack = g->stackbase;
g->syscallguard = g->stackguard; g->gcguard = g->stackguard;
g->status = Gsyscall; g->status = Gsyscall;
if(g->syscallsp < g->syscallguard-StackGuard || g->syscallstack < g->syscallsp) { if(g->gcsp < g->gcguard-StackGuard || g->gcstack < g->gcsp) {
// runtime·printf("entersyscall inconsistent %p [%p,%p]\n", // runtime·printf("entersyscallblock inconsistent %p [%p,%p]\n",
// g->syscallsp, g->syscallguard-StackGuard, g->syscallstack); // g->gcsp, g->gcguard-StackGuard, g->gcstack);
runtime·throw("entersyscallblock"); runtime·throw("entersyscallblock");
} }
@ -1489,8 +1490,8 @@ runtime·exitsyscall(void)
g->status = Grunning; g->status = Grunning;
// Garbage collector isn't running (since we are), // Garbage collector isn't running (since we are),
// so okay to clear gcstack and gcsp. // so okay to clear gcstack and gcsp.
g->syscallstack = (uintptr)nil; g->gcstack = (uintptr)nil;
g->syscallsp = (uintptr)nil; g->gcsp = (uintptr)nil;
m->locks--; m->locks--;
if(g->preempt) { if(g->preempt) {
// restore the preemption request in case we've cleared it in newstack // restore the preemption request in case we've cleared it in newstack
@ -1513,8 +1514,8 @@ runtime·exitsyscall(void)
// Must wait until now because until gosched returns // Must wait until now because until gosched returns
// we don't know for sure that the garbage collector // we don't know for sure that the garbage collector
// is not running. // is not running.
g->syscallstack = (uintptr)nil; g->gcstack = (uintptr)nil;
g->syscallsp = (uintptr)nil; g->gcsp = (uintptr)nil;
} }
#pragma textflag 7 #pragma textflag 7

View File

@ -253,10 +253,10 @@ struct G
Defer* defer; Defer* defer;
Panic* panic; Panic* panic;
Gobuf sched; Gobuf sched;
uintptr syscallstack; // if status==Gsyscall, syscallstack = stackbase to use during gc uintptr gcstack; // if status==Gsyscall, gcstack = stackbase to use during gc
uintptr syscallguard; // if status==Gsyscall, syscallguard = stackguard to use during gc uintptr gcsp; // if status==Gsyscall, gcsp = sched.sp to use during gc
uintptr syscallsp; // if status==Gsyscall, syscallsp = sched.sp to use during gc uintptr gcpc; // if status==Gsyscall, gcpc = sched.pc to use during gc
uintptr syscallpc; // if status==Gsyscall, syscallpc = sched.pc to use during gc uintptr gcguard; // if status==Gsyscall, gcguard = stackguard to use during gc
uintptr stackguard; // same as stackguard0, but not set to StackPreempt uintptr stackguard; // same as stackguard0, but not set to StackPreempt
uintptr stack0; uintptr stack0;
G* alllink; // on allg G* alllink; // on allg

View File

@ -221,8 +221,8 @@ runtime·traceback(uintptr pc, uintptr sp, uintptr lr, G *gp)
{ {
if(gp->status == Gsyscall) { if(gp->status == Gsyscall) {
// Override signal registers if blocked in system call. // Override signal registers if blocked in system call.
pc = gp->syscallpc; pc = gp->sched.pc;
sp = gp->syscallsp; sp = gp->sched.sp;
lr = 0; lr = 0;
} }

View File

@ -229,8 +229,8 @@ runtime·traceback(uintptr pc, uintptr sp, uintptr lr, G *gp)
if(gp->status == Gsyscall) { if(gp->status == Gsyscall) {
// Override signal registers if blocked in system call. // Override signal registers if blocked in system call.
pc = gp->syscallpc; pc = gp->sched.pc;
sp = gp->syscallsp; sp = gp->sched.sp;
} }
// Print traceback. By default, omits runtime frames. // Print traceback. By default, omits runtime frames.