aboutsummaryrefslogtreecommitdiff
path: root/src/runtime/preempt.go
diff options
context:
space:
mode:
authorCherry Zhang <cherryyz@google.com>2019-12-18 15:19:05 -0500
committerCherry Zhang <cherryyz@google.com>2019-12-18 21:02:58 +0000
commitdcdee153cd61de47d0cabd6729a17673536b0418 (patch)
treef4bf4ca4bda5c8f8ee047b4f6dacf5ada188f7c1 /src/runtime/preempt.go
parent87a546776b7f5a0a19abc1d439c73b19a974fc28 (diff)
downloadgo-dcdee153cd61de47d0cabd6729a17673536b0418.tar.gz
go-dcdee153cd61de47d0cabd6729a17673536b0418.zip
runtime: use innermost frame's func name for async preemption check
We don't asynchronously preempt if we are in the runtime. We do this by checking the function name. However, it failed to take inlining into account. If a runtime function gets inlined into a non-runtime function, it can be preempted, and bad things can happen. One instance of this is dounlockOSThread inlined into UnlockOSThread which is in turn inlined into a non-runtime function. Fix this by using the innermost frame's function name. Change-Id: Ifa036ce1320700aaaefd829b4bee0d04d05c395d Reviewed-on: https://go-review.googlesource.com/c/go/+/211978 Run-TryBot: Cherry Zhang <cherryyz@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Austin Clements <austin@google.com>
Diffstat (limited to 'src/runtime/preempt.go')
-rw-r--r--src/runtime/preempt.go14
1 files changed, 11 insertions, 3 deletions
diff --git a/src/runtime/preempt.go b/src/runtime/preempt.go
index 2c38ac02f5..420a7f96e0 100644
--- a/src/runtime/preempt.go
+++ b/src/runtime/preempt.go
@@ -411,9 +411,17 @@ func isAsyncSafePoint(gp *g, pc, sp, lr uintptr) bool {
// locals pointer map, like empty frame functions?
return false
}
- if hasPrefix(funcname(f), "runtime.") ||
- hasPrefix(funcname(f), "runtime/internal/") ||
- hasPrefix(funcname(f), "reflect.") {
+ name := funcname(f)
+ if inldata := funcdata(f, _FUNCDATA_InlTree); inldata != nil {
+ inltree := (*[1 << 20]inlinedCall)(inldata)
+ ix := pcdatavalue(f, _PCDATA_InlTreeIndex, pc, nil)
+ if ix >= 0 {
+ name = funcnameFromNameoff(f, inltree[ix].func_)
+ }
+ }
+ if hasPrefix(name, "runtime.") ||
+ hasPrefix(name, "runtime/internal/") ||
+ hasPrefix(name, "reflect.") {
// For now we never async preempt the runtime or
// anything closely tied to the runtime. Known issues
// include: various points in the scheduler ("don't