]> Cypherpunks repositories - gostls13.git/commit
[release-branch.go1.5] runtime: don't install a stack barrier in cgocallback_gofunc...
authorAustin Clements <austin@google.com>
Wed, 26 Aug 2015 16:16:51 +0000 (12:16 -0400)
committerAndrew Gerrand <adg@golang.org>
Tue, 8 Sep 2015 06:04:48 +0000 (06:04 +0000)
commit23ef1e1933f4483572159277a99f2efc5003e1a2
treeec5b5ce024f8d827d20c3f18e3e21ef29a1d1779
parentf7d740377612142c6a08e460b5c542ebe0d758b3
[release-branch.go1.5] runtime: don't install a stack barrier in cgocallback_gofunc's frame

Currently the runtime can install stack barriers in any frame.
However, the frame of cgocallback_gofunc is special: it's the one
function that switches from a regular G stack to the system stack on
return. Hence, the return PC slot in its frame on the G stack is
actually used to save getg().sched.pc (so tracebacks appear to unwind
to the last Go function running on that G), and not as an actual
return PC for cgocallback_gofunc.

Because of this, if we install a stack barrier in cgocallback_gofunc's
return PC slot, when cgocallback_gofunc does return, it will move the
stack barrier stub PC in to getg().sched.pc and switch back to the
system stack. The rest of the runtime doesn't know how to deal with a
stack barrier stub in sched.pc: nothing knows how to match it up with
the G's stack barrier array and, when the runtime removes stack
barriers, it doesn't know to undo the one in sched.pc. Hence, if the C
code later returns back in to Go code, it will attempt to return
through the stack barrier saved in sched.pc, which may no longer have
correct unwinding information.

Fix this by blacklisting cgocallback_gofunc's frame so the runtime
won't install a stack barrier in it's return PC slot.

Fixes #12238.

Change-Id: I46aa2155df2fd050dd50de3434b62987dc4947b8
Reviewed-on: https://go-review.googlesource.com/13944
Reviewed-by: Russ Cox <rsc@golang.org>
Reviewed-on: https://go-review.googlesource.com/14229
Reviewed-by: Austin Clements <austin@google.com>
src/runtime/asm_amd64p32.s
src/runtime/mgcmark.go
src/runtime/traceback.go