From 5ac2fd0d6edd8198ed10b66f48402678471c044c Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Fri, 27 Jul 2018 18:43:34 +0000 Subject: libgo: prune sighandler frames in runtime.sigprof When writing stack frames to the pprof CPU profile machinery, it is very important to insure that the frames emitted do not contain any frames corresponding to artifacts of the profiling process itself (signal handlers, sigprof, etc). This patch changes runtime.sigprof to strip out those frames from the raw stack generated by "runtime.callers". Fixes golang/go#26595. Reviewed-on: https://go-review.googlesource.com/126175 From-SVN: r263035 --- libgo/go/runtime/proc.go | 30 +++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) (limited to 'libgo/go/runtime/proc.go') diff --git a/libgo/go/runtime/proc.go b/libgo/go/runtime/proc.go index a6746c9..5826958 100644 --- a/libgo/go/runtime/proc.go +++ b/libgo/go/runtime/proc.go @@ -3418,8 +3418,36 @@ func sigprof(pc uintptr, gp *g, mp *m) { var stklocs [maxCPUProfStack]location n = callers(0, stklocs[:]) + // Issue 26595: the stack trace we've just collected is going + // to include frames that we don't want to report in the CPU + // profile, including signal handler frames. Here is what we + // might typically see at the point of "callers" above for a + // signal delivered to the application routine "interesting" + // called by "main". + // + // 0: runtime.sigprof + // 1: runtime.sighandler + // 2: runtime.sigtrampgo + // 3: runtime.sigtramp + // 4: + // 5: main.interesting_routine + // 6: main.main + // + // To ensure a sane profile, walk through the frames in + // "stklocs" until we find the "runtime.sigtramp" frame, then + // report only those frames below the frame one down from + // that. If for some reason "runtime.sigtramp" is not present, + // don't make any changes. + framesToDiscard := 0 + for i := 0; i < n; i++ { + if stklocs[i].function == "runtime.sigtramp" && i+2 < n { + framesToDiscard = i + 2 + n -= framesToDiscard + break + } + } for i := 0; i < n; i++ { - stk[i] = stklocs[i].pc + stk[i] = stklocs[i+framesToDiscard].pc } } -- cgit v1.1