mirror of
https://github.com/golang/go
synced 2024-11-19 03:24:40 -07:00
runtime/cgo: initialize our pthread_create wrapper earlier on openbsd
This is a genuine bug exposed by our test for issue 9456: our wrapper for pthread_create is not initialized until we initialize cgo itself, but it is possible that a static constructor could call pthread_create, and in that case, it will be calling a nil function pointer. Fix that by also initializing the sys_pthread_create function pointer inside our pthread_create wrapper function, and use a pthread_once to make sure it is only initialized once. Fix build for openbsd. Change-Id: Ica4da2c21fcaec186fdd3379128ef46f0e767ed7 Reviewed-on: https://go-review.googlesource.com/2232 Reviewed-by: David Crawshaw <crawshaw@golang.org>
This commit is contained in:
parent
76b2f06ee5
commit
77cd6197d7
@ -65,12 +65,39 @@ thread_start_wrapper(void *arg)
|
||||
return args.func(args.arg);
|
||||
}
|
||||
|
||||
static void init_pthread_wrapper(void) {
|
||||
void *handle;
|
||||
|
||||
// Locate symbol for the system pthread_create function.
|
||||
handle = dlopen("libpthread.so", RTLD_LAZY);
|
||||
if(handle == NULL) {
|
||||
fprintf(stderr, "runtime/cgo: dlopen failed to load libpthread: %s\n", dlerror());
|
||||
abort();
|
||||
}
|
||||
sys_pthread_create = dlsym(handle, "pthread_create");
|
||||
if(sys_pthread_create == NULL) {
|
||||
fprintf(stderr, "runtime/cgo: dlsym failed to find pthread_create: %s\n", dlerror());
|
||||
abort();
|
||||
}
|
||||
dlclose(handle);
|
||||
}
|
||||
|
||||
static pthread_once_t init_pthread_wrapper_once = PTHREAD_ONCE_INIT;
|
||||
|
||||
int
|
||||
pthread_create(pthread_t *thread, const pthread_attr_t *attr,
|
||||
void *(*start_routine)(void *), void *arg)
|
||||
{
|
||||
struct thread_args *p;
|
||||
|
||||
// we must initialize our wrapper in pthread_create, because it is valid to call
|
||||
// pthread_create in a static constructor, and in fact, our test for issue 9456
|
||||
// does just that.
|
||||
if(pthread_once(&init_pthread_wrapper_once, init_pthread_wrapper) != 0) {
|
||||
fprintf(stderr, "runtime/cgo: failed to initialize pthread_create wrapper\n");
|
||||
abort();
|
||||
}
|
||||
|
||||
p = malloc(sizeof(*p));
|
||||
if(p == NULL) {
|
||||
errno = ENOMEM;
|
||||
@ -95,18 +122,10 @@ x_cgo_init(G *g, void (*setg)(void*))
|
||||
g->stacklo = (uintptr)&attr - size + 4096;
|
||||
pthread_attr_destroy(&attr);
|
||||
|
||||
// Locate symbol for the system pthread_create function.
|
||||
handle = dlopen("libpthread.so", RTLD_LAZY);
|
||||
if(handle == NULL) {
|
||||
fprintf(stderr, "dlopen: failed to load libpthread: %s\n", dlerror());
|
||||
if(pthread_once(&init_pthread_wrapper_once, init_pthread_wrapper) != 0) {
|
||||
fprintf(stderr, "runtime/cgo: failed to initialize pthread_create wrapper\n");
|
||||
abort();
|
||||
}
|
||||
sys_pthread_create = dlsym(handle, "pthread_create");
|
||||
if(sys_pthread_create == NULL) {
|
||||
fprintf(stderr, "dlsym: failed to find pthread_create: %s\n", dlerror());
|
||||
abort();
|
||||
}
|
||||
dlclose(handle);
|
||||
|
||||
tcb_fixup(1);
|
||||
}
|
||||
|
@ -65,12 +65,39 @@ thread_start_wrapper(void *arg)
|
||||
return args.func(args.arg);
|
||||
}
|
||||
|
||||
static void init_pthread_wrapper(void) {
|
||||
void *handle;
|
||||
|
||||
// Locate symbol for the system pthread_create function.
|
||||
handle = dlopen("libpthread.so", RTLD_LAZY);
|
||||
if(handle == NULL) {
|
||||
fprintf(stderr, "runtime/cgo: dlopen failed to load libpthread: %s\n", dlerror());
|
||||
abort();
|
||||
}
|
||||
sys_pthread_create = dlsym(handle, "pthread_create");
|
||||
if(sys_pthread_create == NULL) {
|
||||
fprintf(stderr, "runtime/cgo: dlsym failed to find pthread_create: %s\n", dlerror());
|
||||
abort();
|
||||
}
|
||||
dlclose(handle);
|
||||
}
|
||||
|
||||
static pthread_once_t init_pthread_wrapper_once = PTHREAD_ONCE_INIT;
|
||||
|
||||
int
|
||||
pthread_create(pthread_t *thread, const pthread_attr_t *attr,
|
||||
void *(*start_routine)(void *), void *arg)
|
||||
{
|
||||
struct thread_args *p;
|
||||
|
||||
// we must initialize our wrapper in pthread_create, because it is valid to call
|
||||
// pthread_create in a static constructor, and in fact, our test for issue 9456
|
||||
// does just that.
|
||||
if(pthread_once(&init_pthread_wrapper_once, init_pthread_wrapper) != 0) {
|
||||
fprintf(stderr, "runtime/cgo: failed to initialize pthread_create wrapper\n");
|
||||
abort();
|
||||
}
|
||||
|
||||
p = malloc(sizeof(*p));
|
||||
if(p == NULL) {
|
||||
errno = ENOMEM;
|
||||
@ -87,7 +114,6 @@ x_cgo_init(G *g, void (*setg)(void*))
|
||||
{
|
||||
pthread_attr_t attr;
|
||||
size_t size;
|
||||
void *handle;
|
||||
|
||||
setg_gcc = setg;
|
||||
pthread_attr_init(&attr);
|
||||
@ -95,18 +121,10 @@ x_cgo_init(G *g, void (*setg)(void*))
|
||||
g->stacklo = (uintptr)&attr - size + 4096;
|
||||
pthread_attr_destroy(&attr);
|
||||
|
||||
// Locate symbol for the system pthread_create function.
|
||||
handle = dlopen("libpthread.so", RTLD_LAZY);
|
||||
if(handle == NULL) {
|
||||
fprintf(stderr, "dlopen: failed to load libpthread: %s\n", dlerror());
|
||||
if(pthread_once(&init_pthread_wrapper_once, init_pthread_wrapper) != 0) {
|
||||
fprintf(stderr, "runtime/cgo: failed to initialize pthread_create wrapper\n");
|
||||
abort();
|
||||
}
|
||||
sys_pthread_create = dlsym(handle, "pthread_create");
|
||||
if(sys_pthread_create == NULL) {
|
||||
fprintf(stderr, "dlsym: failed to find pthread_create: %s\n", dlerror());
|
||||
abort();
|
||||
}
|
||||
dlclose(handle);
|
||||
|
||||
tcb_fixup(1);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user