]> Cypherpunks repositories - gostls13.git/commitdiff
runtime: fix traceback from goexit1
authorDmitry Vyukov <dvyukov@google.com>
Fri, 20 Feb 2015 17:07:02 +0000 (20:07 +0300)
committerRuss Cox <rsc@golang.org>
Sat, 28 Feb 2015 23:19:57 +0000 (23:19 +0000)
We used to not call traceback from goexit1.
But now tracer does it and crashes on amd64p32:

runtime: unexpected return pc for runtime.getg called from 0x108a4240
goroutine 18 [runnable, locked to thread]:
runtime.traceGoEnd()
    src/runtime/trace.go:758 fp=0x10818fe0 sp=0x10818fdc
runtime.goexit1()
    src/runtime/proc1.go:1540 +0x20 fp=0x10818fe8 sp=0x10818fe0
runtime.getg(0x0)
    src/runtime/asm_386.s:2414 fp=0x10818fec sp=0x10818fe8
created by runtime/pprof_test.TestTraceStress
    src/runtime/pprof/trace_test.go:123 +0x500

Return PC from goexit1 points right after goexit (+0x6).
It happens to work most of the time somehow.

This change fixes traceback from goexit1 by adding an additional NOP to goexit.

Fixes #9931

Change-Id: Ied25240a181b0a2d7bc98127b3ed9068e9a1a13e
Reviewed-on: https://go-review.googlesource.com/5460
Reviewed-by: Russ Cox <rsc@golang.org>
src/runtime/asm_386.s
src/runtime/asm_amd64.s
src/runtime/asm_amd64p32.s
src/runtime/asm_arm.s
src/runtime/asm_ppc64x.s
src/runtime/proc1.go

index f559b0fd5ac31a1edb2d64add9a861c0759f0fba..2b907d6b00827104ca1b567041533e827dc53337 100644 (file)
@@ -2422,6 +2422,8 @@ TEXT _cgo_topofstack(SB),NOSPLIT,$0
 TEXT runtime·goexit(SB),NOSPLIT,$0-0
        BYTE    $0x90   // NOP
        CALL    runtime·goexit1(SB)    // does not return
+       // traceback from goexit1 must hit code range of goexit
+       BYTE    $0x90   // NOP
 
 TEXT runtime·getg(SB),NOSPLIT,$0-4
        get_tls(CX)
index 68bf38464eade2b2103d32395a212e135f87bfdb..139b5059cb6513e1f70b729c10d465fdc1897b4a 100644 (file)
@@ -2457,6 +2457,8 @@ TEXT _cgo_topofstack(SB),NOSPLIT,$0
 TEXT runtime·goexit(SB),NOSPLIT,$0-0
        BYTE    $0x90   // NOP
        CALL    runtime·goexit1(SB)    // does not return
+       // traceback from goexit1 must hit code range of goexit
+       BYTE    $0x90   // NOP
 
 TEXT runtime·getg(SB),NOSPLIT,$0-8
        get_tls(CX)
index a1af9e36c9593430b1295f608f168f6b639d318e..72dd9d7c6db5bc086a298a4a641cbfe55cd089c0 100644 (file)
@@ -1085,6 +1085,8 @@ TEXT runtime·return0(SB), NOSPLIT, $0
 TEXT runtime·goexit(SB),NOSPLIT,$0-0
        BYTE    $0x90   // NOP
        CALL    runtime·goexit1(SB)    // does not return
+       // traceback from goexit1 must hit code range of goexit
+       BYTE    $0x90   // NOP
 
 TEXT runtime·getg(SB),NOSPLIT,$0-4
        get_tls(CX)
index ec85c82b24045d62b52d2c48b24c34d4b831e7e3..21f1d45e8015e311d184c8dcfed91fca0ba82101 100644 (file)
@@ -1338,6 +1338,8 @@ TEXT _cgo_topofstack(SB),NOSPLIT,$8
 TEXT runtime·goexit(SB),NOSPLIT,$-4-0
        MOVW    R0, R0  // NOP
        BL      runtime·goexit1(SB)    // does not return
+       // traceback from goexit1 must hit code range of goexit
+       MOVW    R0, R0  // NOP
 
 TEXT runtime·getg(SB),NOSPLIT,$-4-4
        MOVW    g, ret+0(FP)
index ccb67546313c039a4ff5f040e11754157348eff3..a8adc4c981b1734540a764a284f59d12f3e60c21 100644 (file)
@@ -1241,6 +1241,8 @@ TEXT _cgo_topofstack(SB),NOSPLIT,$-8
 TEXT runtime·goexit(SB),NOSPLIT,$-8-0
        MOVD    R0, R0  // NOP
        BL      runtime·goexit1(SB)    // does not return
+       // traceback from goexit1 must hit code range of goexit
+       MOVD    R0, R0  // NOP
 
 TEXT runtime·getg(SB),NOSPLIT,$-8-8
        MOVD    g, ret+0(FP)
index 17be698c6729d8162a73a980cf4b38ba8c71c539..f3248a53518f20c00c8c5c3e2273f9dd01b897b8 100644 (file)
@@ -1553,8 +1553,6 @@ func gopreempt_m(gp *g) {
 }
 
 // Finishes execution of the current goroutine.
-// Must be NOSPLIT because it is called from Go. (TODO - probably not anymore)
-//go:nosplit
 func goexit1() {
        if raceenabled {
                racegoend()