View
@@ -6,14 +6,19 @@ package tls
import (
"bytes"
"crypto/x509"
"errors"
"fmt"
"internal/testenv"
"io"
"math"
"math/rand"
"net"
"os"
"reflect"
"strings"
"testing"
"testing/quick"
"time"
)
@@ -236,8 +241,8 @@ func testConnReadNonzeroAndEOF(t *testing.T, delay time.Duration) error {
srvCh <- nil
return
}
serverConfig := *testConfig
srv := Server(sconn, &serverConfig)
serverConfig := testConfig.clone()
srv := Server(sconn, serverConfig)
if err := srv.Handshake(); err != nil {
serr = fmt.Errorf("handshake: %v", err)
srvCh <- nil
@@ -246,8 +251,8 @@ func testConnReadNonzeroAndEOF(t *testing.T, delay time.Duration) error {
srvCh <- srv
}()
clientConfig := *testConfig
conn, err := Dial("tcp", ln.Addr().String(), &clientConfig)
clientConfig := testConfig.clone()
conn, err := Dial("tcp", ln.Addr().String(), clientConfig)
if err != nil {
t.Fatal(err)
}
@@ -290,18 +295,18 @@ func TestTLSUniqueMatches(t *testing.T) {
if err != nil {
t.Fatal(err)
}
serverConfig := *testConfig
srv := Server(sconn, &serverConfig)
serverConfig := testConfig.clone()
srv := Server(sconn, serverConfig)
if err := srv.Handshake(); err != nil {
t.Fatal(err)
}
serverTLSUniques <- srv.ConnectionState().TLSUnique
}
}()
clientConfig := *testConfig
clientConfig := testConfig.clone()
clientConfig.ClientSessionCache = NewLRUClientSessionCache(1)
conn, err := Dial("tcp", ln.Addr().String(), &clientConfig)
conn, err := Dial("tcp", ln.Addr().String(), clientConfig)
if err != nil {
t.Fatal(err)
}
@@ -310,7 +315,7 @@ func TestTLSUniqueMatches(t *testing.T) {
}
conn.Close()
conn, err = Dial("tcp", ln.Addr().String(), &clientConfig)
conn, err = Dial("tcp", ln.Addr().String(), clientConfig)
if err != nil {
t.Fatal(err)
}
@@ -389,8 +394,8 @@ func TestConnCloseBreakingWrite(t *testing.T) {
srvCh <- nil
return
}
serverConfig := *testConfig
srv := Server(sconn, &serverConfig)
serverConfig := testConfig.clone()
srv := Server(sconn, serverConfig)
if err := srv.Handshake(); err != nil {
serr = fmt.Errorf("handshake: %v", err)
srvCh <- nil
@@ -409,8 +414,8 @@ func TestConnCloseBreakingWrite(t *testing.T) {
Conn: cconn,
}
clientConfig := *testConfig
tconn := Client(conn, &clientConfig)
clientConfig := testConfig.clone()
tconn := Client(conn, clientConfig)
if err := tconn.Handshake(); err != nil {
t.Fatal(err)
}
@@ -453,6 +458,58 @@ func TestConnCloseBreakingWrite(t *testing.T) {
}
}
func TestClone(t *testing.T) {
var c1 Config
v := reflect.ValueOf(&c1).Elem()
rnd := rand.New(rand.NewSource(time.Now().Unix()))
typ := v.Type()
for i := 0; i < typ.NumField(); i++ {
f := v.Field(i)
if !f.CanSet() {
// unexported field; not cloned.
continue
}
// testing/quick can't handle functions or interfaces.
fn := typ.Field(i).Name
switch fn {
case "Rand":
f.Set(reflect.ValueOf(io.Reader(os.Stdin)))
continue
case "Time", "GetCertificate":
// DeepEqual can't compare functions.
continue
case "Certificates":
f.Set(reflect.ValueOf([]Certificate{
{Certificate: [][]byte{[]byte{'b'}}},
}))
continue
case "NameToCertificate":
f.Set(reflect.ValueOf(map[string]*Certificate{"a": nil}))
continue
case "RootCAs", "ClientCAs":
f.Set(reflect.ValueOf(x509.NewCertPool()))
continue
case "ClientSessionCache":
f.Set(reflect.ValueOf(NewLRUClientSessionCache(10)))
continue
}
q, ok := quick.Value(f.Type(), rnd)
if !ok {
t.Fatalf("quick.Value failed on field %s", fn)
}
f.Set(q)
}
c2 := c1.clone()
if !reflect.DeepEqual(&c1, c2) {
t.Errorf("clone failed to copy a field")
}
}
// changeImplConn is a net.Conn which can change its Write and Close
// methods.
type changeImplConn struct {
@@ -481,32 +538,39 @@ func throughput(b *testing.B, totalBytes int64, dynamicRecordSizingDisabled bool
N := b.N
// Less than 64KB because Windows appears to use a TCP rwin < 64KB.
// See Issue #15899.
const bufsize = 32 << 10
go func() {
buf := make([]byte, bufsize)
for i := 0; i < N; i++ {
sconn, err := ln.Accept()
if err != nil {
// panic rather than synchronize to avoid benchmark overhead
// (cannot call b.Fatal in goroutine)
panic(fmt.Errorf("accept: %v", err))
}
serverConfig := *testConfig
serverConfig := testConfig.clone()
serverConfig.DynamicRecordSizingDisabled = dynamicRecordSizingDisabled
srv := Server(sconn, &serverConfig)
srv := Server(sconn, serverConfig)
if err := srv.Handshake(); err != nil {
panic(fmt.Errorf("handshake: %v", err))
}
io.Copy(srv, srv)
if _, err := io.CopyBuffer(srv, srv, buf); err != nil {
panic(fmt.Errorf("copy buffer: %v", err))
}
}
}()
b.SetBytes(totalBytes)
clientConfig := *testConfig
clientConfig := testConfig.clone()
clientConfig.DynamicRecordSizingDisabled = dynamicRecordSizingDisabled
buf := make([]byte, 1<<14)
buf := make([]byte, bufsize)
chunks := int(math.Ceil(float64(totalBytes) / float64(len(buf))))
for i := 0; i < N; i++ {
conn, err := Dial("tcp", ln.Addr().String(), &clientConfig)
conn, err := Dial("tcp", ln.Addr().String(), clientConfig)
if err != nil {
b.Fatal(err)
}
@@ -577,24 +641,24 @@ func latency(b *testing.B, bps int, dynamicRecordSizingDisabled bool) {
// (cannot call b.Fatal in goroutine)
panic(fmt.Errorf("accept: %v", err))
}
serverConfig := *testConfig
serverConfig := testConfig.clone()
serverConfig.DynamicRecordSizingDisabled = dynamicRecordSizingDisabled
srv := Server(&slowConn{sconn, bps}, &serverConfig)
srv := Server(&slowConn{sconn, bps}, serverConfig)
if err := srv.Handshake(); err != nil {
panic(fmt.Errorf("handshake: %v", err))
}
io.Copy(srv, srv)
}
}()
clientConfig := *testConfig
clientConfig := testConfig.clone()
clientConfig.DynamicRecordSizingDisabled = dynamicRecordSizingDisabled
buf := make([]byte, 16384)
peek := make([]byte, 1)
for i := 0; i < N; i++ {
conn, err := Dial("tcp", ln.Addr().String(), &clientConfig)
conn, err := Dial("tcp", ln.Addr().String(), clientConfig)
if err != nil {
b.Fatal(err)
}
View
@@ -718,6 +718,9 @@ func (db *DB) maybeOpenNewConnections() {
for numRequests > 0 {
db.numOpen++ // optimistically
numRequests--
if db.closed {
return
}
db.openerCh <- struct{}{}
}
}
@@ -915,6 +918,9 @@ func (db *DB) putConn(dc *driverConn, err error) {
// If a connRequest was fulfilled or the *driverConn was placed in the
// freeConn list, then true is returned, otherwise false is returned.
func (db *DB) putConnDBLocked(dc *driverConn, err error) bool {
if db.closed {
return false
}
if db.maxOpen > 0 && db.numOpen > db.maxOpen {
return false
}
View
@@ -144,7 +144,7 @@ func closeDB(t testing.TB, db *DB) {
count := db.numOpen
db.mu.Unlock()
if count != 0 {
t.Fatalf("%d connections still open after closing DB", db.numOpen)
t.Fatalf("%d connections still open after closing DB", count)
}
}
@@ -1239,7 +1239,7 @@ func TestPendingConnsAfterErr(t *testing.T) {
time.Sleep(10 * time.Millisecond) // make extra sure all workers are blocked
close(unblock) // let all workers proceed
const timeout = 100 * time.Millisecond
const timeout = 5 * time.Second
to := time.NewTimer(timeout)
defer to.Stop()
@@ -1615,6 +1615,8 @@ func TestManyErrBadConn(t *testing.T) {
}
}()
db.mu.Lock()
defer db.mu.Unlock()
if db.numOpen != nconn {
t.Fatalf("unexpected numOpen %d (was expecting %d)", db.numOpen, nconn)
} else if len(db.freeConn) != nconn {
View
@@ -104,6 +104,41 @@ var fileTests = []fileTest{
{".debug_loc", 0x38, 0xf000, 0x200, 0x3a00, 0x0, 0x0, 0x0, 0x0, 0x42100000},
},
},
{
file: "testdata/gcc-386-mingw-no-symbols-exec",
hdr: FileHeader{0x14c, 0x8, 0x69676572, 0x0, 0x0, 0xe0, 0x30f},
opthdr: &OptionalHeader32{0x10b, 0x2, 0x18, 0xe00, 0x1e00, 0x200, 0x1280, 0x1000, 0x2000, 0x400000, 0x1000, 0x200, 0x4, 0x0, 0x1, 0x0, 0x4, 0x0, 0x0, 0x9000, 0x400, 0x5306, 0x3, 0x0, 0x200000, 0x1000, 0x100000, 0x1000, 0x0, 0x10,
[16]DataDirectory{
{0x0, 0x0},
{0x6000, 0x378},
{0x0, 0x0},
{0x0, 0x0},
{0x0, 0x0},
{0x0, 0x0},
{0x0, 0x0},
{0x0, 0x0},
{0x0, 0x0},
{0x8004, 0x18},
{0x0, 0x0},
{0x0, 0x0},
{0x60b8, 0x7c},
{0x0, 0x0},
{0x0, 0x0},
{0x0, 0x0},
},
},
sections: []*SectionHeader{
{".text", 0xc64, 0x1000, 0xe00, 0x400, 0x0, 0x0, 0x0, 0x0, 0x60500060},
{".data", 0x10, 0x2000, 0x200, 0x1200, 0x0, 0x0, 0x0, 0x0, 0xc0300040},
{".rdata", 0x134, 0x3000, 0x200, 0x1400, 0x0, 0x0, 0x0, 0x0, 0x40300040},
{".eh_fram", 0x3a0, 0x4000, 0x400, 0x1600, 0x0, 0x0, 0x0, 0x0, 0x40300040},
{".bss", 0x60, 0x5000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc0300080},
{".idata", 0x378, 0x6000, 0x400, 0x1a00, 0x0, 0x0, 0x0, 0x0, 0xc0300040},
{".CRT", 0x18, 0x7000, 0x200, 0x1e00, 0x0, 0x0, 0x0, 0x0, 0xc0300040},
{".tls", 0x20, 0x8000, 0x200, 0x2000, 0x0, 0x0, 0x0, 0x0, 0xc0300040},
},
hasNoDwarfInfo: true,
},
{
file: "testdata/gcc-amd64-mingw-obj",
hdr: FileHeader{0x8664, 0x6, 0x0, 0x198, 0x12, 0x0, 0x4},
View
@@ -24,6 +24,9 @@ type _StringTable []byte
func readStringTable(fh *FileHeader, r io.ReadSeeker) (_StringTable, error) {
// COFF string table is located right after COFF symbol table.
if fh.PointerToSymbolTable <= 0 {
return nil, nil
}
offset := fh.PointerToSymbolTable + COFFSymbolSize*fh.NumberOfSymbols
_, err := r.Seek(int64(offset), io.SeekStart)
if err != nil {
View
Binary file not shown.
View
@@ -645,10 +645,10 @@ func (dec *Decoder) decodeInterface(ityp reflect.Type, state *decoderState, valu
errorf("invalid type name length %d: exceeds input size", nr)
}
n := int(nr)
name := string(state.b.Bytes()[:n])
name := state.b.Bytes()[:n]
state.b.Drop(n)
// Allocate the destination interface value.
if name == "" {
if len(name) == 0 {
// Copy the nil interface value to the target.
value.Set(reflect.Zero(value.Type()))
return
@@ -658,7 +658,7 @@ func (dec *Decoder) decodeInterface(ityp reflect.Type, state *decoderState, valu
}
// The concrete type must be registered.
registerLock.RLock()
typ, ok := nameToConcreteType[name]
typ, ok := nameToConcreteType[string(name)]
registerLock.RUnlock()
if !ok {
errorf("name not registered for interface: %q", name)
View
@@ -17,7 +17,8 @@ Basics
A stream of gobs is self-describing. Each data item in the stream is preceded by
a specification of its type, expressed in terms of a small set of predefined
types. Pointers are not transmitted, but the things they point to are
transmitted; that is, the values are flattened. Recursive types work fine, but
transmitted; that is, the values are flattened. Nil pointers are not permitted,
as they have no value. Recursive types work fine, but
recursive values (data with cycles) are problematic. This may change.
To use gobs, create an Encoder and present it with a series of data items as
View
@@ -170,6 +170,7 @@ func (enc *Encoder) sendType(w io.Writer, state *encoderState, origt reflect.Typ
// Encode transmits the data item represented by the empty interface value,
// guaranteeing that all necessary type information has been transmitted first.
// Passing a nil pointer to Encoder will panic, as they cannot be transmitted by gob.
func (enc *Encoder) Encode(e interface{}) error {
return enc.EncodeValue(reflect.ValueOf(e))
}
@@ -212,9 +213,8 @@ func (enc *Encoder) sendTypeId(state *encoderState, ut *userTypeInfo) {
// EncodeValue transmits the data item represented by the reflection value,
// guaranteeing that all necessary type information has been transmitted first.
// Passing a nil pointer to EncodeValue will panic, as they cannot be transmitted by gob.
func (enc *Encoder) EncodeValue(value reflect.Value) error {
// Gobs contain values. They cannot represent nil pointers, which
// have no value to encode.
if value.Kind() == reflect.Ptr && value.IsNil() {
panic("gob: cannot encode nil pointer of type " + value.Type().String())
}
View
@@ -8,6 +8,7 @@ import (
"bytes"
"encoding/hex"
"fmt"
"io/ioutil"
"reflect"
"strings"
"testing"
@@ -831,30 +832,81 @@ func TestPtrToMapOfMap(t *testing.T) {
// A top-level nil pointer generates a panic with a helpful string-valued message.
func TestTopLevelNilPointer(t *testing.T) {
errMsg := topLevelNilPanic(t)
if errMsg == "" {
var ip *int
encodeErr, panicErr := encodeAndRecover(ip)
if encodeErr != nil {
t.Fatal("error in encode:", encodeErr)
}
if panicErr == nil {
t.Fatal("top-level nil pointer did not panic")
}
errMsg := panicErr.Error()
if !strings.Contains(errMsg, "nil pointer") {
t.Fatal("expected nil pointer error, got:", errMsg)
}
}
func topLevelNilPanic(t *testing.T) (panicErr string) {
func encodeAndRecover(value interface{}) (encodeErr, panicErr error) {
defer func() {
e := recover()
if err, ok := e.(string); ok {
panicErr = err
if e != nil {
switch err := e.(type) {
case error:
panicErr = err
default:
panicErr = fmt.Errorf("%v", err)
}
}
}()
var ip *int
buf := new(bytes.Buffer)
if err := NewEncoder(buf).Encode(ip); err != nil {
t.Fatal("error in encode:", err)
}
encodeErr = NewEncoder(ioutil.Discard).Encode(value)
return
}
func TestNilPointerPanics(t *testing.T) {
var (
nilStringPtr *string
intMap = make(map[int]int)
intMapPtr = &intMap
nilIntMapPtr *map[int]int
zero int
nilBoolChannel chan bool
nilBoolChannelPtr *chan bool
nilStringSlice []string
stringSlice = make([]string, 1)
nilStringSlicePtr *[]string
)
testCases := []struct {
value interface{}
mustPanic bool
}{
{nilStringPtr, true},
{intMap, false},
{intMapPtr, false},
{nilIntMapPtr, true},
{zero, false},
{nilStringSlice, false},
{stringSlice, false},
{nilStringSlicePtr, true},
{nilBoolChannel, false},
{nilBoolChannelPtr, true},
}
for _, tt := range testCases {
_, panicErr := encodeAndRecover(tt.value)
if tt.mustPanic {
if panicErr == nil {
t.Errorf("expected panic with input %#v, did not panic", tt.value)
}
continue
}
if panicErr != nil {
t.Fatalf("expected no panic with input %#v, got panic=%v", tt.value, panicErr)
}
}
}
func TestNilPointerInsideInterface(t *testing.T) {
var ip *int
si := struct {
View
@@ -22,6 +22,7 @@ import (
"strconv"
"strings"
"sync"
"sync/atomic"
"unicode"
"unicode/utf8"
)
@@ -1231,15 +1232,14 @@ func dominantField(fields []field) (field, bool) {
}
var fieldCache struct {
sync.RWMutex
m map[reflect.Type][]field
value atomic.Value // map[reflect.Type][]field
mu sync.Mutex // used only by writers
}
// cachedTypeFields is like typeFields but uses a cache to avoid repeated work.
func cachedTypeFields(t reflect.Type) []field {
fieldCache.RLock()
f := fieldCache.m[t]
fieldCache.RUnlock()
m, _ := fieldCache.value.Load().(map[reflect.Type][]field)
f := m[t]
if f != nil {
return f
}
@@ -1251,11 +1251,14 @@ func cachedTypeFields(t reflect.Type) []field {
f = []field{}
}
fieldCache.Lock()
if fieldCache.m == nil {
fieldCache.m = map[reflect.Type][]field{}
fieldCache.mu.Lock()
m, _ = fieldCache.value.Load().(map[reflect.Type][]field)
newM := make(map[reflect.Type][]field, len(m)+1)
for k, v := range m {
newM[k] = v
}
fieldCache.m[t] = f
fieldCache.Unlock()
newM[t] = f
fieldCache.value.Store(newM)
fieldCache.mu.Unlock()
return f
}
View
@@ -33,7 +33,7 @@ const (
//
// The name for the XML elements is taken from, in order of preference:
// - the tag on the XMLName field, if the data is a struct
// - the value of the XMLName field of type xml.Name
// - the value of the XMLName field of type Name
// - the tag of the struct field used to obtain the data
// - the name of the struct field used to obtain the data
// - the name of the marshalled type
View
@@ -39,7 +39,7 @@ import (
// ",innerxml", Unmarshal accumulates the raw XML nested inside the
// element in that field. The rest of the rules still apply.
//
// * If the struct has a field named XMLName of type xml.Name,
// * If the struct has a field named XMLName of type Name,
// Unmarshal records the element name in that field.
//
// * If the XMLName field has an associated tag of the form
@@ -105,8 +105,8 @@ import (
// interpreting the string value in decimal. There is no check for
// overflow.
//
// Unmarshal maps an XML element to an xml.Name by recording the
// element name.
// Unmarshal maps an XML element to a Name by recording the element
// name.
//
// Unmarshal maps an XML element to a pointer by setting the pointer
// to a freshly allocated value and then mapping the element to that value.
@@ -115,13 +115,13 @@ func Unmarshal(data []byte, v interface{}) error {
return NewDecoder(bytes.NewReader(data)).Decode(v)
}
// Decode works like xml.Unmarshal, except it reads the decoder
// Decode works like Unmarshal, except it reads the decoder
// stream to find the start element.
func (d *Decoder) Decode(v interface{}) error {
return d.DecodeElement(v, nil)
}
// DecodeElement works like xml.Unmarshal except that it takes
// DecodeElement works like Unmarshal except that it takes
// a pointer to the start XML element to decode into v.
// It is useful when a client reads some raw XML tokens itself
// but also wants to defer to Unmarshal for some elements.
View
@@ -244,6 +244,7 @@ var stringTests = []struct {
{"1e9999", "1e+9999", "0x.f8d4a9da224650a8cb2959e10d985ad92adbd44c62917e608b1f24c0e1b76b6f61edffeb15c135a4b601637315f7662f325f82325422b244286a07663c9415d2p+33216"},
{"1e-9999", "1e-9999", "0x.83b01ba6d8c0425eec1b21e96f7742d63c2653ed0a024cf8a2f9686df578d7b07d7a83d84df6a2ec70a921d1f6cd5574893a7eda4d28ee719e13a5dce2700759p-33215"},
{"2.71828182845904523536028747135266249775724709369995957496696763", "2.71828", "271828182845904523536028747135266249775724709369995957496696763/100000000000000000000000000000000000000000000000000000000000000"},
{"0e9999999999", "0", "0"}, // issue #16176
// Complex
{"0i", "(0 + 0i)", "(0 + 0i)"},
View
@@ -21,6 +21,7 @@ type importer struct {
data []byte
path string
buf []byte // for reading strings
version string
// object lists
strList []string // in order of appearance
@@ -66,8 +67,9 @@ func BImportData(imports map[string]*types.Package, data []byte, path string) (i
// --- generic export data ---
if v := p.string(); v != "v0" {
return p.read, nil, fmt.Errorf("unknown export data version: %s", v)
p.version = p.string()
if p.version != "v0" && p.version != "v1" {
return p.read, nil, fmt.Errorf("unknown export data version: %s", p.version)
}
// populate typList with predeclared "known" types
@@ -304,6 +306,10 @@ func (p *importer) typ(parent *types.Package) types.Type {
params, isddd := p.paramList()
result, _ := p.paramList()
if p.version == "v1" {
p.int() // nointerface flag - discarded
}
sig := types.NewSignature(recv.At(0), params, result, isddd)
t0.AddMethod(types.NewFunc(token.NoPos, parent, name, sig))
}
View
@@ -166,7 +166,7 @@ that would have been produced if {{.}} was a regular string.
Security Model
http://js-quasis-libraries-and-repl.googlecode.com/svn/trunk/safetemplate.html#problem_definition defines "safe" as used by this package.
https://rawgit.com/mikesamuel/sanitized-jquery-templates/trunk/safetemplate.html#problem_definition defines "safe" as used by this package.
This package assumes that template authors are trusted, that Execute's data
parameter is not, and seeks to preserve the properties below in the face
View
@@ -88,6 +88,12 @@ func (z *Rat) SetString(s string) (*Rat, bool) {
return nil, false
}
// special-case 0 (see also issue #16176)
if len(z.a.abs) == 0 {
return z, true
}
// len(z.a.abs) > 0
// correct exponent
if ecorr < 0 {
exp += int64(ecorr)
View
@@ -48,6 +48,7 @@ var setStringTests = []StringTest{
{"53/70893980658822810696", "53/70893980658822810696", true},
{"106/141787961317645621392", "53/70893980658822810696", true},
{"204211327800791583.81095", "4084226556015831676219/20000", true},
{"0e9999999999", "0", true}, // issue #16176
{in: "1/0"},
}
View
@@ -33,14 +33,26 @@ func NewSource(seed int64) Source {
// A Rand is a source of random numbers.
type Rand struct {
src Source
// readVal contains remainder of 63-bit integer used for bytes
// generation during most recent Read call.
// It is saved so next Read call can start where the previous
// one finished.
readVal int64
// readPos indicates the number of low-order bytes of readVal
// that are still valid.
readPos int8
}
// New returns a new Rand that uses random values from src
// to generate other random values.
func New(src Source) *Rand { return &Rand{src} }
func New(src Source) *Rand { return &Rand{src: src} }
// Seed uses the provided seed value to initialize the generator to a deterministic state.
func (r *Rand) Seed(seed int64) { r.src.Seed(seed) }
func (r *Rand) Seed(seed int64) {
r.src.Seed(seed)
r.readPos = 0
}
// Int63 returns a non-negative pseudo-random 63-bit integer as an int64.
func (r *Rand) Int63() int64 { return r.src.Int63() }
@@ -161,14 +173,20 @@ func (r *Rand) Perm(n int) []int {
// Read generates len(p) random bytes and writes them into p. It
// always returns len(p) and a nil error.
func (r *Rand) Read(p []byte) (n int, err error) {
for i := 0; i < len(p); i += 7 {
val := r.src.Int63()
for j := 0; i+j < len(p) && j < 7; j++ {
p[i+j] = byte(val)
val >>= 8
pos := r.readPos
val := r.readVal
for n = 0; n < len(p); n++ {
if pos == 0 {
val = r.Int63()
pos = 7
}
p[n] = byte(val)
val >>= 8
pos--
}
return len(p), nil
r.readPos = pos
r.readVal = val
return
}
/*
@@ -179,8 +197,8 @@ var globalRand = New(&lockedSource{src: NewSource(1)})
// Seed uses the provided seed value to initialize the default Source to a
// deterministic state. If Seed is not called, the generator behaves as
// if seeded by Seed(1). Only uses the bottom 31 bits of seed; the top 33
// bits are ignored.
// if seeded by Seed(1). Seed values that have the same remainder when
// divided by 2^31-1 generate the same pseudo-random sequence.
func Seed(seed int64) { globalRand.Seed(seed) }
// Int63 returns a non-negative pseudo-random 63-bit integer as an int64
View
@@ -5,13 +5,16 @@
package rand
import (
"bytes"
"errors"
"fmt"
"internal/testenv"
"io"
"math"
"os"
"runtime"
"testing"
"testing/iotest"
)
const (
@@ -373,7 +376,7 @@ func testReadUniformity(t *testing.T, n int, seed int64) {
checkSampleDistribution(t, samples, expected)
}
func TestRead(t *testing.T) {
func TestReadUniformity(t *testing.T) {
testBufferSizes := []int{
2, 4, 7, 64, 1024, 1 << 16, 1 << 20,
}
@@ -394,7 +397,42 @@ func TestReadEmpty(t *testing.T) {
if n != 0 {
t.Errorf("Read into empty buffer returned unexpected n of %d", n)
}
}
func TestReadByOneByte(t *testing.T) {
r := New(NewSource(1))
b1 := make([]byte, 100)
_, err := io.ReadFull(iotest.OneByteReader(r), b1)
if err != nil {
t.Errorf("read by one byte: %v", err)
}
r = New(NewSource(1))
b2 := make([]byte, 100)
_, err = r.Read(b2)
if err != nil {
t.Errorf("read: %v", err)
}
if !bytes.Equal(b1, b2) {
t.Errorf("read by one byte vs single read:\n%x\n%x", b1, b2)
}
}
func TestReadSeedReset(t *testing.T) {
r := New(NewSource(42))
b1 := make([]byte, 128)
_, err := r.Read(b1)
if err != nil {
t.Errorf("read: %v", err)
}
r.Seed(42)
b2 := make([]byte, 128)
_, err = r.Read(b2)
if err != nil {
t.Errorf("read: %v", err)
}
if !bytes.Equal(b1, b2) {
t.Errorf("mismatch after re-seed:\n%x\n%x", b1, b2)
}
}
// Benchmarks
View
@@ -342,25 +342,25 @@ var regressGolden = []interface{}{
[]int{8, 7, 5, 3, 4, 6, 0, 1, 2}, // Perm(9)
[]int{1, 0, 2, 5, 7, 6, 9, 8, 3, 4}, // Perm(10)
[]byte{0x1}, // Read([0])
[]byte{0xc0, 0x41, 0xd3, 0xff, 0x12, 0x4, 0x5b}, // Read([0 0 0 0 0 0 0])
[]byte{0x73, 0xc8, 0x6e, 0x4f, 0xf9, 0x5f, 0xf6, 0x62}, // Read([0 0 0 0 0 0 0 0])
[]byte{0x4a, 0x2d, 0xb, 0x75, 0xfb, 0x18, 0xd, 0xaf, 0x48}, // Read([0 0 0 0 0 0 0 0 0])
[]byte{0x39, 0x46, 0x51, 0x85, 0xf, 0xd4, 0xa1, 0x78, 0x89, 0x2e}, // Read([0 0 0 0 0 0 0 0 0 0])
[]byte{0x51}, // Read([0])
[]byte{0x4e, 0xe2, 0xd3, 0xd0, 0xd0, 0xde, 0x6b}, // Read([0 0 0 0 0 0 0])
[]byte{0xf8, 0xf9, 0xb4, 0x4c, 0xe8, 0x5f, 0xf0, 0x44}, // Read([0 0 0 0 0 0 0 0])
[]byte{0x3b, 0xbf, 0x85, 0x7a, 0xab, 0x99, 0xc5, 0xb2, 0x52}, // Read([0 0 0 0 0 0 0 0 0])
[]byte{0xa8, 0xae, 0xb7, 0x9e, 0xf8, 0x56, 0xf6, 0x59, 0xc1, 0x8f}, // Read([0 0 0 0 0 0 0 0 0 0])
[]byte{0xc7}, // Read([0])
[]byte{0x5f, 0x67, 0xcf, 0xe2, 0x42, 0xcf, 0x3c}, // Read([0 0 0 0 0 0 0])
[]byte{0xc3, 0x54, 0xf3, 0xed, 0xe2, 0xd6, 0xbe, 0xcc}, // Read([0 0 0 0 0 0 0 0])
[]byte{0x6a, 0x9f, 0x4a, 0x57, 0x8b, 0xcb, 0x9e, 0xf2, 0xd4}, // Read([0 0 0 0 0 0 0 0 0])
[]byte{0x6d, 0x29, 0x97, 0x61, 0xea, 0x9e, 0x4f, 0x5a, 0xa6, 0xae}, // Read([0 0 0 0 0 0 0 0 0 0])
[]byte{0xaa}, // Read([0])
[]byte{0x20, 0xef, 0xcd, 0x6c, 0xea, 0x84, 0xb6}, // Read([0 0 0 0 0 0 0])
[]byte{0x92, 0x5e, 0x60, 0x7b, 0xe0, 0x63, 0x71, 0x6f}, // Read([0 0 0 0 0 0 0 0])
[]byte{0x4, 0x5c, 0x3f, 0x0, 0xf, 0x8a, 0x79, 0x6b, 0xce}, // Read([0 0 0 0 0 0 0 0 0])
[]byte{0xaa, 0xca, 0xee, 0xdf, 0xad, 0x5b, 0x50, 0x66, 0x64, 0xe8}, // Read([0 0 0 0 0 0 0 0 0 0])
[]byte{0x94, 0xfd, 0xc2, 0xfa, 0x2f, 0xfc, 0xc0}, // Read([0 0 0 0 0 0 0])
[]byte{0x41, 0xd3, 0xff, 0x12, 0x4, 0x5b, 0x73, 0xc8}, // Read([0 0 0 0 0 0 0 0])
[]byte{0x6e, 0x4f, 0xf9, 0x5f, 0xf6, 0x62, 0xa5, 0xee, 0xe8}, // Read([0 0 0 0 0 0 0 0 0])
[]byte{0x2a, 0xbd, 0xf4, 0x4a, 0x2d, 0xb, 0x75, 0xfb, 0x18, 0xd}, // Read([0 0 0 0 0 0 0 0 0 0])
[]byte{0xaf}, // Read([0])
[]byte{0x48, 0xa7, 0x9e, 0xe0, 0xb1, 0xd, 0x39}, // Read([0 0 0 0 0 0 0])
[]byte{0x46, 0x51, 0x85, 0xf, 0xd4, 0xa1, 0x78, 0x89}, // Read([0 0 0 0 0 0 0 0])
[]byte{0x2e, 0xe2, 0x85, 0xec, 0xe1, 0x51, 0x14, 0x55, 0x78}, // Read([0 0 0 0 0 0 0 0 0])
[]byte{0x8, 0x75, 0xd6, 0x4e, 0xe2, 0xd3, 0xd0, 0xd0, 0xde, 0x6b}, // Read([0 0 0 0 0 0 0 0 0 0])
[]byte{0xf8}, // Read([0])
[]byte{0xf9, 0xb4, 0x4c, 0xe8, 0x5f, 0xf0, 0x44}, // Read([0 0 0 0 0 0 0])
[]byte{0xc6, 0xb1, 0xf8, 0x3b, 0x8e, 0x88, 0x3b, 0xbf}, // Read([0 0 0 0 0 0 0 0])
[]byte{0x85, 0x7a, 0xab, 0x99, 0xc5, 0xb2, 0x52, 0xc7, 0x42}, // Read([0 0 0 0 0 0 0 0 0])
[]byte{0x9c, 0x32, 0xf3, 0xa8, 0xae, 0xb7, 0x9e, 0xf8, 0x56, 0xf6}, // Read([0 0 0 0 0 0 0 0 0 0])
[]byte{0x59}, // Read([0])
[]byte{0xc1, 0x8f, 0xd, 0xce, 0xcc, 0x77, 0xc7}, // Read([0 0 0 0 0 0 0])
[]byte{0x5e, 0x7a, 0x81, 0xbf, 0xde, 0x27, 0x5f, 0x67}, // Read([0 0 0 0 0 0 0 0])
[]byte{0xcf, 0xe2, 0x42, 0xcf, 0x3c, 0xc3, 0x54, 0xf3, 0xed}, // Read([0 0 0 0 0 0 0 0 0])
[]byte{0xe2, 0xd6, 0xbe, 0xcc, 0x4e, 0xa3, 0xae, 0x5e, 0x88, 0x52}, // Read([0 0 0 0 0 0 0 0 0 0])
uint32(4059586549), // Uint32()
uint32(1052117029), // Uint32()
uint32(2817310706), // Uint32()
View

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

Oops, something went wrong.
View
@@ -17,11 +17,7 @@ func ExampleResponseRecorder() {
http.Error(w, "something failed", http.StatusInternalServerError)
}
req, err := http.NewRequest("GET", "http://example.com/foo", nil)
if err != nil {
log.Fatal(err)
}
req := httptest.NewRequest("GET", "http://example.com/foo", nil)
w := httptest.NewRecorder()
handler(w, req)
View
@@ -4,8 +4,6 @@
// Package pprof serves via its HTTP server runtime profiling data
// in the format expected by the pprof visualization tool.
// For more information about pprof, see
// http://code.google.com/p/google-perftools/.
//
// The package is typically only imported for the side effect of
// registering its HTTP handlers.
View
@@ -213,7 +213,7 @@ func (r *Response) ProtoAtLeast(major, minor int) bool {
r.ProtoMajor == major && r.ProtoMinor >= minor
}
// Write writes r to w in the HTTP/1.n server response format,
// Write writes r to w in the HTTP/1.x server response format,
// including the status line, headers, body, and optional trailer.
//
// This method consults the following fields of the response r:
View
@@ -1107,11 +1107,44 @@ func TestTLSServer(t *testing.T) {
})
}
func TestAutomaticHTTP2_Serve(t *testing.T) {
// Issue 15908
func TestAutomaticHTTP2_Serve_NoTLSConfig(t *testing.T) {
testAutomaticHTTP2_Serve(t, nil, true)
}
func TestAutomaticHTTP2_Serve_NonH2TLSConfig(t *testing.T) {
testAutomaticHTTP2_Serve(t, &tls.Config{}, false)
}
func TestAutomaticHTTP2_Serve_H2TLSConfig(t *testing.T) {
testAutomaticHTTP2_Serve(t, &tls.Config{NextProtos: []string{"h2"}}, true)
}
func testAutomaticHTTP2_Serve(t *testing.T, tlsConf *tls.Config, wantH2 bool) {
defer afterTest(t)
ln := newLocalListener(t)
ln.Close() // immediately (not a defer!)
var s Server
s.TLSConfig = tlsConf
if err := s.Serve(ln); err == nil {
t.Fatal("expected an error")
}
gotH2 := s.TLSNextProto["h2"] != nil
if gotH2 != wantH2 {
t.Errorf("http2 configured = %v; want %v", gotH2, wantH2)
}
}
func TestAutomaticHTTP2_Serve_WithTLSConfig(t *testing.T) {
defer afterTest(t)
ln := newLocalListener(t)
ln.Close() // immediately (not a defer!)
var s Server
// Set the TLSConfig. In reality, this would be the
// *tls.Config given to tls.NewListener.
s.TLSConfig = &tls.Config{
NextProtos: []string{"h2"},
}
if err := s.Serve(ln); err == nil {
t.Fatal("expected an error")
}
@@ -3958,6 +3991,8 @@ func TestServerValidatesHostHeader(t *testing.T) {
host string
want int
}{
{"HTTP/0.9", "", 400},
{"HTTP/1.1", "", 400},
{"HTTP/1.1", "Host: \r\n", 200},
{"HTTP/1.1", "Host: 1.2.3.4\r\n", 200},
@@ -3983,6 +4018,11 @@ func TestServerValidatesHostHeader(t *testing.T) {
// Make an exception for HTTP upgrade requests:
{"PRI * HTTP/2.0", "", 200},
// But not other HTTP/2 stuff:
{"PRI / HTTP/2.0", "", 400},
{"GET / HTTP/2.0", "", 400},
{"GET / HTTP/3.0", "", 400},
}
for _, tt := range tests {
conn := &testConn{closec: make(chan bool, 1)}
View
@@ -771,6 +771,10 @@ func (c *conn) readRequest(ctx context.Context) (w *response, err error) {
return nil, err
}
if !http1ServerSupportsRequest(req) {
return nil, badRequestError("unsupported protocol version")
}
ctx, cancelCtx := context.WithCancel(ctx)
req.ctx = ctx
@@ -828,6 +832,23 @@ func (c *conn) readRequest(ctx context.Context) (w *response, err error) {
return w, nil
}
// http1ServerSupportsRequest reports whether Go's HTTP/1.x server
// supports the given request.
func http1ServerSupportsRequest(req *Request) bool {
if req.ProtoMajor == 1 {
return true
}
// Accept "PRI * HTTP/2.0" upgrade requests, so Handlers can
// wire up their own HTTP/2 upgrades.
if req.ProtoMajor == 2 && req.ProtoMinor == 0 &&
req.Method == "PRI" && req.RequestURI == "*" {
return true
}
// Reject HTTP/0.x, and all other HTTP/2+ requests (which
// aren't encoded in ASCII anyway).
return false
}
func (w *response) Header() Header {
if w.cw.header == nil && w.wroteHeader && !w.cw.wroteHeader {
// Accessing the header between logically writing it
@@ -2201,19 +2222,51 @@ func (srv *Server) ListenAndServe() error {
var testHookServerServe func(*Server, net.Listener) // used if non-nil
// shouldDoServeHTTP2 reports whether Server.Serve should configure
// automatic HTTP/2. (which sets up the srv.TLSNextProto map)
func (srv *Server) shouldConfigureHTTP2ForServe() bool {
if srv.TLSConfig == nil {
// Compatibility with Go 1.6:
// If there's no TLSConfig, it's possible that the user just
// didn't set it on the http.Server, but did pass it to
// tls.NewListener and passed that listener to Serve.
// So we should configure HTTP/2 (to set up srv.TLSNextProto)
// in case the listener returns an "h2" *tls.Conn.
return true
}
// The user specified a TLSConfig on their http.Server.
// In this, case, only configure HTTP/2 if their tls.Config
// explicitly mentions "h2". Otherwise http2.ConfigureServer
// would modify the tls.Config to add it, but they probably already
// passed this tls.Config to tls.NewListener. And if they did,
// it's too late anyway to fix it. It would only be potentially racy.
// See Issue 15908.
return strSliceContains(srv.TLSConfig.NextProtos, http2NextProtoTLS)
}
// Serve accepts incoming connections on the Listener l, creating a
// new service goroutine for each. The service goroutines read requests and
// then call srv.Handler to reply to them.
//
// For HTTP/2 support, srv.TLSConfig should be initialized to the
// provided listener's TLS Config before calling Serve. If
// srv.TLSConfig is non-nil and doesn't include the string "h2" in
// Config.NextProtos, HTTP/2 support is not enabled.
//
// Serve always returns a non-nil error.
func (srv *Server) Serve(l net.Listener) error {
defer l.Close()
if fn := testHookServerServe; fn != nil {
fn(srv, l)
}
var tempDelay time.Duration // how long to sleep on accept failure
if err := srv.setupHTTP2(); err != nil {
return err
if srv.shouldConfigureHTTP2ForServe() {
if err := srv.setupHTTP2(); err != nil {
return err
}
}
// TODO: allow changing base context? can't imagine concrete
// use cases yet.
baseCtx := context.Background()
View
@@ -845,10 +845,26 @@ func (t *Transport) getConn(treq *transportRequest, cm connectMethod) (*persistC
select {
case v := <-dialc:
// Our dial finished.
if trace != nil && trace.GotConn != nil && v.pc != nil && v.pc.alt == nil {
trace.GotConn(httptrace.GotConnInfo{Conn: v.pc.conn})
if v.pc != nil {
if trace != nil && trace.GotConn != nil && v.pc.alt == nil {
trace.GotConn(httptrace.GotConnInfo{Conn: v.pc.conn})
}
return v.pc, nil
}
return v.pc, v.err
// Our dial failed. See why to return a nicer error
// value.
select {
case <-req.Cancel:
case <-req.Context().Done():
case <-cancelc:
default:
// It wasn't an error due to cancelation, so
// return the original error message:
return nil, v.err
}
// It was an error due to cancelation, so prioritize that
// error value. (Issue 16049)
return nil, errRequestCanceledConn
case pc := <-idleConnCh:
// Another request finished first and its net.Conn
// became available before our dial. Or somebody
View
@@ -111,6 +111,7 @@ type Cmd struct {
closeAfterWait []io.Closer
goroutine []func() error
errch chan error // one send per goroutine
waitDone chan struct{}
}
// Command returns the Cmd struct to execute the named program with
@@ -326,6 +327,15 @@ func (c *Cmd) Start() error {
if c.Process != nil {
return errors.New("exec: already started")
}
if c.ctx != nil {
select {
case <-c.ctx.Done():
c.closeDescriptors(c.closeAfterStart)
c.closeDescriptors(c.closeAfterWait)
return c.ctx.Err()
default:
}
}
type F func(*Cmd) (*os.File, error)
for _, setupFd := range []F{(*Cmd).stdin, (*Cmd).stdout, (*Cmd).stderr} {
@@ -361,6 +371,17 @@ func (c *Cmd) Start() error {
}(fn)
}
if c.ctx != nil {
c.waitDone = make(chan struct{})
go func() {
select {
case <-c.ctx.Done():
c.Process.Kill()
case <-c.waitDone:
}
}()
}
return nil
}
@@ -410,20 +431,9 @@ func (c *Cmd) Wait() error {
}
c.finished = true
var waitDone chan struct{}
if c.ctx != nil {
waitDone = make(chan struct{})
go func() {
select {
case <-c.ctx.Done():
c.Process.Kill()
case <-waitDone:
}
}()
}
state, err := c.Process.Wait()
if waitDone != nil {
close(waitDone)
if c.waitDone != nil {
close(c.waitDone)
}
c.ProcessState = state
View
@@ -878,3 +878,73 @@ func TestContext(t *testing.T) {
t.Fatal("timeout waiting for child process death")
}
}
func TestContextCancel(t *testing.T) {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
c := helperCommandContext(t, ctx, "cat")
r, w, err := os.Pipe()
if err != nil {
t.Fatal(err)
}
c.Stdin = r
stdout, err := c.StdoutPipe()
if err != nil {
t.Fatal(err)
}
readDone := make(chan struct{})
go func() {
defer close(readDone)
var a [1024]byte
for {
n, err := stdout.Read(a[:])
if err != nil {
if err != io.EOF {
t.Errorf("unexpected read error: %v", err)
}
return
}
t.Logf("%s", a[:n])
}
}()
if err := c.Start(); err != nil {
t.Fatal(err)
}
if err := r.Close(); err != nil {
t.Fatal(err)
}
if _, err := io.WriteString(w, "echo"); err != nil {
t.Fatal(err)
}
cancel()
// Calling cancel should have killed the process, so writes
// should now fail. Give the process a little while to die.
start := time.Now()
for {
if _, err := io.WriteString(w, "echo"); err != nil {
break
}
if time.Since(start) > time.Second {
t.Fatal("cancelling context did not stop program")
}
time.Sleep(time.Millisecond)
}
if err := w.Close(); err != nil {
t.Error("error closing write end of pipe: %v", err)
}
<-readDone
if err := c.Wait(); err == nil {
t.Error("program unexpectedly exited successfully")
} else {
t.Logf("exit status: %v", err)
}
}
View
@@ -4,9 +4,6 @@
// Package filepath implements utility routines for manipulating filename paths
// in a way compatible with the target operating system-defined file paths.
//
// Functions in this package replace any occurrences of the slash ('/') character
// with os.PathSeparator when returning paths unless otherwise specified.
package filepath
import (
@@ -75,6 +72,8 @@ const (
// The returned path ends in a slash only if it represents a root directory,
// such as "/" on Unix or `C:\` on Windows.
//
// Finally, any occurrences of slash are replaced by Separator.
//
// If the result of this process is an empty string, Clean
// returns the string ".".
//
@@ -198,7 +197,7 @@ func Split(path string) (dir, file string) {
}
// Join joins any number of path elements into a single path, adding
// a Separator if necessary. The result is Cleaned, in particular
// a Separator if necessary. Join calls Clean on the result; in particular,
// all empty strings are ignored.
// On Windows, the result is a UNC path if and only if the first path
// element is a UNC path.
@@ -223,6 +222,7 @@ func Ext(path string) string {
// links.
// If path is relative the result will be relative to the current directory,
// unless one of the components is an absolute symbolic link.
// EvalSymlinks calls Clean on the result.
func EvalSymlinks(path string) (string, error) {
return evalSymlinks(path)
}
@@ -231,6 +231,7 @@ func EvalSymlinks(path string) (string, error) {
// If the path is not absolute it will be joined with the current
// working directory to turn it into an absolute path. The absolute
// path name for a given file is not guaranteed to be unique.
// Abs calls Clean on the result.
func Abs(path string) (string, error) {
return abs(path)
}
@@ -253,6 +254,7 @@ func unixAbs(path string) (string, error) {
// even if basepath and targpath share no elements.
// An error is returned if targpath can't be made relative to basepath or if
// knowing the current working directory would be necessary to compute it.
// Rel calls Clean on the result.
func Rel(basepath, targpath string) (string, error) {
baseVol := VolumeName(basepath)
targVol := VolumeName(targpath)
@@ -442,7 +444,7 @@ func Base(path string) string {
}
// Dir returns all but the last element of path, typically the path's directory.
// After dropping the final element, the path is Cleaned and trailing
// After dropping the final element, Dir calls Clean on the path and trailing
// slashes are removed.
// If the path is empty, Dir returns ".".
// If the path consists entirely of separators, Dir returns a single separator.
View
@@ -5741,3 +5741,10 @@ func TestOffsetLock(t *testing.T) {
}
wg.Wait()
}
func BenchmarkNew(b *testing.B) {
v := TypeOf(XM{})
for i := 0; i < b.N; i++ {
New(v)
}
}
View
@@ -268,6 +268,9 @@ const (
// a program, the type *T also exists and reusing the str data
// saves binary size.
tflagExtraStar tflag = 1 << 1
// tflagNamed means the type has a name.
tflagNamed tflag = 1 << 2
)
// rtype is the common implementation of most values.
@@ -285,7 +288,7 @@ type rtype struct {
alg *typeAlg // algorithm table
gcdata *byte // garbage collection data
str nameOff // string form
_ int32 // unused; keeps rtype always a multiple of ptrSize
ptrToThis typeOff // type for pointer to this type, may be zero
}
// a copy of runtime.typeAlg
@@ -463,15 +466,13 @@ func (n name) tagLen() int {
func (n name) name() (s string) {
if n.bytes == nil {
return ""
}
nl := n.nameLen()
if nl == 0 {
return ""
return
}
b := (*[4]byte)(unsafe.Pointer(n.bytes))
hdr := (*stringHeader)(unsafe.Pointer(&s))
hdr.Data = unsafe.Pointer(n.data(3))
hdr.Len = nl
hdr.Data = unsafe.Pointer(&b[3])
hdr.Len = int(b[1])<<8 | int(b[2])
return s
}
@@ -659,16 +660,10 @@ type typeOff int32 // offset to an *rtype
type textOff int32 // offset from top of text section
func (t *rtype) nameOff(off nameOff) name {
if off == 0 {
return name{}
}
return name{(*byte)(resolveNameOff(unsafe.Pointer(t), int32(off)))}
}
func (t *rtype) typeOff(off typeOff) *rtype {
if off == 0 {
return nil
}
return (*rtype)(resolveTypeOff(unsafe.Pointer(t), int32(off)))
}
@@ -820,6 +815,9 @@ func (t *rtype) NumMethod() int {
tt := (*interfaceType)(unsafe.Pointer(t))
return tt.NumMethod()
}
if t.tflag&tflagUncommon == 0 {
return 0 // avoid methodCache lock in zero case
}
return len(t.exportedMethods())
}
@@ -890,29 +888,10 @@ func hasPrefix(s, prefix string) bool {
}
func (t *rtype) Name() string {
s := t.String()
if hasPrefix(s, "map[") {
return ""
}
if hasPrefix(s, "struct {") {
return ""
}
if hasPrefix(s, "chan ") {
return ""
}
if hasPrefix(s, "chan<-") {
return ""
}
if hasPrefix(s, "func(") {
return ""
}
if hasPrefix(s, "interface {") {
return ""
}
switch s[0] {
case '[', '*', '<':
if t.tflag&tflagNamed == 0 {
return ""
}
s := t.String()
i := len(s) - 1
for i >= 0 {
if s[i] == '.' {
@@ -1430,6 +1409,10 @@ func PtrTo(t Type) Type {
}
func (t *rtype) ptrTo() *rtype {
if t.ptrToThis != 0 {
return t.typeOff(t.ptrToThis)
}
// Check the cache.
ptrMap.RLock()
if m := ptrMap.m; m != nil {
@@ -1927,6 +1910,7 @@ func MapOf(key, elem Type) Type {
mt.bucketsize = uint16(mt.bucket.size)
mt.reflexivekey = isReflexive(ktyp)
mt.needkeyupdate = needKeyUpdate(ktyp)
mt.ptrToThis = 0
return cachePut(ckey, &mt.rtype)
}
@@ -2065,6 +2049,7 @@ func FuncOf(in, out []Type, variadic bool) Type {
// Populate the remaining fields of ft and store in cache.
ft.str = resolveReflectName(newName(str, "", "", false))
ft.ptrToThis = 0
funcLookupCache.m[hash] = append(funcLookupCache.m[hash], &ft.rtype)
return &ft.rtype
@@ -2295,6 +2280,7 @@ func SliceOf(t Type) Type {
slice.str = resolveReflectName(newName(s, "", "", false))
slice.hash = fnv1(typ.hash, '[')
slice.elem = typ
slice.ptrToThis = 0
return cachePut(ckey, &slice.rtype)
}
@@ -2842,6 +2828,7 @@ func ArrayOf(count int, elem Type) Type {
}
array.hash = fnv1(array.hash, ']')
array.elem = typ
array.ptrToThis = 0
max := ^uintptr(0) / typ.size
if uintptr(count) > max {
panic("reflect.ArrayOf: array size would exceed virtual address space")
View
@@ -1692,7 +1692,7 @@ const (
// minimum and maximum runes involved in folding.
// checked during test.
minFold = 0x0041
maxFold = 0x118df
maxFold = 0x1e943
)
// appendFoldedRange returns the result of appending the range lo-hi
View
@@ -593,8 +593,10 @@ func TestSelectStackAdjust(t *testing.T) {
// pointers are adjusted correctly by stack shrinking.
c := make(chan *int)
d := make(chan *int)
ready := make(chan bool)
go func() {
ready1 := make(chan bool)
ready2 := make(chan bool)
f := func(ready chan bool, dup bool) {
// Temporarily grow the stack to 10K.
stackGrowthRecursive((10 << 10) / (128 * 8))
@@ -604,10 +606,20 @@ func TestSelectStackAdjust(t *testing.T) {
val := 42
var cx *int
cx = &val
var c2 chan *int
var d2 chan *int
if dup {
c2 = c
d2 = d
}
// Receive from d. cx won't be affected.
select {
case cx = <-c:
case <-c2:
case <-d:
case <-d2:
}
// Check that pointer in cx was adjusted correctly.
@@ -622,10 +634,14 @@ func TestSelectStackAdjust(t *testing.T) {
}
}
ready <- true
}()
}
go f(ready1, false)
go f(ready2, true)
// Let the goroutine get into the select.
<-ready
// Let the goroutines get into the select.
<-ready1
<-ready2
time.Sleep(10 * time.Millisecond)
// Force concurrent GC a few times.
@@ -642,9 +658,10 @@ func TestSelectStackAdjust(t *testing.T) {
done:
selectSink = nil
// Wake select.
d <- nil
<-ready
// Wake selects.
close(d)
<-ready1
<-ready2
}
func BenchmarkChanNonblocking(b *testing.B) {
View
@@ -252,7 +252,21 @@ func testCgoPprof(t *testing.T, buildArg, runArg string) {
fn := strings.TrimSpace(string(got))
defer os.Remove(fn)
top, err := exec.Command("go", "tool", "pprof", "-top", "-nodecount=1", exe, fn).CombinedOutput()
cmd := testEnv(exec.Command("go", "tool", "pprof", "-top", "-nodecount=1", exe, fn))
found := false
for i, e := range cmd.Env {
if strings.HasPrefix(e, "PPROF_TMPDIR=") {
cmd.Env[i] = "PPROF_TMPDIR=" + os.TempDir()
found = true
break
}
}
if !found {
cmd.Env = append(cmd.Env, "PPROF_TMPDIR="+os.TempDir())
}
top, err := cmd.CombinedOutput()
t.Logf("%s", top)
if err != nil {
t.Fatal(err)
View
@@ -442,3 +442,43 @@ func TestPanicDeadlockGosched(t *testing.T) {
func TestPanicDeadlockSyscall(t *testing.T) {
testPanicDeadlock(t, "SyscallInPanic", "1\n2\npanic: 3\n\n")
}
func TestMemPprof(t *testing.T) {
testenv.MustHaveGoRun(t)
exe, err := buildTestProg(t, "testprog")
if err != nil {
t.Fatal(err)
}
got, err := testEnv(exec.Command(exe, "MemProf")).CombinedOutput()
if err != nil {
t.Fatal(err)
}
fn := strings.TrimSpace(string(got))
defer os.Remove(fn)
cmd := testEnv(exec.Command("go", "tool", "pprof", "-alloc_space", "-top", exe, fn))
found := false
for i, e := range cmd.Env {
if strings.HasPrefix(e, "PPROF_TMPDIR=") {
cmd.Env[i] = "PPROF_TMPDIR=" + os.TempDir()
found = true
break
}
}
if !found {
cmd.Env = append(cmd.Env, "PPROF_TMPDIR="+os.TempDir())
}
top, err := cmd.CombinedOutput()
t.Logf("%s", top)
if err != nil {
t.Fatal(err)
}
if !bytes.Contains(top, []byte("MemProf")) {
t.Error("missing MemProf in pprof output")
}
}
View
@@ -54,7 +54,6 @@ func getitab(inter *interfacetype, typ *_type, canfail bool) *itab {
for m = (*itab)(atomic.Loadp(unsafe.Pointer(&hash[h]))); m != nil; m = m.link {
if m.inter == inter && m._type == typ {
if m.bad != 0 {
m = nil
if !canfail {
// this can only happen if the conversion
// was already done once using the , ok form
@@ -64,6 +63,7 @@ func getitab(inter *interfacetype, typ *_type, canfail bool) *itab {
// adding the itab again, which will throw an error.
additab(m, locked != 0, false)
}
m = nil
}
if locked != 0 {
unlock(&ifaceLock)
View
@@ -161,28 +161,71 @@ TEXT runtime∕internal∕atomic·Store64(SB), NOSPLIT, $0-16
MOVD R4, 0(R3)
RET
// void runtime∕internal∕atomic·Or8(byte volatile*, byte);
// void runtime∕internal∕atomic·Or8(byte volatile*, byte);
TEXT runtime∕internal∕atomic·Or8(SB), NOSPLIT, $0-9
MOVD ptr+0(FP), R3
MOVBZ val+8(FP), R4
#ifdef GOARCH_ppc64
// Align ptr down to 4 bytes so we can use 32-bit load/store.
// R5 = (R3 << 0) & ~3
RLDCR $0, R3, $~3, R5
// Compute val shift.
// Big endian. ptr = ptr ^ 3
XOR $3, R3
// R6 = ((ptr & 3) * 8) = (ptr << 3) & (3*8)
RLDC $3, R3, $(3*8), R6
// Shift val for aligned ptr. R4 = val << R6
SLD R6, R4, R4
SYNC
again:
LWAR (R5), R6
OR R4, R6
STWCCC R6, (R5)
BNE again
#else
SYNC
again:
LBAR (R3), R6
OR R4, R6
STBCCC R6, (R3)
BNE again
#endif
ISYNC
RET
// void runtime∕internal∕atomic·And8(byte volatile*, byte);
// void runtime∕internal∕atomic·And8(byte volatile*, byte);
TEXT runtime∕internal∕atomic·And8(SB), NOSPLIT, $0-9
MOVD ptr+0(FP), R3
MOVBZ val+8(FP), R4
#ifdef GOARCH_ppc64
// Align ptr down to 4 bytes so we can use 32-bit load/store.
// R5 = (R3 << 0) & ~3
RLDCR $0, R3, $~3, R5
// Compute val shift.
// Big endian. ptr = ptr ^ 3
XOR $3, R3
// R6 = ((ptr & 3) * 8) = (ptr << 3) & (3*8)
RLDC $3, R3, $(3*8), R6
// Shift val for aligned ptr. R4 = val << R6 | ^(0xFF << R6)
MOVD $0xFF, R7
SLD R6, R4
SLD R6, R7
XOR $-1, R7
OR R7, R4
SYNC
again:
LBAR (R3), R6
LWAR (R5), R6
AND R4, R6
STBCCC R6, (R3)
STWCCC R6, (R5)
BNE again
#else
SYNC
again:
LBAR (R3),R6
AND R4,R6
STBCCC R6,(R3)
BNE again
#endif
ISYNC
RET
View
@@ -2,6 +2,8 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build !386
package sys
// Using techniques from http://supertech.csail.mit.edu/papers/debruijn.pdf
View
@@ -0,0 +1,68 @@
// 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.
#include "textflag.h"
TEXT runtime∕internal∕sys·Ctz64(SB), NOSPLIT, $0-16
MOVL $0, ret_hi+12(FP)
// Try low 32 bits.
MOVL x_lo+0(FP), AX
BSFL AX, AX
JZ tryhigh
MOVL AX, ret_lo+8(FP)
RET
tryhigh:
// Try high 32 bits.
MOVL x_hi+4(FP), AX
BSFL AX, AX
JZ none
ADDL $32, AX
MOVL AX, ret_lo+8(FP)
RET
none:
// No bits are set.
MOVL $64, ret_lo+8(FP)
RET
TEXT runtime∕internal∕sys·Ctz32(SB), NOSPLIT, $0-8
MOVL x+0(FP), AX
BSFL AX, AX
JNZ 2(PC)
MOVL $32, AX
MOVL AX, ret+4(FP)
RET
TEXT runtime∕internal∕sys·Ctz16(SB), NOSPLIT, $0-6
MOVW x+0(FP), AX
BSFW AX, AX
JNZ 2(PC)
MOVW $16, AX
MOVW AX, ret+4(FP)
RET
TEXT runtime∕internal∕sys·Ctz8(SB), NOSPLIT, $0-5
MOVBLZX x+0(FP), AX
BSFL AX, AX
JNZ 2(PC)
MOVB $8, AX
MOVB AX, ret+4(FP)
RET
TEXT runtime∕internal∕sys·Bswap64(SB), NOSPLIT, $0-16
MOVL x_lo+0(FP), AX
MOVL x_hi+4(FP), BX
BSWAPL AX
BSWAPL BX
MOVL BX, ret_lo+8(FP)
MOVL AX, ret_hi+12(FP)
RET
TEXT runtime∕internal∕sys·Bswap32(SB), NOSPLIT, $0-8
MOVL x+0(FP), AX
BSWAPL AX
MOVL AX, ret+4(FP)
RET
View
@@ -0,0 +1,14 @@
// 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 386
package sys
func Ctz64(x uint64) uint64
func Ctz32(x uint32) uint32
func Ctz16(x uint16) uint16
func Ctz8(x uint8) uint8
func Bswap64(x uint64) uint64
func Bswap32(x uint32) uint32
View
@@ -145,7 +145,7 @@ func writebarrierptr(dst *uintptr, src uintptr) {
if !writeBarrier.needed {
return
}
if src != 0 && (src < sys.PhysPageSize || src == poisonStack) {
if src != 0 && src < sys.PhysPageSize {
systemstack(func() {
print("runtime: writebarrierptr *", dst, " = ", hex(src), "\n")
throw("bad pointer in write barrier")
@@ -164,7 +164,7 @@ func writebarrierptr_nostore(dst *uintptr, src uintptr) {
if !writeBarrier.needed {
return
}
if src != 0 && (src < sys.PhysPageSize || src == poisonStack) {
if src != 0 && src < sys.PhysPageSize {
systemstack(func() { throw("bad pointer in write barrier") })
}
writebarrierptr_nostore1(dst, src)
View
@@ -165,6 +165,9 @@ func newosproc(mp *m, _ unsafe.Pointer) {
sigprocmask(_SIG_SETMASK, &oset, nil)
if ret != 0 {
print("runtime: failed to create new OS thread (have ", mcount(), " already; errno=", ret, ")\n")
if ret == -_EAGAIN {
println("runtime: may need to increase max user processes (ulimit -u)")
}
throw("newosproc")
}
}
View
@@ -134,6 +134,7 @@ func newosproc(mp *m, stk unsafe.Pointer) {
tid2: nil,
}
// TODO: Check for error.
lwp_create(&params)
sigprocmask(_SIG_SETMASK, &oset, nil)
}
View
@@ -121,6 +121,7 @@ func newosproc(mp *m, stk unsafe.Pointer) {
var oset sigset
sigprocmask(_SIG_SETMASK, &sigset_all, &oset)
// TODO: Check for error.
thr_new(&param, int32(unsafe.Sizeof(param)))
sigprocmask(_SIG_SETMASK, &oset, nil)
}
View
@@ -154,6 +154,9 @@ func newosproc(mp *m, stk unsafe.Pointer) {
if ret < 0 {
print("runtime: failed to create new OS thread (have ", mcount(), " already; errno=", -ret, ")\n")
if ret == -_EAGAIN {
println("runtime: may need to increase max user processes (ulimit -u)")
}
throw("newosproc")
}
}
View
@@ -20,6 +20,8 @@ const (
// From NetBSD's <sys/ucontext.h>
_UC_SIGMASK = 0x01
_UC_CPU = 0x04
_EAGAIN = 35
)
type mOS struct {
@@ -162,6 +164,9 @@ func newosproc(mp *m, stk unsafe.Pointer) {
ret := lwp_create(unsafe.Pointer(&uc), 0, unsafe.Pointer(&mp.procid))
if ret < 0 {
print("runtime: failed to create new OS thread (have ", mcount()-1, " already; errno=", -ret, ")\n")
if ret == -_EAGAIN {
println("runtime: may need to increase max user processes (ulimit -p)")
}
throw("runtime.newosproc")
}
}
View
@@ -154,6 +154,9 @@ func newosproc(mp *m, stk unsafe.Pointer) {
if ret < 0 {
print("runtime: failed to create new OS thread (have ", mcount()-1, " already; errno=", -ret, ")\n")
if ret == -_EAGAIN {
println("runtime: may need to increase max user processes (ulimit -p)")
}
throw("runtime.newosproc")
}
}
View
@@ -5,7 +5,7 @@
// Package pprof writes runtime profiling data in the format expected
// by the pprof visualization tool.
// For more information about pprof, see
// http://code.google.com/p/google-perftools/.
// http://github.com/google/pprof/.
package pprof
import (
View
@@ -3826,7 +3826,7 @@ func schedtrace(detailed bool) {
if lockedg != nil {
id3 = lockedg.goid
}
print(" M", mp.id, ": p=", id1, " curg=", id2, " mallocing=", mp.mallocing, " throwing=", mp.throwing, " preemptoff=", mp.preemptoff, ""+" locks=", mp.locks, " dying=", mp.dying, " helpgc=", mp.helpgc, " spinning=", mp.spinning, " blocked=", getg().m.blocked, " lockedg=", id3, "\n")
print(" M", mp.id, ": p=", id1, " curg=", id2, " mallocing=", mp.mallocing, " throwing=", mp.throwing, " preemptoff=", mp.preemptoff, ""+" locks=", mp.locks, " dying=", mp.dying, " helpgc=", mp.helpgc, " spinning=", mp.spinning, " blocked=", mp.blocked, " lockedg=", id3, "\n")
}
lock(&allglock)
View
@@ -0,0 +1,37 @@
// 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 linux,race
package race_test
import (
"sync/atomic"
"syscall"
"testing"
"unsafe"
)
func TestAtomicMmap(t *testing.T) {
// Test that atomic operations work on "external" memory. Previously they crashed (#16206).
// Also do a sanity correctness check: under race detector atomic operations
// are implemented inside of race runtime.
mem, err := syscall.Mmap(-1, 0, 1<<20, syscall.PROT_READ|syscall.PROT_WRITE, syscall.MAP_ANON|syscall.MAP_PRIVATE)
if err != nil {
t.Fatalf("mmap failed: %v", err)
}
defer syscall.Munmap(mem)
a := (*uint64)(unsafe.Pointer(&mem[0]))
if *a != 0 {
t.Fatalf("bad atomic value: %v, want 0", *a)
}
atomic.AddUint64(a, 1)
if *a != 1 {
t.Fatalf("bad atomic value: %v, want 1", *a)
}
atomic.AddUint64(a, 1)
if *a != 2 {
t.Fatalf("bad atomic value: %v, want 2", *a)
}
}
View
@@ -0,0 +1,46 @@
// 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 windows,race
package race_test
import (
"sync/atomic"
"syscall"
"testing"
"unsafe"
)
func TestAtomicMmap(t *testing.T) {
// Test that atomic operations work on "external" memory. Previously they crashed (#16206).
// Also do a sanity correctness check: under race detector atomic operations
// are implemented inside of race runtime.
kernel32 := syscall.NewLazyDLL("kernel32.dll")
VirtualAlloc := kernel32.NewProc("VirtualAlloc")
VirtualFree := kernel32.NewProc("VirtualFree")
const (
MEM_COMMIT = 0x00001000
MEM_RESERVE = 0x00002000
MEM_RELEASE = 0x8000
PAGE_READWRITE = 0x04
)
mem, _, err := syscall.Syscall6(VirtualAlloc.Addr(), 4, 0, 1<<20, MEM_COMMIT|MEM_RESERVE, PAGE_READWRITE, 0, 0)
if err != 0 {
t.Fatalf("VirtualAlloc failed: %v", err)
}
defer syscall.Syscall(VirtualFree.Addr(), 3, mem, 1<<20, MEM_RELEASE)
a := (*uint64)(unsafe.Pointer(mem))
if *a != 0 {
t.Fatalf("bad atomic value: %v, want 0", *a)
}
atomic.AddUint64(a, 1)
if *a != 1 {
t.Fatalf("bad atomic value: %v, want 1", *a)
}
atomic.AddUint64(a, 1)
if *a != 2 {
t.Fatalf("bad atomic value: %v, want 2", *a)
}
}
View
@@ -338,6 +338,7 @@ racecallatomic_ignore:
// An attempt to synchronize on the address would cause crash.
MOVQ AX, R15 // remember the original function
MOVQ $__tsan_go_ignore_sync_begin(SB), AX
get_tls(R12)
MOVQ g(R12), R14
MOVQ g_racectx(R14), RARG0 // goroutine context
CALL racecall<>(SB)
View
@@ -127,7 +127,6 @@ const (
const (
uintptrMask = 1<<(8*sys.PtrSize) - 1
poisonStack = uintptrMask & 0x6868686868686868
// Goroutine preemption request.
// Stored into g->stackguard0 to cause split stack check failure.
@@ -594,7 +593,7 @@ func adjustpointers(scanp unsafe.Pointer, cbv *bitvector, adjinfo *adjustinfo, f
pp := (*uintptr)(add(scanp, i*sys.PtrSize))
retry:
p := *pp
if f != nil && 0 < p && p < _PageSize && debug.invalidptr != 0 || p == poisonStack {
if f != nil && 0 < p && p < _PageSize && debug.invalidptr != 0 {
// Looks like a junk value in a pointer slot.
// Live analysis wrong?
getg().m.traceback = 2
@@ -785,8 +784,12 @@ func syncadjustsudogs(gp *g, used uintptr, adjinfo *adjustinfo) uintptr {
// copystack; otherwise, gp may be in the middle of
// putting itself on wait queues and this would
// self-deadlock.
var lastc *hchan
for sg := gp.waiting; sg != nil; sg = sg.waitlink {
lock(&sg.c.lock)
if sg.c != lastc {
lock(&sg.c.lock)
}
lastc = sg.c
}
// Adjust sudogs.
@@ -804,8 +807,12 @@ func syncadjustsudogs(gp *g, used uintptr, adjinfo *adjustinfo) uintptr {
}
// Unlock channels.
lastc = nil
for sg := gp.waiting; sg != nil; sg = sg.waitlink {
unlock(&sg.c.lock)
if sg.c != lastc {
unlock(&sg.c.lock)
}
lastc = sg.c
}
return sgsize
View
@@ -201,6 +201,11 @@ systime:
MOVL $0, 8(SP) // time zone pointer
MOVL $116, AX
INT $0x80
CMPL AX, $0
JNE inreg
MOVL 12(SP), AX
MOVL 16(SP), DX
inreg:
// sec is in AX, usec in DX
// convert to DX:AX nsec
MOVL DX, BX
View
@@ -155,10 +155,15 @@ timeloop:
systime:
// Fall back to system call (usually first call in this thread).
MOVQ SP, DI // must be non-nil, unused
MOVQ SP, DI
MOVQ $0, SI
MOVL $(0x2000000+116), AX
SYSCALL
CMPQ AX, $0
JNE inreg
MOVQ 0(SP), AX
MOVL 8(SP), DX
inreg:
// sec is in AX, usec in DX
// return nsec in AX
IMULQ $1000000000, AX
View
@@ -0,0 +1,49 @@
// 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"
"io/ioutil"
"os"
"runtime"
"runtime/pprof"
)
func init() {
register("MemProf", MemProf)
}
var memProfBuf bytes.Buffer
var memProfStr string
func MemProf() {
for i := 0; i < 1000; i++ {
fmt.Fprintf(&memProfBuf, "%*d\n", i, i)
}
memProfStr = memProfBuf.String()
runtime.GC()
f, err := ioutil.TempFile("", "memprof")
if err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(2)
}
if err := pprof.WriteHeapProfile(f); err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(2)
}
name := f.Name()
if err := f.Close(); err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(2)
}
fmt.Println(name)
}
View
@@ -19,6 +19,7 @@ type tflag uint8
const (
tflagUncommon tflag = 1 << 0
tflagExtraStar tflag = 1 << 1
tflagNamed tflag = 1 << 2
)
// Needs to be in sync with ../cmd/compile/internal/ld/decodesym.go:/^func.commonsize,
@@ -36,9 +37,9 @@ type _type struct {
// gcdata stores the GC type data for the garbage collector.
// If the KindGCProg bit is set in kind, gcdata is a GC program.
// Otherwise it is a ptrmask bitmap. See mbitmap.go for details.
gcdata *byte
str nameOff
_ int32
gcdata *byte
str nameOff
ptrToThis typeOff
}
func (t *_type) string() string {
@@ -116,29 +117,10 @@ func hasPrefix(s, prefix string) bool {
}
func (t *_type) name() string {
s := t.string()
if hasPrefix(s, "map[") {
return ""
}
if hasPrefix(s, "struct {") {
return ""
}
if hasPrefix(s, "chan ") {
return ""
}
if hasPrefix(s, "chan<-") {
return ""
}
if hasPrefix(s, "func(") {
return ""
}
if hasPrefix(s, "interface {") {
return ""
}
switch s[0] {
case '[', '*', '<':
if t.tflag&tflagNamed == 0 {
return ""
}
s := t.string()
i := len(s) - 1
for i >= 0 {
if s[i] == '.' {
@@ -188,32 +170,29 @@ func resolveNameOff(ptrInModule unsafe.Pointer, off nameOff) name {
return name{}
}
base := uintptr(ptrInModule)
var md *moduledata
for next := &firstmoduledata; next != nil; next = next.next {
if base >= next.types && base < next.etypes {
md = next
break
}
}
if md == nil {
reflectOffsLock()
res, found := reflectOffs.m[int32(off)]
reflectOffsUnlock()
if !found {
println("runtime: nameOff", hex(off), "base", hex(base), "not in ranges:")
for next := &firstmoduledata; next != nil; next = next.next {
println("\ttypes", hex(next.types), "etypes", hex(next.etypes))
for md := &firstmoduledata; md != nil; md = md.next {
if base >= md.types && base < md.etypes {
res := md.types + uintptr(off)
if res > md.etypes {
println("runtime: nameOff", hex(off), "out of range", hex(md.types), "-", hex(md.etypes))
throw("runtime: name offset out of range")
}
throw("runtime: name offset base pointer out of range")
return name{(*byte)(unsafe.Pointer(res))}
}
return name{(*byte)(res)}
}
res := md.types + uintptr(off)
if res > md.etypes {
println("runtime: nameOff", hex(off), "out of range", hex(md.types), "-", hex(md.etypes))
throw("runtime: name offset out of range")
// No module found. see if it is a run time name.
reflectOffsLock()
res, found := reflectOffs.m[int32(off)]
reflectOffsUnlock()
if !found {
println("runtime: nameOff", hex(off), "base", hex(base), "not in ranges:")
for next := &firstmoduledata; next != nil; next = next.next {
println("\ttypes", hex(next.types), "etypes", hex(next.etypes))
}
throw("runtime: name offset base pointer out of range")
}
return name{(*byte)(unsafe.Pointer(res))}
return name{(*byte)(res)}
}
func (t *_type) nameOff(off nameOff) name {
View
@@ -197,7 +197,7 @@ func ParseInt(s string, base int, bitSize int) (i int64, err error) {
return n, nil
}
// Atoi is shorthand for ParseInt(s, 10, 0).
// Atoi returns the result of ParseInt(s, 10, 0) converted to type int.
func Atoi(s string) (int, error) {
i64, err := ParseInt(s, 10, 0)
return int(i64), err
View
@@ -7,7 +7,7 @@
package strconv
// (470+136+73)*2 + (342)*4 = 2726 bytes
// (462+139+82)*2 + (378)*4 = 2878 bytes
var isPrint16 = []uint16{
0x0020, 0x007e,
@@ -26,8 +26,8 @@ var isPrint16 = []uint16{
0x0800, 0x082d,
0x0830, 0x085b,
0x085e, 0x085e,
0x08a0, 0x08b4,
0x08e3, 0x098c,
0x08a0, 0x08bd,
0x08d4, 0x098c,
0x098f, 0x0990,
0x0993, 0x09b2,
0x09b6, 0x09b9,
@@ -83,11 +83,9 @@ var isPrint16 = []uint16{
0x0cde, 0x0ce3,
0x0ce6, 0x0cf2,
0x0d01, 0x0d3a,
0x0d3d, 0x0d4e,
0x0d57, 0x0d57,
0x0d5f, 0x0d63,
0x0d66, 0x0d75,
0x0d79, 0x0d7f,
0x0d3d, 0x0d4f,
0x0d54, 0x0d63,
0x0d66, 0x0d7f,
0x0d82, 0x0d96,
0x0d9a, 0x0dbd,
0x0dc0, 0x0dc6,
@@ -153,11 +151,11 @@ var isPrint16 = []uint16{
0x1b80, 0x1bf3,
0x1bfc, 0x1c37,
0x1c3b, 0x1c49,
0x1c4d, 0x1c7f,
0x1c4d, 0x1c88,
0x1cc0, 0x1cc7,
0x1cd0, 0x1cf9,
0x1d00, 0x1df5,
0x1dfc, 0x1f15,
0x1dfb, 0x1f15,
0x1f18, 0x1f1d,
0x1f20, 0x1f45,
0x1f48, 0x1f4d,
@@ -172,8 +170,7 @@ var isPrint16 = []uint16{
0x20a0, 0x20be,
0x20d0, 0x20f0,
0x2100, 0x218b,
0x2190, 0x23fa,
0x2400, 0x2426,
0x2190, 0x2426,
0x2440, 0x244a,
0x2460, 0x2b73,
0x2b76, 0x2b95,
@@ -186,7 +183,7 @@ var isPrint16 = []uint16{
0x2d30, 0x2d67,
0x2d6f, 0x2d70,
0x2d7f, 0x2d96,
0x2da0, 0x2e42,
0x2da0, 0x2e44,
0x2e80, 0x2ef3,
0x2f00, 0x2fd5,
0x2ff0, 0x2ffb,
@@ -201,12 +198,11 @@ var isPrint16 = []uint16{
0xa490, 0xa4c6,
0xa4d0, 0xa62b,
0xa640, 0xa6f7,
0xa700, 0xa7ad,
0xa7b0, 0xa7b7,
0xa700, 0xa7b7,
0xa7f7, 0xa82b,
0xa830, 0xa839,
0xa840, 0xa877,
0xa880, 0xa8c4,
0xa880, 0xa8c5,
0xa8ce, 0xa8d9,
0xa8e0, 0xa8fd,
0xa900, 0xa953,
@@ -258,6 +254,8 @@ var isNotPrint16 = []uint16{
0x0590,
0x06dd,
0x083f,
0x08b5,
0x08e2,
0x0984,
0x09a9,
0x09b1,
@@ -294,7 +292,6 @@ var isNotPrint16 = []uint16{
0x0c45,
0x0c49,
0x0c57,
0x0c80,
0x0c84,
0x0c8d,
0x0c91,
@@ -354,6 +351,7 @@ var isNotPrint16 = []uint16{
0x1fdc,
0x1ff5,
0x208f,
0x23ff,
0x2bc9,
0x2c2f,
0x2c5f,
@@ -371,6 +369,7 @@ var isNotPrint16 = []uint16{
0x318f,
0x321f,
0x32ff,
0xa7af,
0xa9ce,
0xa9ff,
0xab27,
@@ -392,8 +391,7 @@ var isPrint32 = []uint32{
0x010080, 0x0100fa,
0x010100, 0x010102,
0x010107, 0x010133,
0x010137, 0x01018c,
0x010190, 0x01019b,
0x010137, 0x01019b,
0x0101a0, 0x0101a0,
0x0101d0, 0x0101fd,
0x010280, 0x01029c,
@@ -406,6 +404,8 @@ var isPrint32 = []uint32{
0x0103c8, 0x0103d5,
0x010400, 0x01049d,
0x0104a0, 0x0104a9,
0x0104b0, 0x0104d3,
0x0104d8, 0x0104fb,
0x010500, 0x010527,
0x010530, 0x010563,
0x01056f, 0x01056f,
@@ -451,7 +451,7 @@ var isPrint32 = []uint32{
0x011150, 0x011176,
0x011180, 0x0111cd,
0x0111d0, 0x0111f4,
0x011200, 0x01123d,
0x011200, 0x01123e,
0x011280, 0x0112a9,
0x0112b0, 0x0112ea,
0x0112f0, 0x0112f9,
@@ -466,12 +466,14 @@ var isPrint32 = []uint32{
0x01135d, 0x011363,
0x011366, 0x01136c,
0x011370, 0x011374,
0x011400, 0x01145d,
0x011480, 0x0114c7,
0x0114d0, 0x0114d9,
0x011580, 0x0115b5,
0x0115b8, 0x0115dd,
0x011600, 0x011644,
0x011650, 0x011659,
0x011660, 0x01166c,
0x011680, 0x0116b7,
0x0116c0, 0x0116c9,
0x011700, 0x011719,
@@ -480,6 +482,10 @@ var isPrint32 = []uint32{
0x0118a0, 0x0118f2,
0x0118ff, 0x0118ff,
0x011ac0, 0x011af8,
0x011c00, 0x011c45,
0x011c50, 0x011c6c,
0x011c70, 0x011c8f,
0x011c92, 0x011cb6,
0x012000, 0x012399,
0x012400, 0x012474,
0x012480, 0x012543,
@@ -496,6 +502,9 @@ var isPrint32 = []uint32{
0x016f00, 0x016f44,
0x016f50, 0x016f7e,
0x016f8f, 0x016f9f,
0x016fe0, 0x016fe0,
0x017000, 0x0187ec,
0x018800, 0x018af2,
0x01b000, 0x01b001,
0x01bc00, 0x01bc6a,
0x01bc70, 0x01bc7c,
@@ -518,8 +527,13 @@ var isPrint32 = []uint32{
0x01d6a8, 0x01d7cb,
0x01d7ce, 0x01da8b,
0x01da9b, 0x01daaf,
0x01e000, 0x01e018,
0x01e01b, 0x01e02a,
0x01e800, 0x01e8c4,
0x01e8c7, 0x01e8d6,
0x01e900, 0x01e94a,
0x01e950, 0x01e959,
0x01e95e, 0x01e95f,
0x01ee00, 0x01ee24,
0x01ee27, 0x01ee3b,
0x01ee42, 0x01ee42,
@@ -534,23 +548,26 @@ var isPrint32 = []uint32{
0x01f0b1, 0x01f0f5,
0x01f100, 0x01f10c,
0x01f110, 0x01f16b,
0x01f170, 0x01f19a,
0x01f170, 0x01f1ac,
0x01f1e6, 0x01f202,
0x01f210, 0x01f23a,
0x01f210, 0x01f23b,
0x01f240, 0x01f248,
0x01f250, 0x01f251,
0x01f300, 0x01f6d0,
0x01f300, 0x01f6d2,
0x01f6e0, 0x01f6ec,
0x01f6f0, 0x01f6f3,
0x01f6f0, 0x01f6f6,
0x01f700, 0x01f773,
0x01f780, 0x01f7d4,
0x01f800, 0x01f80b,
0x01f810, 0x01f847,
0x01f850, 0x01f859,
0x01f860, 0x01f887,
0x01f890, 0x01f8ad,
0x01f910, 0x01f918,
0x01f980, 0x01f984,
0x01f910, 0x01f927,
0x01f930, 0x01f930,
0x01f933, 0x01f94b,
0x01f950, 0x01f95e,
0x01f980, 0x01f991,
0x01f9c0, 0x01f9c0,
0x020000, 0x02a6d6,
0x02a700, 0x02b734,
@@ -565,6 +582,7 @@ var isNotPrint32 = []uint16{ // add 0x10000 to each entry
0x0027,
0x003b,
0x003e,
0x018f,
0x039e,
0x0809,
0x0836,
@@ -585,6 +603,11 @@ var isNotPrint32 = []uint16{ // add 0x10000 to each entry
0x1329,
0x1331,
0x1334,
0x145a,
0x145c,
0x1c09,
0x1c37,
0x1ca8,
0x246f,
0x6a5f,
0x6b5a,
@@ -603,6 +626,9 @@ var isNotPrint32 = []uint16{ // add 0x10000 to each entry
0xd545,
0xd551,
0xdaa0,
0xe007,
0xe022,
0xe025,
0xee04,
0xee20,
0xee23,
@@ -632,8 +658,8 @@ var isNotPrint32 = []uint16{ // add 0x10000 to each entry
0xf0c0,
0xf0d0,
0xf12f,
0xf57a,
0xf5a4,
0xf91f,
0xf93f,
}
// isGraphic lists the graphic runes not matched by IsPrint.
View
@@ -130,6 +130,8 @@ func (p *Proc) Addr() uintptr {
return p.addr
}
//go:uintptrescapes
// Call executes procedure p with arguments a. It will panic, if more than 15 arguments
// are supplied.
//
@@ -288,6 +290,8 @@ func (p *LazyProc) Addr() uintptr {
return p.proc.Addr()
}
//go:uintptrescapes
// Call executes procedure p with arguments a. It will panic, if more than 15 arguments
// are supplied.
//
View
@@ -200,8 +200,10 @@ func TestGroupCleanup(t *testing.T) {
}
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)
// Just check prefix because some distros reportedly output a
// context parameter; see https://golang.org/issue/16224.
if !strings.HasPrefix(strOut, expected) {
t.Errorf("id command output: %q, expected prefix: %q", strOut, expected)
}
}
@@ -230,10 +232,17 @@ func TestGroupCleanupUserNamespace(t *testing.T) {
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)
// Strings we've seen in the wild.
expected := []string{
"uid=0(root) gid=0(root) groups=0(root)",
"uid=0(root) gid=0(root) groups=0(root),65534(nobody)",
"uid=0(root) gid=0(root) groups=0(root),65534(nogroup)",
}
for _, e := range expected {
if strOut == e {
return
}
}
t.Errorf("id command output: %q, expected one of %q", strOut, expected)
}
View
@@ -196,6 +196,7 @@ func Getfsstat(buf []Statfs_t, flags int) (n int, err error) {
bufsize = unsafe.Sizeof(Statfs_t{}) * uintptr(len(buf))
}
r0, _, e1 := Syscall(SYS_GETFSSTAT64, uintptr(_p0), bufsize, uintptr(flags))
use(unsafe.Pointer(_p0))
n = int(r0)
if e1 != 0 {
err = e1
View
@@ -109,6 +109,7 @@ func Getfsstat(buf []Statfs_t, flags int) (n int, err error) {
bufsize = unsafe.Sizeof(Statfs_t{}) * uintptr(len(buf))
}
r0, _, e1 := Syscall(SYS_GETFSSTAT, uintptr(_p0), bufsize, uintptr(flags))
use(unsafe.Pointer(_p0))
n = int(r0)
if e1 != 0 {
err = e1
View
@@ -129,6 +129,7 @@ func Getfsstat(buf []Statfs_t, flags int) (n int, err error) {
bufsize = unsafe.Sizeof(Statfs_t{}) * uintptr(len(buf))
}
r0, _, e1 := Syscall(SYS_GETFSSTAT, uintptr(_p0), bufsize, uintptr(flags))
use(unsafe.Pointer(_p0))
n = int(r0)
if e1 != 0 {
err = e1
View
@@ -383,7 +383,7 @@ var _ TB = (*T)(nil)
var _ TB = (*B)(nil)
// T is a type passed to Test functions to manage test state and support formatted test logs.
// Logs are accumulated during execution and dumped to standard error when done.
// Logs are accumulated during execution and dumped to standard output when done.
//
// A test ends when its Test function returns or calls any of the methods
// FailNow, Fatal, Fatalf, SkipNow, Skip, or Skipf. Those methods, as well as
View
@@ -74,8 +74,9 @@ data, defined in detail in the corresponding sections that follow.
/*
{{pipeline}}
The default textual representation of the value of the pipeline
is copied to the output.
The default textual representation (the same as would be
printed by fmt.Print) of the value of the pipeline is copied
to the output.
{{if pipeline}} T1 {{end}}
If the value of the pipeline is empty, no output is generated;
View
@@ -454,8 +454,7 @@ const (
// String returns a string representing the duration in the form "72h3m0.5s".
// Leading zero units are omitted. As a special case, durations less than one
// second format use a smaller unit (milli-, micro-, or nanoseconds) to ensure
// that the leading digit is non-zero. The zero duration formats as 0,
// with no unit.
// that the leading digit is non-zero. The zero duration formats as 0s.
func (d Duration) String() string {
// Largest time is 2540400h10m10.000000000s
var buf [32]byte
View
@@ -73,7 +73,6 @@ var letterTest = []rune{
0x1200,
0x1312,
0x1401,
0x1885,
0x2c00,
0xa800,
0xf900,
@@ -94,6 +93,7 @@ var notletterTest = []rune{
0x375,
0x619,
0x700,
0x1885,
0xfffe,
0x1ffff,
0x10ffff,
View
@@ -44,7 +44,7 @@ func main() {
var dataURL = flag.String("data", "", "full URL for UnicodeData.txt; defaults to --url/UnicodeData.txt")
var casefoldingURL = flag.String("casefolding", "", "full URL for CaseFolding.txt; defaults to --url/CaseFolding.txt")
var url = flag.String("url",
"http://www.unicode.org/Public/8.0.0/ucd/",
"http://www.unicode.org/Public/9.0.0/ucd/",
"URL of Unicode database directory")
var tablelist = flag.String("tables",
"all",
@@ -743,6 +743,10 @@ func fullScriptTest(list []string, installed map[string]*unicode.RangeTable, scr
}
}
var deprecatedAliases = map[string]string{
"Sentence_Terminal": "STerm",
}
// PropList.txt has the same format as Scripts.txt so we can share its parser.
func printScriptOrProperty(doProps bool) {
flag := "scripts"
@@ -797,11 +801,14 @@ func printScriptOrProperty(doProps bool) {
}
for _, k := range all(table) {
printf("\t%q: %s,\n", k, k)
if alias, ok := deprecatedAliases[k]; ok {
printf("\t%q: %s,\n", alias, k)
}
}
print("}\n\n")
}
decl := make(sort.StringSlice, len(list))
decl := make(sort.StringSlice, len(list)+len(deprecatedAliases))
ndecl := 0
for _, name := range list {
if doProps {
@@ -814,6 +821,12 @@ func printScriptOrProperty(doProps bool) {
name, name, name, name)
}
ndecl++
if alias, ok := deprecatedAliases[name]; ok {
decl[ndecl] = fmt.Sprintf(
"\t%[1]s = _%[2]s;\t// %[1]s is an alias for %[2]s.\n",
alias, name)
ndecl++
}
printf("var _%s = &RangeTable {\n", name)
ranges := foldAdjacent(table[name])
print("\tR16: []Range16{\n")
View
@@ -18,10 +18,12 @@ type T struct {
// mostly to discover when new scripts and categories arise.
var inTest = []T{
{0x11711, "Ahom"},
{0x1e900, "Adlam"},
{0x14646, "Anatolian_Hieroglyphs"},
{0x06e2, "Arabic"},
{0x0567, "Armenian"},
{0x10b20, "Avestan"},
{0x11c00, "Bhaiksuki"},
{0x1b37, "Balinese"},
{0xa6af, "Bamum"},
{0x16ada, "Bassa_Vah"},
@@ -89,6 +91,7 @@ var inTest = []T{
{0x0d42, "Malayalam"},
{0x0843, "Mandaic"},
{0x10ac8, "Manichaean"},
{0x11cB6, "Marchen"},
{0xabd0, "Meetei_Mayek"},
{0x1e800, "Mende_Kikakui"},
{0x1099f, "Meroitic_Hieroglyphs"},
@@ -100,6 +103,7 @@ var inTest = []T{
{0x11293, "Multani"},
{0x104c, "Myanmar"},
{0x10880, "Nabataean"},
{0x11400, "Newa"},
{0x19c3, "New_Tai_Lue"},
{0x07f8, "Nko"},
{0x169b, "Ogham"},
@@ -112,6 +116,7 @@ var inTest = []T{
{0x10a6f, "Old_South_Arabian"},
{0x10c20, "Old_Turkic"},
{0x0b3e, "Oriya"},
{0x104d9, "Osage"},
{0x10491, "Osmanya"},
{0x16b2b, "Pahawh_Hmong"},
{0x10876, "Palmyrene"},
@@ -139,6 +144,7 @@ var inTest = []T{
{0xaadc, "Tai_Viet"},
{0x116c9, "Takri"},
{0x0bbf, "Tamil"},
{0x17000, "Tangut"},
{0x0c55, "Telugu"},
{0x07a7, "Thaana"},
{0x0e46, "Thai"},
@@ -220,9 +226,11 @@ var inPropTest = []T{
{0x216F, "Other_Uppercase"},
{0x0027, "Pattern_Syntax"},
{0x0020, "Pattern_White_Space"},
{0x06DD, "Prepended_Concatenation_Mark"},
{0x300D, "Quotation_Mark"},
{0x2EF3, "Radical"},
{0x061F, "STerm"},
{0x061F, "STerm"}, // Deprecated alias of Sentence_Terminal
{0x061F, "Sentence_Terminal"},
{0x2071, "Soft_Dotted"},
{0x003A, "Terminal_Punctuation"},
{0x9FC3, "Unified_Ideograph"},
Oops, something went wrong.