mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
cmd/6g, liblink, runtime: support saving base pointers
This adds a "framepointer" GOEXPERIMENT that that makes the amd64 toolchain maintain base pointer chains in the same way that gcc -fno-omit-frame-pointer does. Go doesn't use these saved base pointers, but this does enable external tools like Linux perf and VTune to unwind Go stacks when collecting system-wide profiles. This requires support in the compilers to not clobber BP, support in liblink for generating the BP-saving function prologue and unwinding epilogue, and support in the runtime to save BPs across preemption, to skip saved BPs during stack unwinding and, and to adjust saved BPs during stack moving. As with other GOEXPERIMENTs, everything from the toolchain to the runtime must be compiled with this experiment enabled. To do this, run make.bash (or all.bash) with GOEXPERIMENT=framepointer. Change-Id: I4024853beefb9539949e5ca381adfdd9cfada544 Reviewed-on: https://go-review.googlesource.com/2992 Reviewed-by: Russ Cox <rsc@golang.org>
This commit is contained in:
parent
20a6ff7261
commit
3c0fee10db
12 changed files with 134 additions and 8 deletions
|
|
@ -46,6 +46,9 @@ var stackpoolmu mutex
|
|||
|
||||
var stackfreequeue stack
|
||||
|
||||
// Cached value of haveexperiment("framepointer")
|
||||
var framepointer_enabled bool
|
||||
|
||||
func stackinit() {
|
||||
if _StackCacheSize&_PageMask != 0 {
|
||||
throw("cache size must be a multiple of page size")
|
||||
|
|
@ -308,6 +311,8 @@ var mapnames = []string{
|
|||
// | args from caller |
|
||||
// +------------------+ <- frame->argp
|
||||
// | return address |
|
||||
// +------------------+
|
||||
// | caller's BP (*) | (*) if framepointer_enabled && varp < sp
|
||||
// +------------------+ <- frame->varp
|
||||
// | locals |
|
||||
// +------------------+
|
||||
|
|
@ -460,6 +465,18 @@ func adjustframe(frame *stkframe, arg unsafe.Pointer) bool {
|
|||
adjustpointers(unsafe.Pointer(frame.varp-size), &bv, adjinfo, f)
|
||||
}
|
||||
|
||||
// Adjust saved base pointer if there is one.
|
||||
if thechar == '6' && frame.argp-frame.varp == 2*ptrSize {
|
||||
if !framepointer_enabled {
|
||||
print("runtime: found space for saved base pointer, but no framepointer experiment")
|
||||
throw("bad frame layout")
|
||||
}
|
||||
if stackDebug >= 3 {
|
||||
print(" saved bp\n")
|
||||
}
|
||||
adjustpointer(adjinfo, unsafe.Pointer(frame.varp))
|
||||
}
|
||||
|
||||
// Adjust arguments.
|
||||
if frame.arglen > 0 {
|
||||
var bv bitvector
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue