diff --git a/src/runtime/cgocall.go b/src/runtime/cgocall.go index 7f1a02fb4b..c2552cbdf5 100644 --- a/src/runtime/cgocall.go +++ b/src/runtime/cgocall.go @@ -136,7 +136,6 @@ func cgocall(fn, arg unsafe.Pointer) int32 { mp := getg().m mp.ncgocall++ - mp.ncgo++ // Reset traceback. mp.cgoCallers[0] = 0 @@ -165,6 +164,14 @@ func cgocall(fn, arg unsafe.Pointer) int32 { osPreemptExtEnter(mp) mp.incgo = true + // We use ncgo as a check during execution tracing for whether there is + // any C on the call stack, which there will be after this point. If + // there isn't, we can use frame pointer unwinding to collect call + // stacks efficiently. This will be the case for the first Go-to-C call + // on a stack, so it's prefereable to update it here, after we emit a + // trace event in entersyscall above. + mp.ncgo++ + errno := asmcgocall(fn, arg) // Update accounting before exitsyscall because exitsyscall may diff --git a/src/runtime/proc.go b/src/runtime/proc.go index d2901e3aa0..0b9df169b2 100644 --- a/src/runtime/proc.go +++ b/src/runtime/proc.go @@ -868,8 +868,8 @@ func (mp *m) becomeSpinning() { sched.needspinning.Store(0) } -func (mp *m) incgocallback() bool { - return (!mp.incgo && mp.ncgo > 0) || mp.isextra +func (mp *m) hasCgoOnStack() bool { + return mp.ncgo > 0 || mp.isextra } var fastrandseed uintptr diff --git a/src/runtime/trace.go b/src/runtime/trace.go index c382068e2f..79ccebb4b3 100644 --- a/src/runtime/trace.go +++ b/src/runtime/trace.go @@ -889,10 +889,10 @@ func traceStackID(mp *m, pcBuf []uintptr, skip int) uint64 { gp := getg() curgp := mp.curg nstk := 1 - if tracefpunwindoff() || mp.incgocallback() { + if tracefpunwindoff() || mp.hasCgoOnStack() { // Slow path: Unwind using default unwinder. Used when frame pointer // unwinding is unavailable or disabled (tracefpunwindoff), or might - // produce incomplete results or crashes (incgocallback). Note that no + // produce incomplete results or crashes (hasCgoOnStack). Note that no // cgo callback related crashes have been observed yet. The main // motivation is to take advantage of a potentially registered cgo // symbolizer.