runtime: correctly handle signals received on foreign threads
Fixes #3250.
R=rsc
CC=golang-dev
https://golang.org/cl/10757044
diff --git a/src/pkg/runtime/os_darwin.c b/src/pkg/runtime/os_darwin.c
index b28e805..2a34f20 100644
--- a/src/pkg/runtime/os_darwin.c
+++ b/src/pkg/runtime/os_darwin.c
@@ -523,30 +523,6 @@
runtime·sigprocmask(SIG_BLOCK, &sigset_prof, nil);
}
-#pragma dataflag 16 // no pointers
-static int8 badsignal[] = "runtime: signal received on thread not created by Go: ";
-
-// This runs on a foreign stack, without an m or a g. No stack split.
-#pragma textflag 7
-void
-runtime·badsignal(int32 sig)
-{
- int32 len;
-
- if (sig == SIGPROF) {
- return; // Ignore SIGPROFs intended for a non-Go thread.
- }
- runtime·write(2, badsignal, sizeof badsignal - 1);
- if (0 <= sig && sig < NSIG) {
- // Can't call findnull() because it will split stack.
- for(len = 0; runtime·sigtab[sig].name[len]; len++)
- ;
- runtime·write(2, runtime·sigtab[sig].name, len);
- }
- runtime·write(2, "\n", 1);
- runtime·exit(1);
-}
-
void
runtime·setsig(int32 i, GoSighandler *fn, bool restart)
{
diff --git a/src/pkg/runtime/os_freebsd.c b/src/pkg/runtime/os_freebsd.c
index efe82ca..c513c0a 100644
--- a/src/pkg/runtime/os_freebsd.c
+++ b/src/pkg/runtime/os_freebsd.c
@@ -235,30 +235,6 @@
USED(on);
}
-#pragma dataflag 16 // no pointers
-static int8 badsignal[] = "runtime: signal received on thread not created by Go: ";
-
-// This runs on a foreign stack, without an m or a g. No stack split.
-#pragma textflag 7
-void
-runtime·badsignal(int32 sig)
-{
- int32 len;
-
- if (sig == SIGPROF) {
- return; // Ignore SIGPROFs intended for a non-Go thread.
- }
- runtime·write(2, badsignal, sizeof badsignal - 1);
- if (0 <= sig && sig < NSIG) {
- // Can't call findnull() because it will split stack.
- for(len = 0; runtime·sigtab[sig].name[len]; len++)
- ;
- runtime·write(2, runtime·sigtab[sig].name, len);
- }
- runtime·write(2, "\n", 1);
- runtime·exit(1);
-}
-
extern void runtime·sigtramp(void);
typedef struct sigaction {
diff --git a/src/pkg/runtime/os_linux.c b/src/pkg/runtime/os_linux.c
index 2ae33af..b27239d 100644
--- a/src/pkg/runtime/os_linux.c
+++ b/src/pkg/runtime/os_linux.c
@@ -284,30 +284,6 @@
USED(on);
}
-#pragma dataflag 16 // no pointers
-static int8 badsignal[] = "runtime: signal received on thread not created by Go: ";
-
-// This runs on a foreign stack, without an m or a g. No stack split.
-#pragma textflag 7
-void
-runtime·badsignal(int32 sig)
-{
- int32 len;
-
- if (sig == SIGPROF) {
- return; // Ignore SIGPROFs intended for a non-Go thread.
- }
- runtime·write(2, badsignal, sizeof badsignal - 1);
- if (0 <= sig && sig < NSIG) {
- // Can't call findnull() because it will split stack.
- for(len = 0; runtime·sigtab[sig].name[len]; len++)
- ;
- runtime·write(2, runtime·sigtab[sig].name, len);
- }
- runtime·write(2, "\n", 1);
- runtime·exit(1);
-}
-
#ifdef GOARCH_386
#define sa_handler k_sa_handler
#endif
diff --git a/src/pkg/runtime/os_netbsd.c b/src/pkg/runtime/os_netbsd.c
index 56ff188..f53855c 100644
--- a/src/pkg/runtime/os_netbsd.c
+++ b/src/pkg/runtime/os_netbsd.c
@@ -275,30 +275,6 @@
USED(on);
}
-#pragma dataflag 16 // no pointers
-static int8 badsignal[] = "runtime: signal received on thread not created by Go: ";
-
-// This runs on a foreign stack, without an m or a g. No stack split.
-#pragma textflag 7
-void
-runtime·badsignal(int32 sig)
-{
- int32 len;
-
- if (sig == SIGPROF) {
- return; // Ignore SIGPROFs intended for a non-Go thread.
- }
- runtime·write(2, badsignal, sizeof badsignal - 1);
- if (0 <= sig && sig < NSIG) {
- // Can't call findnull() because it will split stack.
- for(len = 0; runtime·sigtab[sig].name[len]; len++)
- ;
- runtime·write(2, runtime·sigtab[sig].name, len);
- }
- runtime·write(2, "\n", 1);
- runtime·exit(1);
-}
-
extern void runtime·sigtramp(void);
typedef struct sigaction {
diff --git a/src/pkg/runtime/os_openbsd.c b/src/pkg/runtime/os_openbsd.c
index 8c62886..4c196e8 100644
--- a/src/pkg/runtime/os_openbsd.c
+++ b/src/pkg/runtime/os_openbsd.c
@@ -257,30 +257,6 @@
USED(on);
}
-#pragma dataflag 16 // no pointers
-static int8 badsignal[] = "runtime: signal received on thread not created by Go: ";
-
-// This runs on a foreign stack, without an m or a g. No stack split.
-#pragma textflag 7
-void
-runtime·badsignal(int32 sig)
-{
- int32 len;
-
- if (sig == SIGPROF) {
- return; // Ignore SIGPROFs intended for a non-Go thread.
- }
- runtime·write(2, badsignal, sizeof badsignal - 1);
- if (0 <= sig && sig < NSIG) {
- // Can't call findnull() because it will split stack.
- for(len = 0; runtime·sigtab[sig].name[len]; len++)
- ;
- runtime·write(2, runtime·sigtab[sig].name, len);
- }
- runtime·write(2, "\n", 1);
- runtime·exit(1);
-}
-
extern void runtime·sigtramp(void);
typedef struct sigaction {
diff --git a/src/pkg/runtime/os_plan9.c b/src/pkg/runtime/os_plan9.c
index 0991f81..d64c463 100644
--- a/src/pkg/runtime/os_plan9.c
+++ b/src/pkg/runtime/os_plan9.c
@@ -336,7 +336,7 @@
// This runs on a foreign stack, without an m or a g. No stack split.
#pragma textflag 7
void
-runtime·badsignal(void)
+runtime·badsignal2(void)
{
runtime·pwrite(2, badsignal, sizeof badsignal - 1, -1LL);
runtime·exits(badsignal);
diff --git a/src/pkg/runtime/sigqueue.goc b/src/pkg/runtime/sigqueue.goc
index 7e08368..9bfab3b 100644
--- a/src/pkg/runtime/sigqueue.goc
+++ b/src/pkg/runtime/sigqueue.goc
@@ -28,6 +28,7 @@
#include "runtime.h"
#include "defs_GOOS_GOARCH.h"
#include "os_GOOS.h"
+#include "cgocall.h"
static struct {
Note;
@@ -155,3 +156,11 @@
sig.wanted[s/32] &= ~(1U<<(s&31));
runtime·sigdisable(s);
}
+
+// This runs on a foreign stack, without an m or a g. No stack split.
+#pragma textflag 7
+void
+runtime·badsignal(uintptr sig)
+{
+ runtime·cgocallback((void (*)(void))runtime·sigsend, &sig, sizeof(sig));
+}
diff --git a/src/pkg/runtime/sys_darwin_386.s b/src/pkg/runtime/sys_darwin_386.s
index 59bb9d8..a1a7aaf 100644
--- a/src/pkg/runtime/sys_darwin_386.s
+++ b/src/pkg/runtime/sys_darwin_386.s
@@ -238,11 +238,12 @@
// check that m exists
MOVL m(CX), BP
CMPL BP, $0
- JNE 5(PC)
+ JNE 6(PC)
MOVL sig+8(FP), BX
MOVL BX, 0(SP)
- CALL runtime·badsignal(SB)
- RET
+ MOVL $runtime·badsignal(SB), AX
+ CALL AX
+ JMP sigtramp_ret
// save g
MOVL g(CX), DI
@@ -269,6 +270,7 @@
MOVL 20(SP), DI
MOVL DI, g(CX)
+sigtramp_ret:
// call sigreturn
MOVL context+16(FP), CX
MOVL style+4(FP), BX
diff --git a/src/pkg/runtime/sys_darwin_amd64.s b/src/pkg/runtime/sys_darwin_amd64.s
index b324a04..a11cc33 100644
--- a/src/pkg/runtime/sys_darwin_amd64.s
+++ b/src/pkg/runtime/sys_darwin_amd64.s
@@ -192,13 +192,17 @@
TEXT runtime·sigtramp(SB),7,$64
get_tls(BX)
+ MOVQ R8, 32(SP) // save ucontext
+ MOVQ SI, 40(SP) // save infostyle
+
// check that m exists
MOVQ m(BX), BP
CMPQ BP, $0
- JNE 4(PC)
+ JNE 5(PC)
MOVL DX, 0(SP)
- CALL runtime·badsignal(SB)
- RET
+ MOVQ $runtime·badsignal(SB), AX
+ CALL AX
+ JMP sigtramp_ret
// save g
MOVQ g(BX), R10
@@ -213,8 +217,6 @@
MOVQ R8, 16(SP)
MOVQ R10, 24(SP)
- MOVQ R8, 32(SP) // save ucontext
- MOVQ SI, 40(SP) // save infostyle
CALL DI
// restore g
@@ -222,6 +224,7 @@
MOVQ 48(SP), R10
MOVQ R10, g(BX)
+sigtramp_ret:
// call sigreturn
MOVL $(0x2000000+184), AX // sigreturn(ucontext, infostyle)
MOVQ 32(SP), DI // saved ucontext
diff --git a/src/pkg/runtime/sys_freebsd_386.s b/src/pkg/runtime/sys_freebsd_386.s
index bbfb3e3..2a57cb4 100644
--- a/src/pkg/runtime/sys_freebsd_386.s
+++ b/src/pkg/runtime/sys_freebsd_386.s
@@ -183,11 +183,12 @@
// check that m exists
MOVL m(CX), BX
CMPL BX, $0
- JNE 5(PC)
+ JNE 6(PC)
MOVL signo+0(FP), BX
MOVL BX, 0(SP)
- CALL runtime·badsignal(SB)
- RET
+ MOVL $runtime·badsignal(SB), AX
+ CALL AX
+ JMP sigtramp_ret
// save g
MOVL g(CX), DI
@@ -212,7 +213,8 @@
get_tls(CX)
MOVL 20(SP), BX
MOVL BX, g(CX)
-
+
+sigtramp_ret:
// call sigreturn
MOVL context+8(FP), AX
MOVL $0, 0(SP) // syscall gap
diff --git a/src/pkg/runtime/sys_freebsd_amd64.s b/src/pkg/runtime/sys_freebsd_amd64.s
index 9638acb..50d91c3 100644
--- a/src/pkg/runtime/sys_freebsd_amd64.s
+++ b/src/pkg/runtime/sys_freebsd_amd64.s
@@ -155,13 +155,14 @@
TEXT runtime·sigtramp(SB),7,$64
get_tls(BX)
-
+
// check that m exists
MOVQ m(BX), BP
CMPQ BP, $0
- JNE 4(PC)
+ JNE 5(PC)
MOVQ DI, 0(SP)
- CALL runtime·badsignal(SB)
+ MOVQ $runtime·badsignal(SB), AX
+ CALL AX
RET
// save g
@@ -176,7 +177,7 @@
MOVQ SI, 8(SP)
MOVQ DX, 16(SP)
MOVQ R10, 24(SP)
-
+
CALL runtime·sighandler(SB)
// restore g
diff --git a/src/pkg/runtime/sys_freebsd_arm.s b/src/pkg/runtime/sys_freebsd_arm.s
index 7aba498..8260940 100644
--- a/src/pkg/runtime/sys_freebsd_arm.s
+++ b/src/pkg/runtime/sys_freebsd_arm.s
@@ -158,9 +158,10 @@
BL.NE (R0)
CMP $0, m
- BNE 3(PC)
+ BNE 4(PC)
// signal number is already prepared in 4(R13)
- BL runtime·badsignal(SB)
+ MOVW $runtime·badsignal(SB), R11
+ BL (R11)
RET
// save g
diff --git a/src/pkg/runtime/sys_linux_386.s b/src/pkg/runtime/sys_linux_386.s
index 76ebe3d..7d677ac 100644
--- a/src/pkg/runtime/sys_linux_386.s
+++ b/src/pkg/runtime/sys_linux_386.s
@@ -168,10 +168,11 @@
// check that m exists
MOVL m(CX), BX
CMPL BX, $0
- JNE 5(PC)
+ JNE 6(PC)
MOVL sig+0(FP), BX
MOVL BX, 0(SP)
- CALL runtime·badsignal(SB)
+ MOVL $runtime·badsignal(SB), AX
+ CALL AX
RET
// save g
diff --git a/src/pkg/runtime/sys_linux_amd64.s b/src/pkg/runtime/sys_linux_amd64.s
index 2d802ab..649f205 100644
--- a/src/pkg/runtime/sys_linux_amd64.s
+++ b/src/pkg/runtime/sys_linux_amd64.s
@@ -186,9 +186,10 @@
// check that m exists
MOVQ m(BX), BP
CMPQ BP, $0
- JNE 4(PC)
+ JNE 5(PC)
MOVQ DI, 0(SP)
- CALL runtime·badsignal(SB)
+ MOVQ $runtime·badsignal(SB), AX
+ CALL AX
RET
// save g
diff --git a/src/pkg/runtime/sys_linux_arm.s b/src/pkg/runtime/sys_linux_arm.s
index 6826bea..4927332 100644
--- a/src/pkg/runtime/sys_linux_arm.s
+++ b/src/pkg/runtime/sys_linux_arm.s
@@ -292,9 +292,10 @@
BL.NE (R0)
CMP $0, m
- BNE 3(PC)
+ BNE 4(PC)
// signal number is already prepared in 4(R13)
- BL runtime·badsignal(SB)
+ MOVW $runtime·badsignal(SB), R11
+ BL (R11)
RET
// save g
diff --git a/src/pkg/runtime/sys_netbsd_386.s b/src/pkg/runtime/sys_netbsd_386.s
index 992eba7..19b3a52 100644
--- a/src/pkg/runtime/sys_netbsd_386.s
+++ b/src/pkg/runtime/sys_netbsd_386.s
@@ -196,10 +196,11 @@
// check that m exists
MOVL m(CX), BX
CMPL BX, $0
- JNE 5(PC)
+ JNE 6(PC)
MOVL signo+0(FP), BX
MOVL BX, 0(SP)
- CALL runtime·badsignal(SB)
+ MOVL $runtime·badsignal(SB), AX
+ CALL AX
RET
// save g
diff --git a/src/pkg/runtime/sys_netbsd_amd64.s b/src/pkg/runtime/sys_netbsd_amd64.s
index 574d8a9..10b06c8 100644
--- a/src/pkg/runtime/sys_netbsd_amd64.s
+++ b/src/pkg/runtime/sys_netbsd_amd64.s
@@ -215,9 +215,10 @@
// check that m exists
MOVQ m(BX), BP
CMPQ BP, $0
- JNE 4(PC)
+ JNE 5(PC)
MOVQ DI, 0(SP)
- CALL runtime·badsignal(SB)
+ MOVQ $runtime·badsignal(SB), AX
+ CALL AX
RET
// save g
diff --git a/src/pkg/runtime/sys_netbsd_arm.s b/src/pkg/runtime/sys_netbsd_arm.s
index 0109ad8..d39b648 100644
--- a/src/pkg/runtime/sys_netbsd_arm.s
+++ b/src/pkg/runtime/sys_netbsd_arm.s
@@ -207,9 +207,10 @@
BL.NE (R0)
CMP $0, m
- BNE 3(PC)
+ BNE 4(PC)
// signal number is already prepared in 4(R13)
- BL runtime·badsignal(SB)
+ MOVW $runtime·badsignal(SB), R11
+ BL (R11)
RET
// save g
diff --git a/src/pkg/runtime/sys_openbsd_386.s b/src/pkg/runtime/sys_openbsd_386.s
index f154464..3ca4511 100644
--- a/src/pkg/runtime/sys_openbsd_386.s
+++ b/src/pkg/runtime/sys_openbsd_386.s
@@ -170,11 +170,12 @@
// check that m exists
MOVL m(CX), BX
CMPL BX, $0
- JNE 5(PC)
+ JNE 6(PC)
MOVL signo+0(FP), BX
MOVL BX, 0(SP)
- CALL runtime·badsignal(SB)
- RET
+ MOVL $runtime·badsignal(SB), AX
+ CALL AX
+ JMP sigtramp_ret
// save g
MOVL g(CX), DI
@@ -199,7 +200,8 @@
get_tls(CX)
MOVL 20(SP), BX
MOVL BX, g(CX)
-
+
+sigtramp_ret:
// call sigreturn
MOVL context+8(FP), AX
MOVL $0, 0(SP) // syscall gap
diff --git a/src/pkg/runtime/sys_openbsd_amd64.s b/src/pkg/runtime/sys_openbsd_amd64.s
index 04c5719..3cbf0d9 100644
--- a/src/pkg/runtime/sys_openbsd_amd64.s
+++ b/src/pkg/runtime/sys_openbsd_amd64.s
@@ -204,9 +204,10 @@
// check that m exists
MOVQ m(BX), BP
CMPQ BP, $0
- JNE 4(PC)
+ JNE 5(PC)
MOVQ DI, 0(SP)
- CALL runtime·badsignal(SB)
+ MOVQ $runtime·badsignal(SB), AX
+ CALL AX
RET
// save g
diff --git a/src/pkg/runtime/sys_plan9_386.s b/src/pkg/runtime/sys_plan9_386.s
index 1f860a9..e8fd836 100644
--- a/src/pkg/runtime/sys_plan9_386.s
+++ b/src/pkg/runtime/sys_plan9_386.s
@@ -127,7 +127,7 @@
MOVL m(AX), BX
CMPL BX, $0
JNE 3(PC)
- CALL runtime·badsignal(SB) // will exit
+ CALL runtime·badsignal2(SB) // will exit
RET
// save args
diff --git a/src/pkg/runtime/sys_plan9_amd64.s b/src/pkg/runtime/sys_plan9_amd64.s
index c0c896e..140c5e4 100644
--- a/src/pkg/runtime/sys_plan9_amd64.s
+++ b/src/pkg/runtime/sys_plan9_amd64.s
@@ -159,7 +159,7 @@
MOVQ m(AX), BX
CMPQ BX, $0
JNE 3(PC)
- CALL runtime·badsignal(SB) // will exit
+ CALL runtime·badsignal2(SB) // will exit
RET
// save args