View
@@ -0,0 +1,112 @@
// Copyright 2016 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.
// +build !plan9,!windows
package main
// Run a slow C function saving a CPU profile.
/*
#include <stdint.h>
#include <time.h>
#include <pthread.h>
int threadSalt1;
int threadSalt2;
void cpuHogThread() {
int foo = threadSalt1;
int i;
for (i = 0; i < 100000; i++) {
if (foo > 0) {
foo *= foo;
} else {
foo *= foo + 1;
}
}
threadSalt2 = foo;
}
static int cpuHogThreadCount;
struct cgoTracebackArg {
uintptr_t context;
uintptr_t sigContext;
uintptr_t* buf;
uintptr_t max;
};
static void *pprofThread(void* p) {
time_t start;
(void)p;
start = time(NULL);
while (__sync_add_and_fetch(&cpuHogThreadCount, 0) < 2 && time(NULL) - start < 2) {
cpuHogThread();
}
}
// pprofCgoThreadTraceback is passed to runtime.SetCgoTraceback.
// For testing purposes it pretends that all CPU hits in C code are in cpuHog.
void pprofCgoThreadTraceback(void* parg) {
struct cgoTracebackArg* arg = (struct cgoTracebackArg*)(parg);
arg->buf[0] = (uintptr_t)(cpuHogThread) + 0x10;
arg->buf[1] = 0;
__sync_add_and_fetch(&cpuHogThreadCount, 1);
}
// getCPUHogThreadCount fetches the number of times we've seen cpuHogThread
// in the traceback.
int getCPUHogThreadCount() {
return __sync_add_and_fetch(&cpuHogThreadCount, 0);
}
*/
import "C"
import (
"fmt"
"io/ioutil"
"os"
"runtime"
"runtime/pprof"
"time"
"unsafe"
)
func init() {
register("CgoPprofThread", CgoPprofThread)
}
func CgoPprofThread() {
runtime.SetCgoTraceback(0, unsafe.Pointer(C.pprofCgoThreadTraceback), nil, nil)
f, err := ioutil.TempFile("", "prof")
if err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(2)
}
if err := pprof.StartCPUProfile(f); err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(2)
}
t0 := time.Now()
for C.getCPUHogThreadCount() < 2 && time.Since(t0) < time.Second {
time.Sleep(100 * time.Millisecond)
}
pprof.StopCPUProfile()
name := f.Name()
if err := f.Close(); err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(2)
}
fmt.Println(name)
}
View
@@ -844,8 +844,8 @@ func isSystemGoroutine(gp *g) bool {
// If the Context field is not 0, then it is a value returned by a
// previous call to the context function. This case is called when the
// context is no longer needed; that is, when the Go code is returning
// to its C code caller. This permits permits the context function to
// release any associated resources.
// to its C code caller. This permits the context function to release
// any associated resources.
//
// While it would be correct for the context function to record a
// complete a stack trace whenever it is called, and simply copy that
@@ -962,12 +962,21 @@ func isSystemGoroutine(gp *g) bool {
// traceback function will only be called with the context field set
// to zero. If the context function is nil, then calls from Go to C
// to Go will not show a traceback for the C portion of the call stack.
//
// SetCgoTraceback should be called only once, ideally from an init function.
func SetCgoTraceback(version int, traceback, context, symbolizer unsafe.Pointer) {
if version != 0 {
panic("unsupported version")
}
if cgoTraceback != nil && cgoTraceback != traceback ||
cgoContext != nil && cgoContext != context ||
cgoSymbolizer != nil && cgoSymbolizer != symbolizer {
panic("call SetCgoTraceback only once")
}
cgoTraceback = traceback
cgoContext = context
cgoSymbolizer = symbolizer
// The context function is called when a C function calls a Go
@@ -978,6 +987,7 @@ func SetCgoTraceback(version int, traceback, context, symbolizer unsafe.Pointer)
}
var cgoTraceback unsafe.Pointer
var cgoContext unsafe.Pointer
var cgoSymbolizer unsafe.Pointer
// cgoTracebackArg is the type passed to cgoTraceback.
View
@@ -323,7 +323,9 @@ type method struct {
type uncommontype struct {
pkgpath nameOff
mcount uint16 // number of methods
moff uint16 // offset from this uncommontype to [mcount]method
_ uint16 // unused
moff uint32 // offset from this uncommontype to [mcount]method
_ uint32 // unused
}
type imethod struct {
View
@@ -183,59 +183,50 @@ func TestFtoaRandom(t *testing.T) {
}
}
func BenchmarkFormatFloatDecimal(b *testing.B) {
for i := 0; i < b.N; i++ {
FormatFloat(33909, 'g', -1, 64)
}
var ftoaBenches = []struct {
name string
float float64
fmt byte
prec int
bitSize int
}{
{"Decimal", 33909, 'g', -1, 64},
{"Float", 339.7784, 'g', -1, 64},
{"Exp", -5.09e75, 'g', -1, 64},
{"NegExp", -5.11e-95, 'g', -1, 64},
{"Big", 123456789123456789123456789, 'g', -1, 64},
{"BinaryExp", -1, 'b', -1, 64},
{"32Integer", 33909, 'g', -1, 32},
{"32ExactFraction", 3.375, 'g', -1, 32},
{"32Point", 339.7784, 'g', -1, 32},
{"32Exp", -5.09e25, 'g', -1, 32},
{"32NegExp", -5.11e-25, 'g', -1, 32},
{"64Fixed1", 123456, 'e', 3, 64},
{"64Fixed2", 123.456, 'e', 3, 64},
{"64Fixed3", 1.23456e+78, 'e', 3, 64},
{"64Fixed4", 1.23456e-78, 'e', 3, 64},
}
func BenchmarkFormatFloat(b *testing.B) {
for i := 0; i < b.N; i++ {
FormatFloat(339.7784, 'g', -1, 64)
}
}
func BenchmarkFormatFloatExp(b *testing.B) {
for i := 0; i < b.N; i++ {
FormatFloat(-5.09e75, 'g', -1, 64)
}
}
func BenchmarkFormatFloatNegExp(b *testing.B) {
for i := 0; i < b.N; i++ {
FormatFloat(-5.11e-95, 'g', -1, 64)
}
}
func BenchmarkFormatFloatBig(b *testing.B) {
for i := 0; i < b.N; i++ {
FormatFloat(123456789123456789123456789, 'g', -1, 64)
for _, c := range ftoaBenches {
b.Run(c.name, func(b *testing.B) {
for i := 0; i < b.N; i++ {
FormatFloat(c.float, c.fmt, c.prec, c.bitSize)
}
})
}
}
func benchmarkAppendFloat(b *testing.B, f float64, fmt byte, prec, bitSize int) {
func BenchmarkAppendFloat(b *testing.B) {
dst := make([]byte, 30)
for i := 0; i < b.N; i++ {
AppendFloat(dst[:0], f, fmt, prec, bitSize)
for _, c := range ftoaBenches {
b.Run(c.name, func(b *testing.B) {
for i := 0; i < b.N; i++ {
AppendFloat(dst[:0], c.float, c.fmt, c.prec, c.bitSize)
}
})
}
}
func BenchmarkAppendFloatDecimal(b *testing.B) { benchmarkAppendFloat(b, 33909, 'g', -1, 64) }
func BenchmarkAppendFloat(b *testing.B) { benchmarkAppendFloat(b, 339.7784, 'g', -1, 64) }
func BenchmarkAppendFloatExp(b *testing.B) { benchmarkAppendFloat(b, -5.09e75, 'g', -1, 64) }
func BenchmarkAppendFloatNegExp(b *testing.B) { benchmarkAppendFloat(b, -5.11e-95, 'g', -1, 64) }
func BenchmarkAppendFloatBig(b *testing.B) {
benchmarkAppendFloat(b, 123456789123456789123456789, 'g', -1, 64)
}
func BenchmarkAppendFloatBinaryExp(b *testing.B) { benchmarkAppendFloat(b, -1, 'b', -1, 64) }
func BenchmarkAppendFloat32Integer(b *testing.B) { benchmarkAppendFloat(b, 33909, 'g', -1, 32) }
func BenchmarkAppendFloat32ExactFraction(b *testing.B) { benchmarkAppendFloat(b, 3.375, 'g', -1, 32) }
func BenchmarkAppendFloat32Point(b *testing.B) { benchmarkAppendFloat(b, 339.7784, 'g', -1, 32) }
func BenchmarkAppendFloat32Exp(b *testing.B) { benchmarkAppendFloat(b, -5.09e25, 'g', -1, 32) }
func BenchmarkAppendFloat32NegExp(b *testing.B) { benchmarkAppendFloat(b, -5.11e-25, 'g', -1, 32) }
func BenchmarkAppendFloat64Fixed1(b *testing.B) { benchmarkAppendFloat(b, 123456, 'e', 3, 64) }
func BenchmarkAppendFloat64Fixed2(b *testing.B) { benchmarkAppendFloat(b, 123.456, 'e', 3, 64) }
func BenchmarkAppendFloat64Fixed3(b *testing.B) { benchmarkAppendFloat(b, 1.23456e+78, 'e', 3, 64) }
func BenchmarkAppendFloat64Fixed4(b *testing.B) { benchmarkAppendFloat(b, 1.23456e-78, 'e', 3, 64) }
View
@@ -206,9 +206,15 @@ func forkAndExecInChild(argv0 *byte, argv, envv []*byte, chroot, dir *byte, attr
// User and groups
if cred := sys.Credential; cred != nil {
ngroups := uintptr(len(cred.Groups))
groups := uintptr(0)
if ngroups > 0 {
groups := unsafe.Pointer(&cred.Groups[0])
_, _, err1 = RawSyscall(SYS_SETGROUPS, ngroups, uintptr(groups), 0)
groups = uintptr(unsafe.Pointer(&cred.Groups[0]))
}
// Don't call setgroups in case of user namespace, gid mappings
// and disabled setgroups, because otherwise unprivileged user namespace
// will fail with any non-empty SysProcAttr.Credential.
if !(sys.GidMappings != nil && !sys.GidMappingsEnableSetgroups && ngroups == 0) {
_, _, err1 = RawSyscall(SYS_SETGROUPS, ngroups, groups, 0)
if err1 != 0 {
goto childerror
}
View
@@ -26,7 +26,7 @@ func isChrooted(t *testing.T) bool {
return root.Sys().(*syscall.Stat_t).Ino != 2
}
func whoamiCmd(t *testing.T, uid, gid int, setgroups bool) *exec.Cmd {
func checkUserNS(t *testing.T) {
if _, err := os.Stat("/proc/self/ns/user"); err != nil {
if os.IsNotExist(err) {
t.Skip("kernel doesn't support user namespaces")
@@ -56,6 +56,10 @@ func whoamiCmd(t *testing.T, uid, gid int, setgroups bool) *exec.Cmd {
if os.Getenv("GO_BUILDER_NAME") != "" && os.Getenv("IN_KUBERNETES") == "1" {
t.Skip("skipping test on Kubernetes-based builders; see Issue 12815")
}
}
func whoamiCmd(t *testing.T, uid, gid int, setgroups bool) *exec.Cmd {
checkUserNS(t)
cmd := exec.Command("whoami")
cmd.SysProcAttr = &syscall.SysProcAttr{
Cloneflags: syscall.CLONE_NEWUSER,
@@ -141,7 +145,24 @@ func TestUnshare(t *testing.T) {
t.Skip("skipping test on Kubernetes-based builders; see Issue 12815")
}
cmd := exec.Command("cat", "/proc/net/dev")
path := "/proc/net/dev"
if _, err := os.Stat(path); err != nil {
if os.IsNotExist(err) {
t.Skip("kernel doesn't support proc filesystem")
}
if os.IsPermission(err) {
t.Skip("unable to test proc filesystem due to permissions")
}
t.Fatal(err)
}
if _, err := os.Stat("/proc/self/ns/net"); err != nil {
if os.IsNotExist(err) {
t.Skip("kernel doesn't support net namespace")
}
t.Fatal(err)
}
cmd := exec.Command("cat", path)
cmd.SysProcAttr = &syscall.SysProcAttr{
Unshareflags: syscall.CLONE_NEWNET,
}
@@ -161,3 +182,58 @@ func TestUnshare(t *testing.T) {
t.Fatalf("Expected 3 lines of output, got %d", len(lines))
}
}
func TestGroupCleanup(t *testing.T) {
if os.Getuid() != 0 {
t.Skip("we need root for credential")
}
cmd := exec.Command("id")
cmd.SysProcAttr = &syscall.SysProcAttr{
Credential: &syscall.Credential{
Uid: 0,
Gid: 0,
},
}
out, err := cmd.CombinedOutput()
if err != nil {
t.Fatalf("Cmd failed with err %v, output: %s", err, out)
}
strOut := strings.TrimSpace(string(out))
expected := "uid=0(root) gid=0(root) groups=0(root)"
if strOut != expected {
t.Fatalf("id command output: %s, expected: %s", strOut, expected)
}
}
func TestGroupCleanupUserNamespace(t *testing.T) {
if os.Getuid() != 0 {
t.Skip("we need root for credential")
}
checkUserNS(t)
cmd := exec.Command("id")
uid, gid := os.Getuid(), os.Getgid()
cmd.SysProcAttr = &syscall.SysProcAttr{
Cloneflags: syscall.CLONE_NEWUSER,
Credential: &syscall.Credential{
Uid: uint32(uid),
Gid: uint32(gid),
},
UidMappings: []syscall.SysProcIDMap{
{ContainerID: 0, HostID: uid, Size: 1},
},
GidMappings: []syscall.SysProcIDMap{
{ContainerID: 0, HostID: gid, Size: 1},
},
}
out, err := cmd.CombinedOutput()
if err != nil {
t.Fatalf("Cmd failed with err %v, output: %s", err, out)
}
strOut := strings.TrimSpace(string(out))
// there are two possible outs
expected1 := "uid=0(root) gid=0(root) groups=0(root)"
expected2 := "uid=0(root) gid=0(root) groups=0(root),65534(nobody)"
if strOut != expected1 && strOut != expected2 {
t.Fatalf("id command output: %s, expected: %s or %s", strOut, expected1, expected2)
}
}
View
@@ -117,7 +117,7 @@ struct my_epoll_event {
// alignment requirements of EABI
int32_t padFd;
#endif
#ifdef __powerpc64__
#if defined(__powerpc64__) || defined(__s390x__)
int32_t _padFd;
#endif
int32_t fd;
View
@@ -588,6 +588,7 @@ type Ustat_t struct {
type EpollEvent struct {
Events uint32
_ int32
Fd int32
Pad int32
}
View
@@ -51,6 +51,9 @@ import "errors"
// use of "GMT" in that case.
// In general RFC1123Z should be used instead of RFC1123 for servers
// that insist on that format, and RFC3339 should be preferred for new protocols.
// RFC822, RFC822Z, RFC1123, and RFC1123Z are useful for formatting;
// when used with time.Parse they do not accept all the time formats
// permitted by the RFCs.
const (
ANSIC = "Mon Jan _2 15:04:05 2006"
UnixDate = "Mon Jan _2 15:04:05 MST 2006"
View
@@ -30,7 +30,7 @@ var filename = flag.String("output", "zoneinfo_abbrs_windows.go", "output file n
// getAbbrs finds timezone abbreviations (standard and daylight saving time)
// for location l.
func getAbbrs(l *time.Location) (st, dt string) {
t := time.Date(time.Now().Year(), 0, 0, 0, 0, 0, 0, l)
t := time.Date(time.Now().Year(), 0, 1, 0, 0, 0, 0, l)
abbr1, off1 := t.Zone()
for i := 0; i < 12; i++ {
t = t.AddDate(0, 1, 0)
View
@@ -54,6 +54,14 @@ type Timer struct {
// expired or been stopped.
// Stop does not close the channel, to prevent a read from the channel succeeding
// incorrectly.
//
// To prevent the timer firing after a call to Stop,
// check the return value and drain the channel. For example:
// if !t.Stop() {
// <-t.C
// }
// This cannot be done concurrent to other receives from the Timer's
// channel.
func (t *Timer) Stop() bool {
if t.r.f == nil {
panic("time: Stop called on uninitialized Timer")
@@ -80,6 +88,20 @@ func NewTimer(d Duration) *Timer {
// Reset changes the timer to expire after duration d.
// It returns true if the timer had been active, false if the timer had
// expired or been stopped.
//
// To reuse an active timer, always call its Stop method first and—if it had
// expired—drain the value from its channel. For example:
// if !t.Stop() {
// <-t.C
// }
// t.Reset(d)
// This should not be done concurrent to other receives from the Timer's
// channel.
//
// Note that it is not possible to use Reset's return value correctly, as there
// is a race condition between draining the channel and the new timer expiring.
// Reset should always be used in concert with Stop, as described above.
// The return value exists to preserve compatibility with existing programs.
func (t *Timer) Reset(d Duration) bool {
if t.r.f == nil {
panic("time: Reset called on uninitialized Timer")
View

Some generated files are not rendered by default. Learn more.

Oops, something went wrong.
View
@@ -0,0 +1,20 @@
// build
// Copyright 2016 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.
// Issue 15926: linker was adding .def to the end of symbols, causing
// a name collision with a method actually named def.
package main
type S struct{}
func (s S) def() {}
var I = S.def
func main() {
I(S{})
}
View
@@ -0,0 +1,21 @@
// compile
// Copyright 2016 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.
package y
type symSet []int
//go:noinline
func (s symSet) len() (r int) {
return 0
}
func f(m map[int]symSet) {
var symSet []int
for _, x := range symSet {
m[x] = nil
}
}
View
@@ -0,0 +1,36 @@
// run
// Copyright 2016 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.
package main
var fail bool
type Closer interface {
Close()
}
func nilInterfaceDeferCall() {
var x Closer
defer x.Close()
// if it panics when evaluating x.Close, it should not reach here
fail = true
}
func shouldPanic(f func()) {
defer func() {
if recover() == nil {
panic("did not panic")
}
}()
f()
}
func main() {
shouldPanic(nilInterfaceDeferCall)
if fail {
panic("fail")
}
}
View
@@ -0,0 +1,14 @@
// compile
// Copyright 2016 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.
package p
func f(p, q []int) {
p = append(q, 5)
sink = &p
}
var sink *[]int
View
@@ -0,0 +1,52 @@
// errorcheck -0 -race
package foo
const benchmarkNumNodes = 10000
func BenchmarkUpdateNodeTransaction(b B) {
s, nodeIDs := setupNodes(benchmarkNumNodes)
b.ResetTimer()
for i := 0; i < b.N(); i++ {
_ = s.Update(func(tx1 Tx) error {
_ = UpdateNode(tx1, &Node{
ID: nodeIDs[i%benchmarkNumNodes],
})
return nil
})
}
}
type B interface {
ResetTimer()
N() int
}
type Tx interface {
}
type Node struct {
ID string
}
type MemoryStore struct {
}
// go:noinline
func setupNodes(n int) (s *MemoryStore, nodeIDs []string) {
return
}
//go:noinline
func (s *MemoryStore) Update(cb func(Tx) error) error {
return nil
}
var sink interface{}
//go:noinline
func UpdateNode(tx Tx, n *Node) error {
sink = tx
sink = n
return nil
}
View
@@ -0,0 +1,35 @@
// run
// Copyright 2016 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.
package main
import "time"
type T struct{}
func (*T) Foo(vals []interface{}) {
switch v := vals[0].(type) {
case string:
_ = v
}
}
type R struct{ *T }
type Q interface {
Foo([]interface{})
}
func main() {
var q Q = &R{&T{}}
for i := 0; i < 10000; i++ {
go func() {
defer q.Foo([]interface{}{"meow"})
time.Sleep(100 * time.Millisecond)
}()
}
time.Sleep(1 * time.Second)
}
View
@@ -0,0 +1,70 @@
// +build !nacl,!android
// run
// Copyright 2016 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.
package main
import (
"bytes"
"fmt"
"html/template"
"io/ioutil"
"log"
"os"
"os/exec"
"path/filepath"
)
var tmpl = template.Must(template.New("main").Parse(`
package main
type T struct {
{{range .Names}}
{{.Name}} *string
{{end}}
}
{{range .Names}}
func (t *T) Get{{.Name}}() string {
if t.{{.Name}} == nil {
return ""
}
return *t.{{.Name}}
}
{{end}}
func main() {}
`))
func main() {
const n = 5000
type Name struct{ Name string }
var t struct{ Names []Name }
for i := 0; i < n; i++ {
t.Names = append(t.Names, Name{Name: fmt.Sprintf("H%06X", i)})
}
buf := new(bytes.Buffer)
if err := tmpl.Execute(buf, t); err != nil {
log.Fatal(err)
}
dir, err := ioutil.TempDir("", "issue16037-")
if err != nil {
log.Fatal(err)
}
defer os.RemoveAll(dir)
path := filepath.Join(dir, "ridiculous_number_of_fields.go")
if err := ioutil.WriteFile(path, buf.Bytes(), 0664); err != nil {
log.Fatal(err)
}
out, err := exec.Command("go", "build", "-o="+filepath.Join(dir, "out"), path).CombinedOutput()
if err != nil {
log.Fatalf("build failed: %v\n%s", err, out)
}
}