c2047754c3
Compiler changes: * Change map assignment to use mapassign and assign value directly. * Change string iteration to use decoderune, faster for ASCII strings. * Change makeslice to take int, and use makeslice64 for larger values. * Add new noverflow field to hmap struct used for maps. Unresolved problems, to be fixed later: * Commented out test in go/types/sizes_test.go that doesn't compile. * Commented out reflect.TestStructOf test for padding after zero-sized field. Reviewed-on: https://go-review.googlesource.com/35231 gotools/: Updates for Go 1.8rc1. * Makefile.am (go_cmd_go_files): Add bug.go. (s-zdefaultcc): Write defaultPkgConfig. * Makefile.in: Rebuild. From-SVN: r244456
99 lines
2.1 KiB
Go
99 lines
2.1 KiB
Go
// Copyright 2015 The Go Authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style
|
|
// license that can be found in the LICENSE file.
|
|
|
|
// We only build this file with the tag "threadprof", since it starts
|
|
// a thread running a busy loop at constructor time.
|
|
|
|
// +build !plan9,!windows
|
|
// +build threadprof
|
|
|
|
package main
|
|
|
|
/*
|
|
#include <stdint.h>
|
|
#include <signal.h>
|
|
#include <pthread.h>
|
|
|
|
volatile int32_t spinlock;
|
|
|
|
static void *thread1(void *p) {
|
|
(void)p;
|
|
while (spinlock == 0)
|
|
;
|
|
pthread_kill(pthread_self(), SIGPROF);
|
|
spinlock = 0;
|
|
return NULL;
|
|
}
|
|
|
|
__attribute__((constructor)) void issue9456() {
|
|
pthread_t tid;
|
|
pthread_create(&tid, 0, thread1, NULL);
|
|
}
|
|
|
|
void **nullptr;
|
|
|
|
void *crash(void *p) {
|
|
*nullptr = p;
|
|
return 0;
|
|
}
|
|
|
|
int start_crashing_thread(void) {
|
|
pthread_t tid;
|
|
return pthread_create(&tid, 0, crash, 0);
|
|
}
|
|
*/
|
|
import "C"
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
"os/exec"
|
|
"runtime"
|
|
"sync/atomic"
|
|
"time"
|
|
"unsafe"
|
|
)
|
|
|
|
func init() {
|
|
register("CgoExternalThreadSIGPROF", CgoExternalThreadSIGPROF)
|
|
register("CgoExternalThreadSignal", CgoExternalThreadSignal)
|
|
}
|
|
|
|
func CgoExternalThreadSIGPROF() {
|
|
// This test intends to test that sending SIGPROF to foreign threads
|
|
// before we make any cgo call will not abort the whole process, so
|
|
// we cannot make any cgo call here. See https://golang.org/issue/9456.
|
|
atomic.StoreInt32((*int32)(unsafe.Pointer(&C.spinlock)), 1)
|
|
for atomic.LoadInt32((*int32)(unsafe.Pointer(&C.spinlock))) == 1 {
|
|
runtime.Gosched()
|
|
}
|
|
println("OK")
|
|
}
|
|
|
|
func CgoExternalThreadSignal() {
|
|
if len(os.Args) > 2 && os.Args[2] == "crash" {
|
|
i := C.start_crashing_thread()
|
|
if i != 0 {
|
|
fmt.Println("pthread_create failed:", i)
|
|
// Exit with 0 because parent expects us to crash.
|
|
return
|
|
}
|
|
|
|
// We should crash immediately, but give it plenty of
|
|
// time before failing (by exiting 0) in case we are
|
|
// running on a slow system.
|
|
time.Sleep(5 * time.Second)
|
|
return
|
|
}
|
|
|
|
out, err := exec.Command(os.Args[0], "CgoExternalThreadSignal", "crash").CombinedOutput()
|
|
if err == nil {
|
|
fmt.Println("C signal did not crash as expected")
|
|
fmt.Printf("\n%s\n", out)
|
|
os.Exit(1)
|
|
}
|
|
|
|
fmt.Println("OK")
|
|
}
|