1
0
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:
Dmitriy Vyukov 2011-11-09 23:11:48 +03:00
parent 98321731f2
commit fbfed49134
12 changed files with 89 additions and 20 deletions

View File

@ -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;
}

View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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)