1
0
mirror of https://github.com/golang/go synced 2024-11-26 16:16:57 -07:00

runtime: do not treat mcall as a topofstack

I added mcall to this list in 2013 without explaining why.
(https://codereview.appspot.com/11085043/diff/61001/src/pkg/runtime/traceback_x86.c)
I suspect I was stopping crashes during profiling where the unwind
tried to walk up past mcall and got confused.

mcall is not something you can unwind past, because it switches
stacks, but it's also not something you should expect as a
standard top-of-stack frame. So if you do see it during say
a garbage collection stack walk, it would be important to crash
instead of silently stopping the walk prematurely.

This CL removes it from the topofstack list to avoid the silent stop.
Now that mcall is detected as SPWRITE, that will stop the
unwind (with a crash if encountered during GC, which we want).

This CL is part of a stack adding windows/arm64
support (#36439), intended to land in the Go 1.17 cycle.
This CL is, however, not windows/arm64-specific.
It is cleanup meant to make the port (and future ports) easier.

Change-Id: I666487ce24efd72292f2bc3eac7fe0477e16bddd
Reviewed-on: https://go-review.googlesource.com/c/go/+/288803
Trust: Russ Cox <rsc@golang.org>
Reviewed-by: Cherry Zhang <cherryyz@google.com>
This commit is contained in:
Russ Cox 2021-01-28 17:17:38 -05:00
parent 54da3ab385
commit 5ecd9e34df
2 changed files with 14 additions and 1 deletions

View File

@ -337,7 +337,21 @@ const (
type funcFlag uint8 type funcFlag uint8
const ( const (
// TOPFRAME indicates a function that appears at the top of its stack.
// The traceback routine stop at such a function and consider that a
// successful, complete traversal of the stack.
// Examples of TOPFRAME functions include goexit, which appears
// at the top of a user goroutine stack, and mstart, which appears
// at the top of a system goroutine stack.
funcFlag_TOPFRAME funcFlag = 1 << iota funcFlag_TOPFRAME funcFlag = 1 << iota
// SPWRITE indicates a function that writes an arbitrary value to SP
// (any write other than adding or subtracting a constant amount).
// The traceback routines cannot encode such changes into the
// pcsp tables, so the function traceback cannot safely unwind past
// SPWRITE functions. Stopping at an SPWRITE function is considered
// to be an incomplete unwinding of the stack. In certain contexts
// (in particular garbage collector stack scans) that is a fatal error.
funcFlag_SPWRITE funcFlag_SPWRITE
) )

View File

@ -1003,7 +1003,6 @@ func tracebackHexdump(stk stack, frame *stkframe, bad uintptr) {
// Does f mark the top of a goroutine stack? // Does f mark the top of a goroutine stack?
func topofstack(f funcInfo, g0 bool) bool { func topofstack(f funcInfo, g0 bool) bool {
return f.flag&funcFlag_TOPFRAME != 0 || return f.flag&funcFlag_TOPFRAME != 0 ||
f.funcID == funcID_mcall ||
f.funcID == funcID_morestack || f.funcID == funcID_morestack ||
// asmcgocall is TOS on the system stack because it // asmcgocall is TOS on the system stack because it
// switches to the system stack, but in this case we // switches to the system stack, but in this case we