src/runtime/pprof/pprof_test.go | 35 +++++++++++++++++++++++++++++++++++ src/runtime/sys_linux_arm.s | 6 ++++-- src/runtime/sys_linux_arm64.s | 6 ++++-- src/runtime/sys_linux_mips64x.s | 6 ++++-- src/runtime/sys_linux_ppc64x.s | 8 +++++--- diff --git a/src/runtime/pprof/pprof_test.go b/src/runtime/pprof/pprof_test.go index 0e0cccbc6a6a54f59bf10770453f2d957eac2fab..7bd28fc8bbf20c16965132220bc4077c05dd0fe0 100644 --- a/src/runtime/pprof/pprof_test.go +++ b/src/runtime/pprof/pprof_test.go @@ -1458,3 +1458,38 @@ } }) } } + +func TestTimeVDSO(t *testing.T) { + // Test that time functions have the right stack trace. In particular, + // it shouldn't be recursive. + + if runtime.GOOS == "android" { + // Flaky on Android, issue 48655. VDSO may not be enabled. + testenv.SkipFlaky(t, 48655) + } + + p := testCPUProfile(t, stackContains, []string{"time.now"}, avoidFunctions(), func(dur time.Duration) { + t0 := time.Now() + for { + t := time.Now() + if t.Sub(t0) >= dur { + return + } + } + }) + + // Check for recursive time.now sample. + for _, sample := range p.Sample { + var seenNow bool + for _, loc := range sample.Location { + for _, line := range loc.Line { + if line.Function.Name == "time.now" { + if seenNow { + t.Fatalf("unexpected recursive time.now") + } + seenNow = true + } + } + } + } +} diff --git a/src/runtime/sys_linux_arm.s b/src/runtime/sys_linux_arm.s index 475f52344c7e9b3113af1e4cd0a549aa09b5d35b..5ebff90e7600c6f6f35b7eec19e4759c6066fddd 100644 --- a/src/runtime/sys_linux_arm.s +++ b/src/runtime/sys_linux_arm.s @@ -259,8 +259,9 @@ MOVW m_vdsoSP(R5), R2 MOVW R1, 4(R13) MOVW R2, 8(R13) + MOVW $ret-4(FP), R2 // caller's SP MOVW LR, m_vdsoPC(R5) - MOVW R13, m_vdsoSP(R5) + MOVW R2, m_vdsoSP(R5) MOVW m_curg(R5), R0 @@ -351,8 +352,9 @@ MOVW m_vdsoSP(R5), R2 MOVW R1, 4(R13) MOVW R2, 8(R13) + MOVW $ret-4(FP), R2 // caller's SP MOVW LR, m_vdsoPC(R5) - MOVW R13, m_vdsoSP(R5) + MOVW R2, m_vdsoSP(R5) MOVW m_curg(R5), R0 diff --git a/src/runtime/sys_linux_arm64.s b/src/runtime/sys_linux_arm64.s index 198a5bacefbb70725b1020b1628a8f9bfd1db9a2..27a285090e9561fd1ea57d8ed9abec59e5e4aade 100644 --- a/src/runtime/sys_linux_arm64.s +++ b/src/runtime/sys_linux_arm64.s @@ -221,8 +221,9 @@ MOVD m_vdsoSP(R21), R3 MOVD R2, 8(RSP) MOVD R3, 16(RSP) + MOVD $ret-8(FP), R2 // caller's SP MOVD LR, m_vdsoPC(R21) - MOVD R20, m_vdsoSP(R21) + MOVD R2, m_vdsoSP(R21) MOVD m_curg(R21), R0 CMP g, R0 @@ -304,8 +305,9 @@ MOVD m_vdsoSP(R21), R3 MOVD R2, 8(RSP) MOVD R3, 16(RSP) + MOVD $ret-8(FP), R2 // caller's SP MOVD LR, m_vdsoPC(R21) - MOVD R20, m_vdsoSP(R21) + MOVD R2, m_vdsoSP(R21) MOVD m_curg(R21), R0 CMP g, R0 diff --git a/src/runtime/sys_linux_mips64x.s b/src/runtime/sys_linux_mips64x.s index c3e9f37694578e140cd38c7300b60bdc4b148db0..6450b2896a558ab9e23799aeefe3c90a5efade8b 100644 --- a/src/runtime/sys_linux_mips64x.s +++ b/src/runtime/sys_linux_mips64x.s @@ -228,8 +228,9 @@ MOVV m_vdsoSP(R17), R3 MOVV R2, 8(R29) MOVV R3, 16(R29) + MOVV $ret-8(FP), R2 // caller's SP MOVV R31, m_vdsoPC(R17) - MOVV R29, m_vdsoSP(R17) + MOVV R2, m_vdsoSP(R17) MOVV m_curg(R17), R4 MOVV g, R5 @@ -297,8 +298,9 @@ MOVV m_vdsoSP(R17), R3 MOVV R2, 8(R29) MOVV R3, 16(R29) + MOVV $ret-8(FP), R2 // caller's SP MOVV R31, m_vdsoPC(R17) - MOVV R29, m_vdsoSP(R17) + MOVV R2, m_vdsoSP(R17) MOVV m_curg(R17), R4 MOVV g, R5 diff --git a/src/runtime/sys_linux_ppc64x.s b/src/runtime/sys_linux_ppc64x.s index 7be8c4c7242485df682ae19d99e3b4a4d30834b3..601ce20b7862d3953da041e56341c2fc2c3a7b3a 100644 --- a/src/runtime/sys_linux_ppc64x.s +++ b/src/runtime/sys_linux_ppc64x.s @@ -204,8 +204,9 @@ MOVD R4, 32(R1) MOVD R5, 40(R1) MOVD LR, R14 + MOVD $ret-FIXED_FRAME(FP), R5 // caller's SP MOVD R14, m_vdsoPC(R21) - MOVD R15, m_vdsoSP(R21) + MOVD R5, m_vdsoSP(R21) MOVD m_curg(R21), R6 CMP g, R6 @@ -296,9 +297,10 @@ MOVD m_vdsoSP(R21), R5 MOVD R4, 32(R1) MOVD R5, 40(R1) - MOVD LR, R14 // R14 is unchanged by C code + MOVD LR, R14 // R14 is unchanged by C code + MOVD $ret-FIXED_FRAME(FP), R5 // caller's SP MOVD R14, m_vdsoPC(R21) - MOVD R15, m_vdsoSP(R21) + MOVD R5, m_vdsoSP(R21) MOVD m_curg(R21), R6 CMP g, R6