mirror of
https://github.com/golang/go
synced 2024-11-23 07:00:05 -07:00
runtime/cgo: use frame address to set g0 stack bound
This extends CL 419434 to all Unix targets. Rather than repeating the code, pull all the similar code into a single function. CL 419434 description: For a cgo binary, at startup we set g0's stack bounds using the address of a local variable (&size) in a C function x_cgo_init and the stack size from pthread_attr_getstacksize. Normally, &size is an address within the current stack frame. However, when it is compiled with ASAN, it may be instrumented to __asan_stack_malloc_0 and the address may not live in the current stack frame, causing the stack bound to be set incorrectly, e.g. lo > hi. Using __builtin_frame_address(0) to get the stack address instead. Change-Id: I914a09d32c66a79515b6f700be18c690f3c0c77b Reviewed-on: https://go-review.googlesource.com/c/go/+/517335 Reviewed-by: Russ Cox <rsc@golang.org> Reviewed-by: Ian Lance Taylor <iant@google.com> TryBot-Result: Gopher Robot <gobot@golang.org> Run-TryBot: Ian Lance Taylor <iant@google.com> Run-TryBot: Ian Lance Taylor <iant@golang.org> Auto-Submit: Ian Lance Taylor <iant@google.com>
This commit is contained in:
parent
2d5ce9b729
commit
a3ced4a633
@ -14,12 +14,8 @@ static void (*setg_gcc)(void*);
|
||||
void
|
||||
x_cgo_init(G *g, void (*setg)(void*), void **tlsg, void **tlsbase)
|
||||
{
|
||||
size_t size;
|
||||
|
||||
setg_gcc = setg;
|
||||
|
||||
size = pthread_get_stacksize_np(pthread_self());
|
||||
g->stacklo = (uintptr)&size - size + 4096;
|
||||
_cgo_set_stacklo(g, NULL);
|
||||
}
|
||||
|
||||
|
||||
|
@ -127,12 +127,9 @@ init_working_dir()
|
||||
void
|
||||
x_cgo_init(G *g, void (*setg)(void*))
|
||||
{
|
||||
size_t size;
|
||||
|
||||
//fprintf(stderr, "x_cgo_init = %p\n", &x_cgo_init); // aid debugging in presence of ASLR
|
||||
setg_gcc = setg;
|
||||
size = pthread_get_stacksize_np(pthread_self());
|
||||
g->stacklo = (uintptr)&size - size + 4096;
|
||||
_cgo_set_stacklo(g, NULL);
|
||||
|
||||
#if TARGET_OS_IPHONE
|
||||
darwin_arm_init_mach_exception_handler();
|
||||
|
@ -16,14 +16,8 @@ static void (*setg_gcc)(void*);
|
||||
void
|
||||
x_cgo_init(G *g, void (*setg)(void*))
|
||||
{
|
||||
pthread_attr_t attr;
|
||||
size_t size;
|
||||
|
||||
setg_gcc = setg;
|
||||
pthread_attr_init(&attr);
|
||||
pthread_attr_getstacksize(&attr, &size);
|
||||
g->stacklo = (uintptr)&attr - size + 4096;
|
||||
pthread_attr_destroy(&attr);
|
||||
_cgo_set_stacklo(g, NULL);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -16,14 +16,8 @@ static void (*setg_gcc)(void*);
|
||||
void
|
||||
x_cgo_init(G *g, void (*setg)(void*))
|
||||
{
|
||||
pthread_attr_t attr;
|
||||
size_t size;
|
||||
|
||||
setg_gcc = setg;
|
||||
pthread_attr_init(&attr);
|
||||
pthread_attr_getstacksize(&attr, &size);
|
||||
g->stacklo = (uintptr)&attr - size + 4096;
|
||||
pthread_attr_destroy(&attr);
|
||||
_cgo_set_stacklo(g, NULL);
|
||||
}
|
||||
|
||||
|
||||
|
@ -18,7 +18,6 @@ void
|
||||
x_cgo_init(G *g, void (*setg)(void*))
|
||||
{
|
||||
pthread_attr_t *attr;
|
||||
size_t size;
|
||||
|
||||
// Deal with memory sanitizer/clang interaction.
|
||||
// See gcc_linux_amd64.c for details.
|
||||
@ -27,10 +26,7 @@ x_cgo_init(G *g, void (*setg)(void*))
|
||||
if (attr == NULL) {
|
||||
fatalf("malloc failed: %s", strerror(errno));
|
||||
}
|
||||
pthread_attr_init(attr);
|
||||
pthread_attr_getstacksize(attr, &size);
|
||||
g->stacklo = (uintptr)&attr - size + 4096;
|
||||
pthread_attr_destroy(attr);
|
||||
_cgo_set_stacklo(g, attr);
|
||||
free(attr);
|
||||
}
|
||||
|
||||
|
@ -27,14 +27,8 @@ static void (*setg_gcc)(void*);
|
||||
void
|
||||
x_cgo_init(G *g, void (*setg)(void*))
|
||||
{
|
||||
pthread_attr_t attr;
|
||||
size_t size;
|
||||
|
||||
setg_gcc = setg;
|
||||
pthread_attr_init(&attr);
|
||||
pthread_attr_getstacksize(&attr, &size);
|
||||
g->stacklo = (uintptr)&attr - size + 4096;
|
||||
pthread_attr_destroy(&attr);
|
||||
_cgo_set_stacklo(g, NULL);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -17,14 +17,8 @@ static void (*setg_gcc)(void*);
|
||||
void
|
||||
x_cgo_init(G *g, void (*setg)(void*))
|
||||
{
|
||||
pthread_attr_t attr;
|
||||
size_t size;
|
||||
|
||||
setg_gcc = setg;
|
||||
pthread_attr_init(&attr);
|
||||
pthread_attr_getstacksize(&attr, &size);
|
||||
g->stacklo = (uintptr)&attr - size + 4096;
|
||||
pthread_attr_destroy(&attr);
|
||||
_cgo_set_stacklo(g, NULL);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -17,14 +17,8 @@ static void (*setg_gcc)(void*);
|
||||
void
|
||||
x_cgo_init(G *g, void (*setg)(void*))
|
||||
{
|
||||
pthread_attr_t attr;
|
||||
size_t size;
|
||||
|
||||
setg_gcc = setg;
|
||||
pthread_attr_init(&attr);
|
||||
pthread_attr_getstacksize(&attr, &size);
|
||||
g->stacklo = (uintptr)&attr - size + 4096;
|
||||
pthread_attr_destroy(&attr);
|
||||
_cgo_set_stacklo(g, NULL);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -82,6 +82,34 @@ _cgo_wait_runtime_init_done(void) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// _cgo_set_stacklo sets g->stacklo based on the stack size.
|
||||
// This is common code called from x_cgo_init, which is itself
|
||||
// called by rt0_go in the runtime package.
|
||||
void _cgo_set_stacklo(G *g, pthread_attr_t *pattr)
|
||||
{
|
||||
pthread_attr_t attr;
|
||||
size_t size;
|
||||
|
||||
// pattr can be passed in by the caller; see gcc_linux_amd64.c.
|
||||
if (pattr == NULL) {
|
||||
pattr = &attr;
|
||||
}
|
||||
|
||||
pthread_attr_init(pattr);
|
||||
pthread_attr_getstacksize(pattr, &size);
|
||||
|
||||
g->stacklo = (uintptr)(__builtin_frame_address(0)) - size + 4096;
|
||||
|
||||
// Sanity check the results now, rather than getting a
|
||||
// morestack on g0 crash.
|
||||
if (g->stacklo >= g->stackhi) {
|
||||
fprintf(stderr, "runtime/cgo: bad stack bounds: lo=%p hi=%p\n", (void*)(g->stacklo), (void*)(g->stackhi));
|
||||
abort();
|
||||
}
|
||||
|
||||
pthread_attr_destroy(pattr);
|
||||
}
|
||||
|
||||
// Store the g into a thread-specific value associated with the pthread key pthread_g.
|
||||
// And pthread_key_destructor will dropm when the thread is exiting.
|
||||
void x_cgo_bindm(void* g) {
|
||||
|
@ -17,14 +17,8 @@ void (*x_cgo_inittls)(void **tlsg, void **tlsbase) __attribute__((common));
|
||||
void
|
||||
x_cgo_init(G *g, void (*setg)(void*), void **tlsg, void **tlsbase)
|
||||
{
|
||||
pthread_attr_t attr;
|
||||
size_t size;
|
||||
|
||||
setg_gcc = setg;
|
||||
pthread_attr_init(&attr);
|
||||
pthread_attr_getstacksize(&attr, &size);
|
||||
g->stacklo = (uintptr)&attr - size + 4096;
|
||||
pthread_attr_destroy(&attr);
|
||||
_cgo_set_stacklo(g, NULL);
|
||||
|
||||
if (x_cgo_inittls) {
|
||||
x_cgo_inittls(tlsg, tlsbase);
|
||||
|
@ -20,7 +20,6 @@ void
|
||||
x_cgo_init(G *g, void (*setg)(void*), void **tlsg, void **tlsbase)
|
||||
{
|
||||
pthread_attr_t *attr;
|
||||
size_t size;
|
||||
|
||||
/* The memory sanitizer distributed with versions of clang
|
||||
before 3.8 has a bug: if you call mmap before malloc, mmap
|
||||
@ -42,12 +41,7 @@ x_cgo_init(G *g, void (*setg)(void*), void **tlsg, void **tlsbase)
|
||||
if (attr == NULL) {
|
||||
fatalf("malloc failed: %s", strerror(errno));
|
||||
}
|
||||
pthread_attr_init(attr);
|
||||
pthread_attr_getstacksize(attr, &size);
|
||||
g->stacklo = (uintptr)__builtin_frame_address(0) - size + 4096;
|
||||
if (g->stacklo >= g->stackhi)
|
||||
fatalf("bad stack bounds: lo=%p hi=%p\n", g->stacklo, g->stackhi);
|
||||
pthread_attr_destroy(attr);
|
||||
_cgo_set_stacklo(g, attr);
|
||||
free(attr);
|
||||
|
||||
if (x_cgo_inittls) {
|
||||
|
@ -54,14 +54,8 @@ threadentry(void *v)
|
||||
void
|
||||
x_cgo_init(G *g, void (*setg)(void*), void **tlsg, void **tlsbase)
|
||||
{
|
||||
pthread_attr_t attr;
|
||||
size_t size;
|
||||
|
||||
setg_gcc = setg;
|
||||
pthread_attr_init(&attr);
|
||||
pthread_attr_getstacksize(&attr, &size);
|
||||
g->stacklo = (uintptr)&attr - size + 4096;
|
||||
pthread_attr_destroy(&attr);
|
||||
_cgo_set_stacklo(g, NULL);
|
||||
|
||||
if (x_cgo_inittls) {
|
||||
x_cgo_inittls(tlsg, tlsbase);
|
||||
|
@ -57,7 +57,6 @@ void
|
||||
x_cgo_init(G *g, void (*setg)(void*), void **tlsg, void **tlsbase)
|
||||
{
|
||||
pthread_attr_t *attr;
|
||||
size_t size;
|
||||
|
||||
/* The memory sanitizer distributed with versions of clang
|
||||
before 3.8 has a bug: if you call mmap before malloc, mmap
|
||||
@ -79,10 +78,7 @@ x_cgo_init(G *g, void (*setg)(void*), void **tlsg, void **tlsbase)
|
||||
if (attr == NULL) {
|
||||
fatalf("malloc failed: %s", strerror(errno));
|
||||
}
|
||||
pthread_attr_init(attr);
|
||||
pthread_attr_getstacksize(attr, &size);
|
||||
g->stacklo = (uintptr)&size - size + 4096;
|
||||
pthread_attr_destroy(attr);
|
||||
_cgo_set_stacklo(g, attr);
|
||||
free(attr);
|
||||
|
||||
if (x_cgo_inittls) {
|
||||
|
@ -54,14 +54,8 @@ threadentry(void *v)
|
||||
void
|
||||
x_cgo_init(G *g, void (*setg)(void*), void **tlsg, void **tlsbase)
|
||||
{
|
||||
pthread_attr_t attr;
|
||||
size_t size;
|
||||
|
||||
setg_gcc = setg;
|
||||
pthread_attr_init(&attr);
|
||||
pthread_attr_getstacksize(&attr, &size);
|
||||
g->stacklo = (uintptr)&attr - size + 4096;
|
||||
pthread_attr_destroy(&attr);
|
||||
_cgo_set_stacklo(g, NULL);
|
||||
|
||||
if (x_cgo_inittls) {
|
||||
x_cgo_inittls(tlsg, tlsbase);
|
||||
|
@ -56,14 +56,8 @@ threadentry(void *v)
|
||||
void
|
||||
x_cgo_init(G *g, void (*setg)(void*), void **tlsg, void **tlsbase)
|
||||
{
|
||||
pthread_attr_t attr;
|
||||
size_t size;
|
||||
|
||||
setg_gcc = setg;
|
||||
pthread_attr_init(&attr);
|
||||
pthread_attr_getstacksize(&attr, &size);
|
||||
g->stacklo = (uintptr)&attr - size + 4096;
|
||||
pthread_attr_destroy(&attr);
|
||||
_cgo_set_stacklo(g, NULL);
|
||||
|
||||
if (x_cgo_inittls) {
|
||||
x_cgo_inittls(tlsg, tlsbase);
|
||||
|
@ -56,15 +56,9 @@ threadentry(void *v)
|
||||
void
|
||||
x_cgo_init(G *g, void (*setg)(void*), void **tlsg, void **tlsbase)
|
||||
{
|
||||
pthread_attr_t attr;
|
||||
size_t size;
|
||||
|
||||
setg_gcc = setg;
|
||||
|
||||
pthread_attr_init(&attr);
|
||||
pthread_attr_getstacksize(&attr, &size);
|
||||
g->stacklo = (uintptr)&attr - size + 4096;
|
||||
pthread_attr_destroy(&attr);
|
||||
_cgo_set_stacklo(g, NULL);
|
||||
|
||||
if (x_cgo_inittls) {
|
||||
x_cgo_inittls(tlsg, tlsbase);
|
||||
|
@ -54,14 +54,8 @@ threadentry(void *v)
|
||||
void
|
||||
x_cgo_init(G *g, void (*setg)(void*), void **tlsg, void **tlsbase)
|
||||
{
|
||||
pthread_attr_t attr;
|
||||
size_t size;
|
||||
|
||||
setg_gcc = setg;
|
||||
pthread_attr_init(&attr);
|
||||
pthread_attr_getstacksize(&attr, &size);
|
||||
g->stacklo = (uintptr)&attr - size + 4096;
|
||||
pthread_attr_destroy(&attr);
|
||||
_cgo_set_stacklo(g, NULL);
|
||||
|
||||
if (x_cgo_inittls) {
|
||||
x_cgo_inittls(tlsg, tlsbase);
|
||||
|
@ -16,14 +16,8 @@ static void (*setg_gcc)(void*);
|
||||
void
|
||||
x_cgo_init(G *g, void (*setg)(void*), void **tlsbase)
|
||||
{
|
||||
pthread_attr_t attr;
|
||||
size_t size;
|
||||
|
||||
setg_gcc = setg;
|
||||
pthread_attr_init(&attr);
|
||||
pthread_attr_getstacksize(&attr, &size);
|
||||
g->stacklo = (uintptr)&attr - size + 4096;
|
||||
pthread_attr_destroy(&attr);
|
||||
_cgo_set_stacklo(g, NULL);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -15,14 +15,8 @@ static void (*setg_gcc)(void*);
|
||||
void
|
||||
x_cgo_init(G *g, void (*setg)(void*))
|
||||
{
|
||||
pthread_attr_t attr;
|
||||
size_t size;
|
||||
|
||||
setg_gcc = setg;
|
||||
pthread_attr_init(&attr);
|
||||
pthread_attr_getstacksize(&attr, &size);
|
||||
g->stacklo = (uintptr)&attr - size + 4096;
|
||||
pthread_attr_destroy(&attr);
|
||||
_cgo_set_stacklo(g, NULL);
|
||||
}
|
||||
|
||||
|
||||
|
@ -15,14 +15,8 @@ static void (*setg_gcc)(void*);
|
||||
void
|
||||
x_cgo_init(G *g, void (*setg)(void*))
|
||||
{
|
||||
pthread_attr_t attr;
|
||||
size_t size;
|
||||
|
||||
setg_gcc = setg;
|
||||
pthread_attr_init(&attr);
|
||||
pthread_attr_getstacksize(&attr, &size);
|
||||
g->stacklo = (uintptr)&attr - size + 4096;
|
||||
pthread_attr_destroy(&attr);
|
||||
_cgo_set_stacklo(g, NULL);
|
||||
}
|
||||
|
||||
|
||||
|
@ -16,14 +16,8 @@ static void (*setg_gcc)(void*);
|
||||
void
|
||||
x_cgo_init(G *g, void (*setg)(void*))
|
||||
{
|
||||
pthread_attr_t attr;
|
||||
size_t size;
|
||||
|
||||
setg_gcc = setg;
|
||||
pthread_attr_init(&attr);
|
||||
pthread_attr_getstacksize(&attr, &size);
|
||||
g->stacklo = (uintptr)&attr - size + 4096;
|
||||
pthread_attr_destroy(&attr);
|
||||
_cgo_set_stacklo(g, NULL);
|
||||
}
|
||||
|
||||
|
||||
|
@ -16,14 +16,8 @@ static void (*setg_gcc)(void*);
|
||||
void
|
||||
x_cgo_init(G *g, void (*setg)(void*))
|
||||
{
|
||||
pthread_attr_t attr;
|
||||
size_t size;
|
||||
|
||||
setg_gcc = setg;
|
||||
pthread_attr_init(&attr);
|
||||
pthread_attr_getstacksize(&attr, &size);
|
||||
g->stacklo = (uintptr)&attr - size + 4096;
|
||||
pthread_attr_destroy(&attr);
|
||||
_cgo_set_stacklo(g, NULL);
|
||||
}
|
||||
|
||||
|
||||
|
@ -15,14 +15,8 @@ static void (*setg_gcc)(void*);
|
||||
void
|
||||
x_cgo_init(G *g, void (*setg)(void*))
|
||||
{
|
||||
pthread_attr_t attr;
|
||||
size_t size;
|
||||
|
||||
setg_gcc = setg;
|
||||
pthread_attr_init(&attr);
|
||||
pthread_attr_getstacksize(&attr, &size);
|
||||
g->stacklo = (uintptr)&attr - size + 4096;
|
||||
pthread_attr_destroy(&attr);
|
||||
_cgo_set_stacklo(g, NULL);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -15,14 +15,8 @@ static void (*setg_gcc)(void*);
|
||||
void
|
||||
x_cgo_init(G *g, void (*setg)(void*))
|
||||
{
|
||||
pthread_attr_t attr;
|
||||
size_t size;
|
||||
|
||||
setg_gcc = setg;
|
||||
pthread_attr_init(&attr);
|
||||
pthread_attr_getstacksize(&attr, &size);
|
||||
g->stacklo = (uintptr)&attr - size + 4096;
|
||||
pthread_attr_destroy(&attr);
|
||||
_cgo_set_stacklo(g, NULL);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -15,14 +15,8 @@ static void (*setg_gcc)(void*);
|
||||
void
|
||||
x_cgo_init(G *g, void (*setg)(void*))
|
||||
{
|
||||
pthread_attr_t attr;
|
||||
size_t size;
|
||||
|
||||
setg_gcc = setg;
|
||||
pthread_attr_init(&attr);
|
||||
pthread_attr_getstacksize(&attr, &size);
|
||||
g->stacklo = (uintptr)&attr - size + 4096;
|
||||
pthread_attr_destroy(&attr);
|
||||
_cgo_set_stacklo(g, NULL);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -15,14 +15,8 @@ static void (*setg_gcc)(void*);
|
||||
void
|
||||
x_cgo_init(G *g, void (*setg)(void*))
|
||||
{
|
||||
pthread_attr_t attr;
|
||||
size_t size;
|
||||
|
||||
setg_gcc = setg;
|
||||
pthread_attr_init(&attr);
|
||||
pthread_attr_getstacksize(&attr, &size);
|
||||
g->stacklo = (uintptr)&attr - size + 4096;
|
||||
pthread_attr_destroy(&attr);
|
||||
_cgo_set_stacklo(g, NULL);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -15,14 +15,8 @@ static void (*setg_gcc)(void*);
|
||||
void
|
||||
x_cgo_init(G *g, void (*setg)(void*))
|
||||
{
|
||||
pthread_attr_t attr;
|
||||
size_t size;
|
||||
|
||||
setg_gcc = setg;
|
||||
pthread_attr_init(&attr);
|
||||
pthread_attr_getstacksize(&attr, &size);
|
||||
g->stacklo = (uintptr)&attr - size + 4096;
|
||||
pthread_attr_destroy(&attr);
|
||||
_cgo_set_stacklo(g, NULL);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -18,14 +18,8 @@ static void (*setg_gcc)(void*);
|
||||
void
|
||||
x_cgo_init(G *g, void (*setg)(void*), void **tlsbase)
|
||||
{
|
||||
pthread_attr_t attr;
|
||||
size_t size;
|
||||
|
||||
setg_gcc = setg;
|
||||
pthread_attr_init(&attr);
|
||||
pthread_attr_getstacksize(&attr, &size);
|
||||
g->stacklo = (uintptr)&attr - size + 4096;
|
||||
pthread_attr_destroy(&attr);
|
||||
_cgo_set_stacklo(g, NULL);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -27,6 +27,13 @@ x_cgo_init(G *g, void (*setg)(void*))
|
||||
// See golang.org/issue/12210.
|
||||
if(ctx.uc_stack.ss_size < 1024*1024)
|
||||
g->stacklo -= 1024*1024 - ctx.uc_stack.ss_size;
|
||||
|
||||
// Sanity check the results now, rather than getting a
|
||||
// morestack on g0 crash.
|
||||
if (g->stacklo >= g->stackhi) {
|
||||
fprintf(stderr, "runtime/cgo: bad stack bounds: lo=%p hi=%p\n", (void*)(g->stacklo), (void*)(g->stackhi));
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -2,6 +2,11 @@
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
/*
|
||||
* Initialize g->stacklo.
|
||||
*/
|
||||
extern void _cgo_set_stacklo(G *, pthread_attr_t*);
|
||||
|
||||
/*
|
||||
* Call pthread_create, retrying on EAGAIN.
|
||||
*/
|
||||
|
Loading…
Reference in New Issue
Block a user