mirror of https://github.com/golang/go.git
[release-branch.go1.4] runtime: fix SIGPROF change
CL 2789 backported a change that required a barrage of followup CLs.
This CL backports all the followup CLs together.
There are manual edits to os_plan9.go and syscall_windows.go to take
the place of edits to defs_windows_{amd64,386}.go and os2_plan9.go
in the original. Those files do not exist in the release branch, but the
definition being added must go somewhere.
Original change descriptions below.
---
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>
(cherry picked from commit 77cd6197d7)
---
runtime: provide a dummy value of _SIGPROF on plan9 and windows
Fixes build on plan9 and windows.
Change-Id: Ic9b02c641ab84e4f6d8149de71b9eb495e3343b2
Reviewed-on: https://go-review.googlesource.com/2233
Reviewed-by: Alex Brainman <alex.brainman@gmail.com>
(cherry picked from commit 1f28238557)
---
runtime/cgo: remove unused variable
I missed this one in golang.org/cl/2232 and only tested the patch
on openbsd/amd64.
Change-Id: I4ff437ae0bfc61c989896c01904b6d33f9bdf0ec
Reviewed-on: https://go-review.googlesource.com/2234
Reviewed-by: Minux Ma <minux@golang.org>
(cherry picked from commit 0b2a74e89c)
---
runtime: skip TestCgoExternalThreadSIGPROF on OS X 10.6
The test program requires static constructor, which in turn needs
external linking to work, but external linking never works on 10.6.
This should fix the darwin-{386,amd64} builders.
Change-Id: I714fdd3e35f9a7e5f5659cf26367feec9412444f
Reviewed-on: https://go-review.googlesource.com/2235
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
(cherry picked from commit 2cbe27a272)
---
runtime: fix TestCgoExternalThreadSIGPROF again
Shell out to `uname -r` this time, so that the test will compile
even if the platform doesn't have syscall.Sysctl.
Change-Id: I3a19ab5d820bdb94586a97f4507b3837d7040525
Reviewed-on: https://go-review.googlesource.com/2271
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
(cherry picked from commit 865e5e98b6)
---
runtime: remove unnecessary GOOS switch
Change-Id: I8f518e273c02110042b08f7c50c3d38a648c8b6e
Reviewed-on: https://go-review.googlesource.com/2281
Reviewed-by: Minux Ma <minux@golang.org>
(cherry picked from commit 1ebfb082a7)
---
Change-Id: Ifee9667ca90eda2b074817c319b1b7c66d4f741d
Reviewed-on: https://go-review.googlesource.com/2805
Reviewed-by: Minux Ma <minux@golang.org>
Reviewed-by: Andrew Gerrand <adg@golang.org>
This commit is contained in:
parent
d9e0ca4055
commit
add1ee0ed5
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@
|
|||
package runtime_test
|
||||
|
||||
import (
|
||||
"os/exec"
|
||||
"runtime"
|
||||
"strings"
|
||||
"testing"
|
||||
|
|
@ -52,8 +53,20 @@ func TestCgoExternalThreadPanic(t *testing.T) {
|
|||
|
||||
func TestCgoExternalThreadSIGPROF(t *testing.T) {
|
||||
// issue 9456.
|
||||
if runtime.GOOS == "plan9" || runtime.GOOS == "windows" {
|
||||
switch runtime.GOOS {
|
||||
case "plan9", "windows":
|
||||
t.Skipf("no pthreads on %s", runtime.GOOS)
|
||||
case "darwin":
|
||||
// static constructor needs external linking, but we don't support
|
||||
// external linking on OS X 10.6.
|
||||
out, err := exec.Command("uname", "-r").Output()
|
||||
if err != nil {
|
||||
t.Fatalf("uname -r failed: %v", err)
|
||||
}
|
||||
// OS X 10.6 == Darwin 10.x
|
||||
if strings.HasPrefix(string(out), "10.") {
|
||||
t.Skipf("no external linking on OS X 10.6")
|
||||
}
|
||||
}
|
||||
got := executeTest(t, cgoExternalThreadSIGPROFSource, nil)
|
||||
want := "OK\n"
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@ const (
|
|||
DUPLICATE_SAME_ACCESS = C.DUPLICATE_SAME_ACCESS
|
||||
THREAD_PRIORITY_HIGHEST = C.THREAD_PRIORITY_HIGHEST
|
||||
|
||||
SIGPROF = 0 // dummy value for badsignal
|
||||
SIGINT = C.SIGINT
|
||||
CTRL_C_EVENT = C.CTRL_C_EVENT
|
||||
CTRL_BREAK_EVENT = C.CTRL_BREAK_EVENT
|
||||
|
|
|
|||
|
|
@ -6,6 +6,8 @@ package runtime
|
|||
|
||||
import "unsafe"
|
||||
|
||||
const _SIGPROF = 0 // dummy value for badsignal
|
||||
|
||||
func pread(fd int32, buf unsafe.Pointer, nbytes int32, offset int64) int32
|
||||
func pwrite(fd int32, buf unsafe.Pointer, nbytes int32, offset int64) int32
|
||||
func seek(fd int32, offset int64, whence int32) int64
|
||||
|
|
|
|||
|
|
@ -160,7 +160,7 @@ func badsignal(sig uintptr) {
|
|||
// call to cgocallback below will bring down the whole process.
|
||||
// It's better to miss a few SIGPROF signals than to abort in this case.
|
||||
// See http://golang.org/issue/9456.
|
||||
if sig == _SIGPROF && needextram != 0 {
|
||||
if _SIGPROF != 0 && sig == _SIGPROF && needextram != 0 {
|
||||
return
|
||||
}
|
||||
cgocallback(unsafe.Pointer(funcPC(sigsend)), noescape(unsafe.Pointer(&sig)), unsafe.Sizeof(sig))
|
||||
|
|
|
|||
|
|
@ -8,6 +8,8 @@ import (
|
|||
"unsafe"
|
||||
)
|
||||
|
||||
const _SIGPROF = 0 // dummy value for badsignal
|
||||
|
||||
type callbacks struct {
|
||||
lock mutex
|
||||
ctxt [cb_max]*wincallbackcontext
|
||||
|
|
|
|||
Loading…
Reference in New Issue