aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRuss Cox <rsc@golang.org>2010-06-12 10:48:04 -0700
committerRuss Cox <rsc@golang.org>2010-06-12 10:48:04 -0700
commit53a529ab2b8ef0616b5baf5f04e673e046e8e36c (patch)
tree58dd5238630ae1593c33786f4a82563cf053b324
parent9d72aaabda66222cdf630423ec36a6efa2ce4121 (diff)
downloadgo-53a529ab2b8ef0616b5baf5f04e673e046e8e36c.tar.gz
go-53a529ab2b8ef0616b5baf5f04e673e046e8e36c.zip
runtime: fix 386 signal handler bug
Cannot assume that g == m->curg at time of signal. Must save actual g and restore. Fixes flaky crashes with messages like throw: malloc mlookup throw: malloc/free - deadlock throw: unwindstack on self throw: free mlookup (and probably others) when running cgo. R=iant CC=golang-dev https://golang.org/cl/1648043
-rw-r--r--src/pkg/runtime/darwin/386/sys.s12
-rw-r--r--src/pkg/runtime/linux/386/sys.s38
2 files changed, 35 insertions, 15 deletions
diff --git a/src/pkg/runtime/darwin/386/sys.s b/src/pkg/runtime/darwin/386/sys.s
index f88f6b2468..4e0a0b3fd6 100644
--- a/src/pkg/runtime/darwin/386/sys.s
+++ b/src/pkg/runtime/darwin/386/sys.s
@@ -74,8 +74,13 @@ TEXT sigaction(SB),7,$0
// 16(FP) siginfo
// 20(FP) context
TEXT sigtramp(SB),7,$40
- // g = m->gsignal
get_tls(CX)
+
+ // save g
+ MOVL g(CX), BP
+ MOVL BP, 20(SP)
+
+ // g = m->gsignal
MOVL m(CX), BP
MOVL m_gsignal(BP), BP
MOVL BP, g(CX)
@@ -91,10 +96,9 @@ TEXT sigtramp(SB),7,$40
MOVL CX, 8(SP)
CALL DI
- // g = m->curg
+ // restore g
get_tls(CX)
- MOVL m(CX), BP
- MOVL m_curg(BP), BP
+ MOVL 20(SP), BP
MOVL BP, g(CX)
MOVL context+16(FP), CX
diff --git a/src/pkg/runtime/linux/386/sys.s b/src/pkg/runtime/linux/386/sys.s
index ed7c155f1f..57ffc4aa4f 100644
--- a/src/pkg/runtime/linux/386/sys.s
+++ b/src/pkg/runtime/linux/386/sys.s
@@ -56,22 +56,39 @@ TEXT rt_sigaction(SB),7,$0
INT $0x80
RET
-TEXT sigtramp(SB),7,$0
+TEXT sigtramp(SB),7,$40
get_tls(CX)
- MOVL m(CX), BP
- MOVL m_gsignal(BP), AX
- MOVL AX, g(CX)
- JMP sighandler(SB)
+
+ // save g
+ MOVL g(CX), BX
+ MOVL BX, 20(SP)
+
+ // g = m->gsignal
+ MOVL m(CX), BX
+ MOVL m_gsignal(BX), BX
+ MOVL BX, g(CX)
+
+ // copy arguments for call to sighandler
+ MOVL sig+0(FP), BX
+ MOVL BX, 0(SP)
+ MOVL info+4(FP), BX
+ MOVL BX, 4(SP)
+ MOVL context+8(FP), BX
+ MOVL BX, 8(SP)
+
+ CALL sighandler(SB)
+
+ // restore g
+ get_tls(CX)
+ MOVL 20(SP), BX
+ MOVL BX, g(CX)
+
+ RET
TEXT sigignore(SB),7,$0
RET
TEXT sigreturn(SB),7,$0
- // g = m->curg
- get_tls(CX)
- MOVL m(CX), BP
- MOVL m_curg(BP), BP
- MOVL BP, g(CX)
MOVL $173, AX // rt_sigreturn
INT $0x80
INT $3 // not reached
@@ -259,4 +276,3 @@ TEXT setldt(SB),7,$32
MOVW AX, GS
RET
-