mirror of
https://github.com/golang/go
synced 2024-11-21 17:54:39 -07:00
cgo: fix g0 stack guard
Fixes crash when cgo consumes more than 8K of stack and makes a callback. Fixes #1328. R=golang-dev, rogpeppe, rsc CC=golang-dev, mpimenov https://golang.org/cl/5371042
This commit is contained in:
parent
98321731f2
commit
fbfed49134
@ -8,5 +8,10 @@
|
||||
void
|
||||
callback(void *f)
|
||||
{
|
||||
// use some stack space
|
||||
volatile char data[64*1024];
|
||||
|
||||
data[0] = 0;
|
||||
goCallback(f);
|
||||
data[sizeof(data)-1] = 0;
|
||||
}
|
||||
|
@ -26,12 +26,14 @@ TEXT _rt0_386(SB),7,$0
|
||||
// we set up GS ourselves.
|
||||
MOVL initcgo(SB), AX
|
||||
TESTL AX, AX
|
||||
JZ 4(PC)
|
||||
JZ needtls
|
||||
PUSHL $runtime·g0(SB)
|
||||
CALL AX
|
||||
POPL AX
|
||||
// skip runtime·ldt0setup(SB) and tls test after initcgo for non-windows
|
||||
CMPL runtime·iswindows(SB), $0
|
||||
JEQ ok
|
||||
|
||||
needtls:
|
||||
// skip runtime·ldt0setup(SB) and tls test on Plan 9 in all cases
|
||||
CMPL runtime·isplan9(SB), $1
|
||||
JEQ ok
|
||||
@ -58,9 +60,15 @@ ok:
|
||||
MOVL CX, m_g0(AX)
|
||||
|
||||
// create istack out of the OS stack
|
||||
// if there is an initcgo, it had setup stackguard for us
|
||||
MOVL initcgo(SB), AX
|
||||
TESTL AX, AX
|
||||
JNZ stackok
|
||||
LEAL (-64*1024+104)(SP), AX // TODO: 104?
|
||||
MOVL AX, g_stackguard(CX)
|
||||
stackok:
|
||||
MOVL SP, g_stackbase(CX)
|
||||
|
||||
CALL runtime·emptyfunc(SB) // fault if stack check is wrong
|
||||
|
||||
// convention is D is always cleared
|
||||
|
@ -17,6 +17,7 @@ TEXT _rt0_amd64(SB),7,$-8
|
||||
MOVQ initcgo(SB), AX
|
||||
TESTQ AX, AX
|
||||
JZ needtls
|
||||
LEAQ runtime·g0(SB), DI
|
||||
CALL AX
|
||||
CMPL runtime·iswindows(SB), $0
|
||||
JEQ ok
|
||||
@ -44,8 +45,13 @@ ok:
|
||||
MOVQ CX, m_g0(AX)
|
||||
|
||||
// create istack out of the given (operating system) stack
|
||||
// if there is an initcgo, it had setup stackguard for us
|
||||
MOVQ initcgo(SB), AX
|
||||
TESTQ AX, AX
|
||||
JNZ stackok
|
||||
LEAQ (-8192+104)(SP), AX
|
||||
MOVQ AX, g_stackguard(CX)
|
||||
stackok:
|
||||
MOVQ SP, g_stackbase(CX)
|
||||
|
||||
CLD // convention is D is always left cleared
|
||||
|
@ -100,12 +100,20 @@ inittls(void)
|
||||
}
|
||||
|
||||
static void
|
||||
xinitcgo(void)
|
||||
xinitcgo(G *g)
|
||||
{
|
||||
pthread_attr_t attr;
|
||||
size_t size;
|
||||
|
||||
pthread_attr_init(&attr);
|
||||
pthread_attr_getstacksize(&attr, &size);
|
||||
g->stackguard = (uintptr)&attr - size + 4096;
|
||||
pthread_attr_destroy(&attr);
|
||||
|
||||
inittls();
|
||||
}
|
||||
|
||||
void (*initcgo)(void) = xinitcgo;
|
||||
void (*initcgo)(G*) = xinitcgo;
|
||||
|
||||
void
|
||||
libcgo_sys_thread_start(ThreadStart *ts)
|
||||
|
@ -70,12 +70,20 @@ inittls(void)
|
||||
}
|
||||
|
||||
void
|
||||
xinitcgo(void)
|
||||
xinitcgo(G *g)
|
||||
{
|
||||
pthread_attr_t attr;
|
||||
size_t size;
|
||||
|
||||
pthread_attr_init(&attr);
|
||||
pthread_attr_getstacksize(&attr, &size);
|
||||
g->stackguard = (uintptr)&attr - size + 4096;
|
||||
pthread_attr_destroy(&attr);
|
||||
|
||||
inittls();
|
||||
}
|
||||
|
||||
void (*initcgo) = xinitcgo;
|
||||
void (*initcgo)(G*) = xinitcgo;
|
||||
|
||||
void
|
||||
libcgo_sys_thread_start(ThreadStart *ts)
|
||||
|
@ -8,11 +8,18 @@
|
||||
static void* threadentry(void*);
|
||||
|
||||
static void
|
||||
xinitcgo(void)
|
||||
xinitcgo(G *g)
|
||||
{
|
||||
pthread_attr_t attr;
|
||||
size_t size;
|
||||
|
||||
pthread_attr_init(&attr);
|
||||
pthread_attr_getstacksize(&attr, &size);
|
||||
g->stackguard = (uintptr)&attr - size + 4096;
|
||||
pthread_attr_destroy(&attr);
|
||||
}
|
||||
|
||||
void (*initcgo)(void) = xinitcgo;
|
||||
void (*initcgo)(G*) = xinitcgo;
|
||||
|
||||
void
|
||||
libcgo_sys_thread_start(ThreadStart *ts)
|
||||
|
@ -8,11 +8,18 @@
|
||||
static void* threadentry(void*);
|
||||
|
||||
static void
|
||||
xinitcgo(void)
|
||||
xinitcgo(G *g)
|
||||
{
|
||||
pthread_attr_t attr;
|
||||
size_t size;
|
||||
|
||||
pthread_attr_init(&attr);
|
||||
pthread_attr_getstacksize(&attr, &size);
|
||||
g->stackguard = (uintptr)&attr - size + 4096;
|
||||
pthread_attr_destroy(&attr);
|
||||
}
|
||||
|
||||
void (*initcgo)(void) = xinitcgo;
|
||||
void (*initcgo)(G*) = xinitcgo;
|
||||
|
||||
void
|
||||
libcgo_sys_thread_start(ThreadStart *ts)
|
||||
|
@ -9,11 +9,18 @@
|
||||
static void *threadentry(void*);
|
||||
|
||||
static void
|
||||
xinitcgo(void)
|
||||
xinitcgo(G *g)
|
||||
{
|
||||
pthread_attr_t attr;
|
||||
size_t size;
|
||||
|
||||
pthread_attr_init(&attr);
|
||||
pthread_attr_getstacksize(&attr, &size);
|
||||
g->stackguard = (uintptr)&attr - size + 4096;
|
||||
pthread_attr_destroy(&attr);
|
||||
}
|
||||
|
||||
void (*initcgo) = xinitcgo;
|
||||
void (*initcgo)(G*) = xinitcgo;
|
||||
|
||||
void
|
||||
libcgo_sys_thread_start(ThreadStart *ts)
|
||||
|
@ -3,16 +3,24 @@
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
#include <pthread.h>
|
||||
#include <string.h> // strerror
|
||||
#include "libcgo.h"
|
||||
|
||||
static void* threadentry(void*);
|
||||
|
||||
void
|
||||
xinitcgo(void)
|
||||
xinitcgo(G* g)
|
||||
{
|
||||
pthread_attr_t attr;
|
||||
size_t size;
|
||||
|
||||
pthread_attr_init(&attr);
|
||||
pthread_attr_getstacksize(&attr, &size);
|
||||
g->stackguard = (uintptr)&attr - size + 4096;
|
||||
pthread_attr_destroy(&attr);
|
||||
}
|
||||
|
||||
void (*initcgo)(void) = xinitcgo;
|
||||
void (*initcgo)(G*) = xinitcgo;
|
||||
|
||||
void
|
||||
libcgo_sys_thread_start(ThreadStart *ts)
|
||||
|
@ -5,11 +5,12 @@
|
||||
#include "libcgo.h"
|
||||
|
||||
static void
|
||||
xinitcgo(void)
|
||||
xinitcgo(G *g)
|
||||
{
|
||||
// unimplemented
|
||||
}
|
||||
|
||||
void (*initcgo)(void) = xinitcgo;
|
||||
void (*initcgo)(G*) = xinitcgo;
|
||||
|
||||
void
|
||||
libcgo_sys_thread_start(ThreadStart *ts)
|
||||
|
@ -13,11 +13,13 @@ static void *threadentry(void*);
|
||||
#define STACKSIZE (1*1024*1024)
|
||||
|
||||
static void
|
||||
xinitcgo(void)
|
||||
xinitcgo(G *g)
|
||||
{
|
||||
int tmp;
|
||||
g->stackguard = (uintptr)&tmp - STACKSIZE + 4096;
|
||||
}
|
||||
|
||||
void (*initcgo)(void) = xinitcgo;
|
||||
void (*initcgo)(G*) = xinitcgo;
|
||||
|
||||
void
|
||||
libcgo_sys_thread_start(ThreadStart *ts)
|
||||
|
@ -13,11 +13,13 @@ static void *threadentry(void*);
|
||||
#define STACKSIZE (2*1024*1024)
|
||||
|
||||
static void
|
||||
xinitcgo(void)
|
||||
xinitcgo(G *g)
|
||||
{
|
||||
int tmp;
|
||||
g->stackguard = (uintptr)&tmp - STACKSIZE + 4096;
|
||||
}
|
||||
|
||||
void (*initcgo)(void) = xinitcgo;
|
||||
void (*initcgo)(G*) = xinitcgo;
|
||||
|
||||
void
|
||||
libcgo_sys_thread_start(ThreadStart *ts)
|
||||
|
Loading…
Reference in New Issue
Block a user