diff options
author | Russ Cox <rsc@golang.org> | 2010-06-12 10:48:04 -0700 |
---|---|---|
committer | Russ Cox <rsc@golang.org> | 2010-06-12 10:48:04 -0700 |
commit | 5cc45168f9d5aa01db50aa19ce69e39fc4967541 (patch) | |
tree | 0a11f197f8d573278723e52c5d505bd0ad25017d | |
parent | 66d41569837e7319adbf217ceef43203109ce3f1 (diff) | |
download | golang-5cc45168f9d5aa01db50aa19ce69e39fc4967541.tar.gz |
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
http://codereview.appspot.com/1648043
-rw-r--r-- | src/pkg/runtime/darwin/386/sys.s | 12 | ||||
-rw-r--r-- | src/pkg/runtime/linux/386/sys.s | 38 |
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 f88f6b246..4e0a0b3fd 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 ed7c155f1..57ffc4aa4 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 - |