Skip to content

Commit dcdee15

Browse files
committed
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 <[email protected]> TryBot-Result: Gobot Gobot <[email protected]> Reviewed-by: Austin Clements <[email protected]>
1 parent 87a5467 commit dcdee15

File tree

1 file changed

+11
-3
lines changed

1 file changed

+11
-3
lines changed

src/runtime/preempt.go

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -411,9 +411,17 @@ func isAsyncSafePoint(gp *g, pc, sp, lr uintptr) bool {
411411
// locals pointer map, like empty frame functions?
412412
return false
413413
}
414-
if hasPrefix(funcname(f), "runtime.") ||
415-
hasPrefix(funcname(f), "runtime/internal/") ||
416-
hasPrefix(funcname(f), "reflect.") {
414+
name := funcname(f)
415+
if inldata := funcdata(f, _FUNCDATA_InlTree); inldata != nil {
416+
inltree := (*[1 << 20]inlinedCall)(inldata)
417+
ix := pcdatavalue(f, _PCDATA_InlTreeIndex, pc, nil)
418+
if ix >= 0 {
419+
name = funcnameFromNameoff(f, inltree[ix].func_)
420+
}
421+
}
422+
if hasPrefix(name, "runtime.") ||
423+
hasPrefix(name, "runtime/internal/") ||
424+
hasPrefix(name, "reflect.") {
417425
// For now we never async preempt the runtime or
418426
// anything closely tied to the runtime. Known issues
419427
// include: various points in the scheduler ("don't

0 commit comments

Comments
 (0)