mirror of
https://github.com/golang/go
synced 2024-11-25 12:27:57 -07:00
cgo, runtime: diagnose callback on non-Go thread
Before: $ go run x.go signal 11 (core dumped) $ After: $ go run x.go runtime: cgo callback on thread not created by Go. signal 11 (core dumped) $ For issue 3068. Not a fix, but as much of a fix as we can do before Go 1. R=golang-dev, rogpeppe, gri CC=golang-dev https://golang.org/cl/5781047
This commit is contained in:
parent
9b7b574edc
commit
9b73238daa
@ -573,8 +573,9 @@ func (p *Package) writeExports(fgo2, fc, fm *os.File) {
|
|||||||
goname = "_cgoexpwrap" + cPrefix + "_" + fn.Recv.List[0].Names[0].Name + "_" + goname
|
goname = "_cgoexpwrap" + cPrefix + "_" + fn.Recv.List[0].Names[0].Name + "_" + goname
|
||||||
}
|
}
|
||||||
fmt.Fprintf(fc, "#pragma dynexport %s %s\n", goname, goname)
|
fmt.Fprintf(fc, "#pragma dynexport %s %s\n", goname, goname)
|
||||||
fmt.Fprintf(fc, "extern void ·%s();\n", goname)
|
fmt.Fprintf(fc, "extern void ·%s();\n\n", goname)
|
||||||
fmt.Fprintf(fc, "\nvoid\n")
|
fmt.Fprintf(fc, "#pragma textflag 7\n") // no split stack, so no use of m or g
|
||||||
|
fmt.Fprintf(fc, "void\n")
|
||||||
fmt.Fprintf(fc, "_cgoexp%s_%s(void *a, int32 n)\n", cPrefix, exp.ExpName)
|
fmt.Fprintf(fc, "_cgoexp%s_%s(void *a, int32 n)\n", cPrefix, exp.ExpName)
|
||||||
fmt.Fprintf(fc, "{\n")
|
fmt.Fprintf(fc, "{\n")
|
||||||
fmt.Fprintf(fc, "\truntime·cgocallback(·%s, a, n);\n", goname)
|
fmt.Fprintf(fc, "\truntime·cgocallback(·%s, a, n);\n", goname)
|
||||||
|
@ -425,6 +425,14 @@ TEXT runtime·cgocallback(SB),7,$12
|
|||||||
// Save current m->g0->sched.sp on stack and then set it to SP.
|
// Save current m->g0->sched.sp on stack and then set it to SP.
|
||||||
get_tls(CX)
|
get_tls(CX)
|
||||||
MOVL m(CX), BP
|
MOVL m(CX), BP
|
||||||
|
|
||||||
|
// If m is nil, it is almost certainly because we have been called
|
||||||
|
// on a thread that Go did not create. We're going to crash as
|
||||||
|
// soon as we try to use m; instead, try to print a nice error and exit.
|
||||||
|
CMPL BP, $0
|
||||||
|
JNE 2(PC)
|
||||||
|
CALL runtime·badcallback(SB)
|
||||||
|
|
||||||
MOVL m_g0(BP), SI
|
MOVL m_g0(BP), SI
|
||||||
PUSHL (g_sched+gobuf_sp)(SI)
|
PUSHL (g_sched+gobuf_sp)(SI)
|
||||||
MOVL SP, (g_sched+gobuf_sp)(SI)
|
MOVL SP, (g_sched+gobuf_sp)(SI)
|
||||||
|
@ -471,6 +471,14 @@ TEXT runtime·cgocallback(SB),7,$24
|
|||||||
// Save current m->g0->sched.sp on stack and then set it to SP.
|
// Save current m->g0->sched.sp on stack and then set it to SP.
|
||||||
get_tls(CX)
|
get_tls(CX)
|
||||||
MOVQ m(CX), BP
|
MOVQ m(CX), BP
|
||||||
|
|
||||||
|
// If m is nil, it is almost certainly because we have been called
|
||||||
|
// on a thread that Go did not create. We're going to crash as
|
||||||
|
// soon as we try to use m; instead, try to print a nice error and exit.
|
||||||
|
CMPQ BP, $0
|
||||||
|
JNE 2(PC)
|
||||||
|
CALL runtime·badcallback(SB)
|
||||||
|
|
||||||
MOVQ m_g0(BP), SI
|
MOVQ m_g0(BP), SI
|
||||||
PUSHQ (g_sched+gobuf_sp)(SI)
|
PUSHQ (g_sched+gobuf_sp)(SI)
|
||||||
MOVQ SP, (g_sched+gobuf_sp)(SI)
|
MOVQ SP, (g_sched+gobuf_sp)(SI)
|
||||||
|
@ -477,3 +477,13 @@ runtime·setprof(bool on)
|
|||||||
else
|
else
|
||||||
runtime·sigprocmask(SIG_BLOCK, &sigset_prof, nil);
|
runtime·sigprocmask(SIG_BLOCK, &sigset_prof, nil);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int8 badcallback[] = "runtime: cgo callback on thread not created by Go.\n";
|
||||||
|
|
||||||
|
// This runs on a foreign stack, without an m or a g. No stack split.
|
||||||
|
#pragma textflag 7
|
||||||
|
void
|
||||||
|
runtime·badcallback(void)
|
||||||
|
{
|
||||||
|
runtime·write(2, badcallback, sizeof badcallback - 1);
|
||||||
|
}
|
||||||
|
@ -195,3 +195,13 @@ runtime·setprof(bool on)
|
|||||||
{
|
{
|
||||||
USED(on);
|
USED(on);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int8 badcallback[] = "runtime: cgo callback on thread not created by Go.\n";
|
||||||
|
|
||||||
|
// This runs on a foreign stack, without an m or a g. No stack split.
|
||||||
|
#pragma textflag 7
|
||||||
|
void
|
||||||
|
runtime·badcallback(void)
|
||||||
|
{
|
||||||
|
runtime·write(2, badcallback, sizeof badcallback - 1);
|
||||||
|
}
|
||||||
|
@ -255,3 +255,13 @@ runtime·setprof(bool on)
|
|||||||
{
|
{
|
||||||
USED(on);
|
USED(on);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int8 badcallback[] = "runtime: cgo callback on thread not created by Go.\n";
|
||||||
|
|
||||||
|
// This runs on a foreign stack, without an m or a g. No stack split.
|
||||||
|
#pragma textflag 7
|
||||||
|
void
|
||||||
|
runtime·badcallback(void)
|
||||||
|
{
|
||||||
|
runtime·write(2, badcallback, sizeof badcallback - 1);
|
||||||
|
}
|
||||||
|
@ -213,3 +213,13 @@ runtime·setprof(bool on)
|
|||||||
{
|
{
|
||||||
USED(on);
|
USED(on);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int8 badcallback[] = "runtime: cgo callback on thread not created by Go.\n";
|
||||||
|
|
||||||
|
// This runs on a foreign stack, without an m or a g. No stack split.
|
||||||
|
#pragma textflag 7
|
||||||
|
void
|
||||||
|
runtime·badcallback(void)
|
||||||
|
{
|
||||||
|
runtime·write(2, badcallback, sizeof badcallback - 1);
|
||||||
|
}
|
||||||
|
@ -213,3 +213,13 @@ runtime·setprof(bool on)
|
|||||||
{
|
{
|
||||||
USED(on);
|
USED(on);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int8 badcallback[] = "runtime: cgo callback on thread not created by Go.\n";
|
||||||
|
|
||||||
|
// This runs on a foreign stack, without an m or a g. No stack split.
|
||||||
|
#pragma textflag 7
|
||||||
|
void
|
||||||
|
runtime·badcallback(void)
|
||||||
|
{
|
||||||
|
runtime·write(2, badcallback, sizeof badcallback - 1);
|
||||||
|
}
|
||||||
|
@ -247,3 +247,13 @@ runtime·setprof(bool on)
|
|||||||
{
|
{
|
||||||
USED(on);
|
USED(on);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int8 badcallback[] = "runtime: cgo callback on thread not created by Go.\n";
|
||||||
|
|
||||||
|
// This runs on a foreign stack, without an m or a g. No stack split.
|
||||||
|
#pragma textflag 7
|
||||||
|
void
|
||||||
|
runtime·badcallback(void)
|
||||||
|
{
|
||||||
|
runtime·pwrite(2, badcallback, sizeof badcallback - 1, -1LL);
|
||||||
|
}
|
||||||
|
@ -422,3 +422,22 @@ runtime·setprof(bool on)
|
|||||||
{
|
{
|
||||||
USED(on);
|
USED(on);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int8 badcallback[] = "runtime: cgo callback on thread not created by Go.\n";
|
||||||
|
|
||||||
|
// This runs on a foreign stack, without an m or a g. No stack split.
|
||||||
|
#pragma textflag 7
|
||||||
|
void
|
||||||
|
runtime·badcallback(void)
|
||||||
|
{
|
||||||
|
uint32 written;
|
||||||
|
|
||||||
|
runtime·stdcall(
|
||||||
|
runtime·WriteFile, 5,
|
||||||
|
runtime·stdcall(runtime·GetStdHandle, 1, (uintptr)-12), // stderr
|
||||||
|
badcallback,
|
||||||
|
(uintptr)(sizeof badcallback - 1),
|
||||||
|
&written,
|
||||||
|
nil
|
||||||
|
);
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user