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 7c71d8263be8b8e7799ea856f65f0dcbdef1dcce..4d37cdb53c30dce8cc13e6e76d6cb42cfe17c27a 100644 --- a/src/runtime/pprof/pprof_test.go +++ b/src/runtime/pprof/pprof_test.go @@ -1543,3 +1543,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 02a5d4a6427402cdc0981364caf157bcd82d77a0..ae99810c10299705add3163ef7e9836139a1d7f2 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 69ac16027800f3df0e61100b3278ee6357ed9f82..9289ad5028b403a3be8c664512c9eac855a4193c 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 e18d29144563fed07dfecfcb859c5f1257de0782..7529a0ed27db35e9d8489ce6f1cccfd5ecfa5538 100644 --- a/src/runtime/sys_linux_mips64x.s +++ b/src/runtime/sys_linux_mips64x.s @@ -229,8 +229,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 @@ -298,8 +299,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 005fa4d2b4d002acfb2a946ff72b2369580ae08a..33b6a9409c2c5b51eaf8ee0c12fcde74b8819d90 100644 --- a/src/runtime/sys_linux_ppc64x.s +++ b/src/runtime/sys_linux_ppc64x.s @@ -205,8 +205,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 @@ -297,9 +298,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