diff options
author | Ian Lance Taylor <iant@golang.org> | 2018-02-26 14:03:47 -0800 |
---|---|---|
committer | Ian Lance Taylor <iant@golang.org> | 2018-03-07 23:35:25 +0000 |
commit | 419c06455a91c54a0552e1eb1565c397dd6fa763 (patch) | |
tree | d849fa34ce017185a2d0f8fd96c0560dd65c8e71 /src/runtime/vdso_linux.go | |
parent | c2f28de732749425ea29b5efa982c407964f8560 (diff) | |
download | go-419c06455a91c54a0552e1eb1565c397dd6fa763.tar.gz go-419c06455a91c54a0552e1eb1565c397dd6fa763.zip |
runtime: get traceback from VDSO code
Currently if a profiling signal arrives while executing within a VDSO
the profiler will report _ExternalCode, which is needlessly confusing
for a pure Go program. Change the VDSO calling code to record the
caller's PC/SP, so that we can do a traceback from that point. If that
fails for some reason, report _VDSO rather than _ExternalCode, which
should at least point in the right direction.
This adds some instructions to the code that calls the VDSO, but the
slowdown is reasonably negligible:
name old time/op new time/op delta
ClockVDSOAndFallbackPaths/vDSO-8 40.5ns ± 2% 41.3ns ± 1% +1.85% (p=0.002 n=10+10)
ClockVDSOAndFallbackPaths/Fallback-8 41.9ns ± 1% 43.5ns ± 1% +3.84% (p=0.000 n=9+9)
TimeNow-8 41.5ns ± 3% 41.5ns ± 2% ~ (p=0.723 n=10+10)
Fixes #24142
Change-Id: Iacd935db3c4c782150b3809aaa675a71799b1c9c
Reviewed-on: https://go-review.googlesource.com/97315
Run-TryBot: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Austin Clements <austin@google.com>
Diffstat (limited to 'src/runtime/vdso_linux.go')
-rw-r--r-- | src/runtime/vdso_linux.go | 11 |
1 files changed, 11 insertions, 0 deletions
diff --git a/src/runtime/vdso_linux.go b/src/runtime/vdso_linux.go index 6f4c5bb83e..7939bb54be 100644 --- a/src/runtime/vdso_linux.go +++ b/src/runtime/vdso_linux.go @@ -279,3 +279,14 @@ func vdsoauxv(tag, val uintptr) { vdsoParseSymbols(info1, vdsoFindVersion(info1, &linux26)) } } + +// vdsoMarker returns whether PC is on the VDSO page. +func inVDSOPage(pc uintptr) bool { + for _, k := range vdsoSymbolKeys { + if *k.ptr != 0 { + page := *k.ptr &^ (physPageSize - 1) + return pc >= page && pc < page+physPageSize + } + } + return false +} |