runtime: don't unwind past asmcgocall

asmcgocall switches to the system stack and aligns the SP, so
gentraceback both can't unwind over it when it appears on the system
stack (it'll read some uninitialized stack slot as the return PC).
There's also no point in unwinding over it, so don't.

Updates #23576.

Change-Id: Idfcc9599c7636b80dec5451cb65ae892b4611981
Reviewed-on: https://go-review.googlesource.com/90895
Run-TryBot: Austin Clements <austin@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
diff --git a/src/runtime/traceback.go b/src/runtime/traceback.go
index 62622df..0d5b06a 100644
--- a/src/runtime/traceback.go
+++ b/src/runtime/traceback.go
@@ -43,6 +43,7 @@
 	morestackPC          uintptr
 	mstartPC             uintptr
 	rt0_goPC             uintptr
+	asmcgocallPC         uintptr
 	sigpanicPC           uintptr
 	runfinqPC            uintptr
 	bgsweepPC            uintptr
@@ -70,6 +71,7 @@
 	morestackPC = funcPC(morestack)
 	mstartPC = funcPC(mstart)
 	rt0_goPC = funcPC(rt0_go)
+	asmcgocallPC = funcPC(asmcgocall)
 	sigpanicPC = funcPC(sigpanic)
 	runfinqPC = funcPC(runfinq)
 	bgsweepPC = funcPC(bgsweep)
@@ -251,7 +253,7 @@
 			}
 		}
 		var flr funcInfo
-		if topofstack(f) {
+		if topofstack(f, gp.m != nil && gp == gp.m.g0) {
 			frame.lr = 0
 			flr = funcInfo{}
 		} else if usesLR && f.entry == jmpdeferPC {
@@ -920,14 +922,20 @@
 }
 
 // Does f mark the top of a goroutine stack?
-func topofstack(f funcInfo) bool {
+func topofstack(f funcInfo, g0 bool) bool {
 	pc := f.entry
 	return pc == goexitPC ||
 		pc == mstartPC ||
 		pc == mcallPC ||
 		pc == morestackPC ||
 		pc == rt0_goPC ||
-		externalthreadhandlerp != 0 && pc == externalthreadhandlerp
+		externalthreadhandlerp != 0 && pc == externalthreadhandlerp ||
+		// asmcgocall is TOS on the system stack because it
+		// switches to the system stack, but in this case we
+		// can come back to the regular stack and still want
+		// to be able to unwind through the call that appeared
+		// on the regular stack.
+		(g0 && pc == asmcgocallPC)
 }
 
 // isSystemGoroutine reports whether the goroutine g must be omitted in