diff options
| author | Dmitriy Vyukov <dvyukov@google.com> | 2013-08-13 22:12:02 +0400 |
|---|---|---|
| committer | Dmitriy Vyukov <dvyukov@google.com> | 2013-08-13 22:12:02 +0400 |
| commit | cc4e6aad8ec18b4ee7fe0392f30f229ddb979589 (patch) | |
| tree | 73680a46d29bf17e50838c8ac4e3546780d52699 /src/pkg/runtime/proc.c | |
| parent | 1da1030b5dd9d9610ccada4413a23e77b21c7f3b (diff) | |
| download | go-cc4e6aad8ec18b4ee7fe0392f30f229ddb979589.tar.xz | |
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
Diffstat (limited to 'src/pkg/runtime/proc.c')
| -rw-r--r-- | src/pkg/runtime/proc.c | 31 |
1 files changed, 25 insertions, 6 deletions
diff --git a/src/pkg/runtime/proc.c b/src/pkg/runtime/proc.c index ef4d27f314..10a25f0a95 100644 --- a/src/pkg/runtime/proc.c +++ b/src/pkg/runtime/proc.c @@ -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); } |
