From 201cfe4afb657fec7bc9535ff0e2312be762c2ca Mon Sep 17 00:00:00 2001 From: Russ Cox Date: Mon, 8 Sep 2014 16:56:46 -0400 Subject: runtime: run sighandler on g0 stack on windows The sighander has been run at the bottom of the currently executing goroutine stack, but it's in C, and we don't want C on our ordinary goroutine stacks. Worse, it does a lot of stuff, and it might need more stack space. There is scary code in traceback_windows.go that talks about stack splits during sighandler. Moving sighandler to g0 will eliminate the possibility of stack splits and such, and then we can delete traceback_windows.go entirely. Win win. On the builder, all.bat passes with GOARCH=amd64 and all.bat gets most of the way with GOARCH=386 except for a DLL-loading test that I think is unrelated. Fixes windows build. TBR=brainman, iant CC=golang-codereviews https://golang.org/cl/140380043 --- src/runtime/sys_windows_amd64.s | 47 +++++++++++++++++++++++++++++++++++------ 1 file changed, 41 insertions(+), 6 deletions(-) (limited to 'src/runtime/sys_windows_amd64.s') diff --git a/src/runtime/sys_windows_amd64.s b/src/runtime/sys_windows_amd64.s index 21f73daf09..3d63a04de9 100644 --- a/src/runtime/sys_windows_amd64.s +++ b/src/runtime/sys_windows_amd64.s @@ -106,7 +106,7 @@ TEXT runtime·sigtramp(SB),NOSPLIT,$0-0 // DI SI BP BX R12 R13 R14 R15 registers and DF flag are preserved // as required by windows callback convention. PUSHFQ - SUBQ $96, SP + SUBQ $112, SP MOVQ DI, 80(SP) MOVQ SI, 72(SP) MOVQ BP, 64(SP) @@ -116,10 +116,7 @@ TEXT runtime·sigtramp(SB),NOSPLIT,$0-0 MOVQ R14, 32(SP) MOVQ R15, 88(SP) - MOVQ 0(CX), BX // ExceptionRecord* - MOVQ 8(CX), CX // Context* - - // fetch g + // find g get_tls(DX) CMPQ DX, $0 JNE 3(PC) @@ -129,6 +126,37 @@ TEXT runtime·sigtramp(SB),NOSPLIT,$0-0 CMPQ DX, $0 JNE 2(PC) CALL runtime·badsignal2(SB) + + // save g and SP in case of stack switch + MOVQ DX, 96(SP) // g + MOVQ SP, 104(SP) + + // do we need to switch to the g0 stack? + MOVQ g_m(DX), BX + MOVQ m_g0(BX), BX + CMPQ DX, BX + JEQ sigtramp_g0 + + // switch to g0 stack + get_tls(BP) + MOVQ BX, g(BP) + MOVQ (g_sched+gobuf_sp)(BX), DI + // make it look like mstart called us on g0, to stop traceback + SUBQ $8, DI + MOVQ $runtime·mstart(SB), SI + MOVQ SI, 0(DI) + // traceback will think that we've done PUSHFQ and SUBQ + // on this stack, so subtract them here to match. + // (we need room for sighandler arguments anyway). + // and re-save old SP for restoring later. + SUBQ $(112+8), DI + // save g, save old stack pointer. + MOVQ SP, 104(DI) + MOVQ DI, SP + +sigtramp_g0: + MOVQ 0(CX), BX // ExceptionRecord* + MOVQ 8(CX), CX // Context* // call sighandler(ExceptionRecord*, Context*, G*) MOVQ BX, 0(SP) MOVQ CX, 8(SP) @@ -137,6 +165,13 @@ TEXT runtime·sigtramp(SB),NOSPLIT,$0-0 // AX is set to report result back to Windows MOVL 24(SP), AX + // switch back to original stack and g + // no-op if we never left. + MOVQ 104(SP), SP + MOVQ 96(SP), DX + get_tls(BP) + MOVQ DX, g(BP) + done: // restore registers as required for windows callback MOVQ 88(SP), R15 @@ -147,7 +182,7 @@ done: MOVQ 64(SP), BP MOVQ 72(SP), SI MOVQ 80(SP), DI - ADDQ $96, SP + ADDQ $112, SP POPFQ RET -- cgit v1.3