mirror of https://github.com/golang/go.git
runtime: do no lose CPU profiling signals
Currently we lose lots of profiling signals. Most notably, GC is not accounted at all. But stack splits, scheduler, syscalls, etc are lost as well. This creates seriously misleading profile. With this change all profiling signals are accounted. Now I see these additional entries that were previously absent: 161 29.7% 29.7% 164 30.3% syscall.Syscall 12 2.2% 50.9% 12 2.2% scanblock 11 2.0% 55.0% 11 2.0% markonly 10 1.8% 58.9% 10 1.8% sweepspan 2 0.4% 85.8% 2 0.4% runtime.newstack It is still impossible to understand what causes stack splits, but at least it's clear how many time is spent on them. Update #2197. Update #5659. R=golang-dev, rsc CC=golang-dev https://golang.org/cl/12179043
This commit is contained in:
parent
1da1030b5d
commit
cc4e6aad8e
|
|
@ -1990,26 +1990,45 @@ static struct {
|
|||
uintptr pcbuf[100];
|
||||
} prof;
|
||||
|
||||
static void
|
||||
System(void)
|
||||
{
|
||||
}
|
||||
|
||||
// Called if we receive a SIGPROF signal.
|
||||
void
|
||||
runtime·sigprof(uint8 *pc, uint8 *sp, uint8 *lr, G *gp)
|
||||
{
|
||||
int32 n;
|
||||
bool traceback;
|
||||
|
||||
// Windows does profiling in a dedicated thread w/o m.
|
||||
if(!Windows && (m == nil || m->mcache == nil))
|
||||
return;
|
||||
if(prof.fn == nil || prof.hz == 0)
|
||||
return;
|
||||
traceback = true;
|
||||
// Windows does profiling in a dedicated thread w/o m.
|
||||
if(!Windows && (m == nil || m->mcache == nil))
|
||||
traceback = false;
|
||||
if(gp == m->g0 || gp == m->gsignal)
|
||||
traceback = false;
|
||||
// Race detector calls asmcgocall w/o entersyscall/exitsyscall,
|
||||
// we can not currently unwind through asmcgocall.
|
||||
if(m != nil && m->racecall)
|
||||
traceback = false;
|
||||
|
||||
runtime·lock(&prof);
|
||||
if(prof.fn == nil) {
|
||||
runtime·unlock(&prof);
|
||||
return;
|
||||
}
|
||||
n = runtime·gentraceback((uintptr)pc, (uintptr)sp, (uintptr)lr, gp, 0, prof.pcbuf, nelem(prof.pcbuf), nil, nil, false);
|
||||
if(n > 0)
|
||||
prof.fn(prof.pcbuf, n);
|
||||
n = 0;
|
||||
if(traceback)
|
||||
n = runtime·gentraceback((uintptr)pc, (uintptr)sp, (uintptr)lr, gp, 0, prof.pcbuf, nelem(prof.pcbuf), nil, nil, false);
|
||||
if(!traceback || n <= 0) {
|
||||
n = 2;
|
||||
prof.pcbuf[0] = (uintptr)pc;
|
||||
prof.pcbuf[1] = (uintptr)System + 1;
|
||||
}
|
||||
prof.fn(prof.pcbuf, n);
|
||||
runtime·unlock(&prof);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -39,8 +39,7 @@ runtime·sighandler(int32 sig, Siginfo *info, void *ctxt, G *gp)
|
|||
bool crash;
|
||||
|
||||
if(sig == SIGPROF) {
|
||||
if(gp != m->g0 && gp != m->gsignal)
|
||||
runtime·sigprof((byte*)SIG_EIP(info, ctxt), (byte*)SIG_ESP(info, ctxt), nil, gp);
|
||||
runtime·sigprof((byte*)SIG_EIP(info, ctxt), (byte*)SIG_ESP(info, ctxt), nil, gp);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -47,8 +47,7 @@ runtime·sighandler(int32 sig, Siginfo *info, void *ctxt, G *gp)
|
|||
bool crash;
|
||||
|
||||
if(sig == SIGPROF) {
|
||||
if(gp != m->g0 && gp != m->gsignal)
|
||||
runtime·sigprof((byte*)SIG_RIP(info, ctxt), (byte*)SIG_RSP(info, ctxt), nil, gp);
|
||||
runtime·sigprof((byte*)SIG_RIP(info, ctxt), (byte*)SIG_RSP(info, ctxt), nil, gp);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -46,8 +46,7 @@ runtime·sighandler(int32 sig, Siginfo *info, void *ctxt, G *gp)
|
|||
bool crash;
|
||||
|
||||
if(sig == SIGPROF) {
|
||||
if(gp != m->g0 && gp != m->gsignal)
|
||||
runtime·sigprof((uint8*)SIG_PC(info, ctxt), (uint8*)SIG_SP(info, ctxt), (uint8*)SIG_LR(info, ctxt), gp);
|
||||
runtime·sigprof((uint8*)SIG_PC(info, ctxt), (uint8*)SIG_SP(info, ctxt), (uint8*)SIG_LR(info, ctxt), gp);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue