]> Cypherpunks repositories - gostls13.git/commitdiff
runtime: unwind BP in jmpdefer to match SP unwind
authorAustin Clements <austin@google.com>
Thu, 26 May 2016 00:56:56 +0000 (20:56 -0400)
committerAustin Clements <austin@google.com>
Thu, 26 May 2016 13:54:05 +0000 (13:54 +0000)
The irregular calling convention for defers currently incorrectly
manages the BP if frame pointers are enabled. Specifically, jmpdefer
manipulates the SP as if its own caller, deferreturn, had returned.
However, it does not manipulate the BP to match. As a result, when a
BP-based traceback happens during a deferred function call, it unwinds
to the function that performed the defer and then thinks that function
called itself in an infinite regress.

Fix this by making jmpdefer manipulate the BP as if deferreturn had
actually returned.

Fixes #12968.

Updates #15840.

Change-Id: Ic9cc7c863baeaf977883ed0c25a7e80e592cf066
Reviewed-on: https://go-review.googlesource.com/23457
Reviewed-by: Russ Cox <rsc@golang.org>
Run-TryBot: Austin Clements <austin@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>

src/runtime/asm_amd64.s

index d6e54941805b4a381335b4d7b0deb25871187240..e50c44304441de2ab405ff39c445e2b0232ed365 100644 (file)
@@ -526,6 +526,7 @@ TEXT runtime·jmpdefer(SB), NOSPLIT, $0-16
        MOVQ    fv+0(FP), DX    // fn
        MOVQ    argp+8(FP), BX  // caller sp
        LEAQ    -8(BX), SP      // caller sp after CALL
+       MOVQ    -8(SP), BP      // restore BP as if deferreturn returned (harmless if framepointers not in use)
        SUBQ    $5, (SP)        // return to CALL again
        MOVQ    0(DX), BX
        JMP     BX      // but first run the deferred function