[dev.link] all: merge branch 'master' into dev.link

Clean merge.

Change-Id: If642f7901a797c6df5a0fa64aecebba22e5ee951
This commit is contained in:
Cherry Zhang 2020-08-07 12:42:10 -04:00
commit d9c19a7d3e
15 changed files with 197 additions and 61 deletions

View File

@ -655,8 +655,8 @@ Do not send CLs removing the interior tags from such phrases.
<dl id="flag"><dt><a href="/pkg/flag/">flag</a></dt>
<dd>
<p><!-- CL 221427 -->
When the flag package sees <code>-h</code> or <code>-help</code>, and
those flags are not defined, it now prints a usage message.
When the <code>flag</code> package sees <code>-h</code> or <code>-help</code>,
and those flags are not defined, it now prints a usage message.
If the <a href="/pkg/flag/#FlagSet"><code>FlagSet</code></a> was created with
<a href="/pkg/flag/#ExitOnError"><code>ExitOnError</code></a>,
<a href="/pkg/flag/#FlagSet.Parse"><code>FlagSet.Parse</code></a> would then
@ -901,9 +901,9 @@ Do not send CLs removing the interior tags from such phrases.
<dl id="pkg-runtime-pprof"><dt><a href="/pkg/runtime/pprof/">runtime/pprof</a></dt>
<dd>
<p><!-- CL 189318 -->
The goroutine profile includes the profile labels associated with each goroutine
at the time of profiling. This feature is not yet implemented for the profile
reported with <code>debug=2</code>.
The goroutine profile now includes the profile labels associated with each
goroutine at the time of profiling. This feature is not yet implemented for
the profile reported with <code>debug=2</code>.
</p>
</dd>
</dl>
@ -934,6 +934,7 @@ Do not send CLs removing the interior tags from such phrases.
<a href="/pkg/sync/#Map.Delete"><code>Map.Delete</code></a>
is more efficient.
</p>
</dd>
</dl><!-- sync -->
<dl id="syscall"><dt><a href="/pkg/syscall/">syscall</a></dt>

View File

@ -10,4 +10,5 @@ require (
golang.org/x/mod v0.3.0
golang.org/x/sys v0.0.0-20200501145240-bc7a7d42d5c3 // indirect
golang.org/x/tools v0.0.0-20200616133436-c1934b75d054
golang.org/x/xerrors v0.0.0-20200806184451-1a77d5e9f316 // indirect
)

View File

@ -34,4 +34,6 @@ golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8T
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200806184451-1a77d5e9f316 h1:Jhw4VC65LaKnpq9FvcK+a8ZzrFm3D+UygvMMrhkOw70=
golang.org/x/xerrors v0.0.0-20200806184451-1a77d5e9f316/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4=

View File

@ -239,11 +239,25 @@ func (p *Package) setLoadPackageDataError(err error, path string, stk *ImportSta
err = &NoGoError{Package: p}
}
// Take only the first error from a scanner.ErrorList. PackageError only
// has room for one position, so we report the first error with a position
// instead of all of the errors without a position.
var pos string
var isScanErr bool
if scanErr, ok := err.(scanner.ErrorList); ok && len(scanErr) > 0 {
isScanErr = true // For stack push/pop below.
scanPos := scanErr[0].Pos
scanPos.Filename = base.ShortPath(scanPos.Filename)
pos = scanPos.String()
err = errors.New(scanErr[0].Msg)
}
// Report the error on the importing package if the problem is with the import declaration
// for example, if the package doesn't exist or if the import path is malformed.
// On the other hand, don't include a position if the problem is with the imported package,
// for example there are no Go files (NoGoError), or there's a problem in the imported
// package's source files themselves.
// package's source files themselves (scanner errors).
//
// TODO(matloob): Perhaps make each of those the errors in the first group
// (including modload.ImportMissingError, and the corresponding
@ -254,22 +268,11 @@ func (p *Package) setLoadPackageDataError(err error, path string, stk *ImportSta
// to make it easier to check for them? That would save us from having to
// move the modload errors into this package to avoid a package import cycle,
// and from having to export an error type for the errors produced in build.
if !isMatchErr && nogoErr != nil {
if !isMatchErr && (nogoErr != nil || isScanErr) {
stk.Push(path)
defer stk.Pop()
}
// Take only the first error from a scanner.ErrorList. PackageError only
// has room for one position, so we report the first error with a position
// instead of all of the errors without a position.
var pos string
if scanErr, ok := err.(scanner.ErrorList); ok && len(scanErr) > 0 {
scanPos := scanErr[0].Pos
scanPos.Filename = base.ShortPath(scanPos.Filename)
pos = scanPos.String()
err = errors.New(scanErr[0].Msg)
}
p.Error = &PackageError{
ImportStack: stk.Copy(),
Pos: pos,

View File

@ -0,0 +1,27 @@
# golang.org/issue/40544: regression in error stacks for parse errors
env GO111MODULE=off
cd sandbox/foo
go list -e -json .
stdout '"sandbox/foo"'
stdout '"sandbox/bar"'
stdout '"Pos": "..(/|\\\\)bar(/|\\\\)bar.go:1:1"'
stdout '"Err": "expected ''package'', found ackage"'
env GO111MODULE=on
go list -e -json .
stdout '"sandbox/foo"'
stdout '"sandbox/bar"'
stdout '"Pos": "..(/|\\\\)bar(/|\\\\)bar.go:1:1"'
stdout '"Err": "expected ''package'', found ackage"'
-- sandbox/go.mod --
module sandbox
-- sandbox/foo/foo.go --
package pkg
import "sandbox/bar"
-- sandbox/bar/bar.go --
ackage bar

View File

@ -84,6 +84,7 @@ golang.org/x/tools/go/cfg
golang.org/x/tools/go/types/objectpath
golang.org/x/tools/go/types/typeutil
golang.org/x/tools/internal/analysisinternal
# golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543
# golang.org/x/xerrors v0.0.0-20200806184451-1a77d5e9f316
## explicit
golang.org/x/xerrors
golang.org/x/xerrors/internal

View File

@ -106,13 +106,13 @@ var overflow = errors.New("binary: varint overflows a 64-bit integer")
func ReadUvarint(r io.ByteReader) (uint64, error) {
var x uint64
var s uint
for i := 0; ; i++ {
for i := 0; i < MaxVarintLen64; i++ {
b, err := r.ReadByte()
if err != nil {
return x, err
}
if b < 0x80 {
if i > 9 || i == 9 && b > 1 {
if i == 9 && b > 1 {
return x, overflow
}
return x | uint64(b)<<s, nil
@ -120,6 +120,7 @@ func ReadUvarint(r io.ByteReader) (uint64, error) {
x |= uint64(b&0x7f) << s
s += 7
}
return x, overflow
}
// ReadVarint reads an encoded signed integer from r and returns it as an int64.

View File

@ -121,21 +121,27 @@ func TestBufferTooSmall(t *testing.T) {
}
}
func testOverflow(t *testing.T, buf []byte, n0 int, err0 error) {
func testOverflow(t *testing.T, buf []byte, x0 uint64, n0 int, err0 error) {
x, n := Uvarint(buf)
if x != 0 || n != n0 {
t.Errorf("Uvarint(%v): got x = %d, n = %d; want 0, %d", buf, x, n, n0)
}
x, err := ReadUvarint(bytes.NewReader(buf))
if x != 0 || err != err0 {
t.Errorf("ReadUvarint(%v): got x = %d, err = %s; want 0, %s", buf, x, err, err0)
r := bytes.NewReader(buf)
len := r.Len()
x, err := ReadUvarint(r)
if x != x0 || err != err0 {
t.Errorf("ReadUvarint(%v): got x = %d, err = %s; want %d, %s", buf, x, err, x0, err0)
}
if read := len - r.Len(); read > MaxVarintLen64 {
t.Errorf("ReadUvarint(%v): read more than MaxVarintLen64 bytes, got %d", buf, read)
}
}
func TestOverflow(t *testing.T) {
testOverflow(t, []byte{0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x2}, -10, overflow)
testOverflow(t, []byte{0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x1, 0, 0}, -13, overflow)
testOverflow(t, []byte{0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x2}, 0, -10, overflow)
testOverflow(t, []byte{0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x1, 0, 0}, 0, -13, overflow)
testOverflow(t, []byte{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, 1<<64-1, 0, overflow) // 11 bytes, should overflow
}
func TestNonCanonicalZero(t *testing.T) {

View File

@ -100,7 +100,7 @@ type Transport struct {
idleLRU connLRU
reqMu sync.Mutex
reqCanceler map[*Request]func(error)
reqCanceler map[cancelKey]func(error)
altMu sync.Mutex // guards changing altProto only
altProto atomic.Value // of nil or map[string]RoundTripper, key is URI scheme
@ -273,6 +273,13 @@ type Transport struct {
ForceAttemptHTTP2 bool
}
// A cancelKey is the key of the reqCanceler map.
// We wrap the *Request in this type since we want to use the original request,
// not any transient one created by roundTrip.
type cancelKey struct {
req *Request
}
func (t *Transport) writeBufferSize() int {
if t.WriteBufferSize > 0 {
return t.WriteBufferSize
@ -433,9 +440,10 @@ func ProxyURL(fixedURL *url.URL) func(*Request) (*url.URL, error) {
// optional extra headers to write and stores any error to return
// from roundTrip.
type transportRequest struct {
*Request // original request, not to be mutated
extra Header // extra headers to write, or nil
trace *httptrace.ClientTrace // optional
*Request // original request, not to be mutated
extra Header // extra headers to write, or nil
trace *httptrace.ClientTrace // optional
cancelKey cancelKey
mu sync.Mutex // guards err
err error // first setError value for mapRoundTripError to consider
@ -512,6 +520,7 @@ func (t *Transport) roundTrip(req *Request) (*Response, error) {
}
origReq := req
cancelKey := cancelKey{origReq}
req = setupRewindBody(req)
if altRT := t.alternateRoundTripper(req); altRT != nil {
@ -546,7 +555,7 @@ func (t *Transport) roundTrip(req *Request) (*Response, error) {
}
// treq gets modified by roundTrip, so we need to recreate for each retry.
treq := &transportRequest{Request: req, trace: trace}
treq := &transportRequest{Request: req, trace: trace, cancelKey: cancelKey}
cm, err := t.connectMethodForRequest(treq)
if err != nil {
req.closeBody()
@ -559,7 +568,7 @@ func (t *Transport) roundTrip(req *Request) (*Response, error) {
// to send it requests.
pconn, err := t.getConn(treq, cm)
if err != nil {
t.setReqCanceler(req, nil)
t.setReqCanceler(cancelKey, nil)
req.closeBody()
return nil, err
}
@ -567,7 +576,7 @@ func (t *Transport) roundTrip(req *Request) (*Response, error) {
var resp *Response
if pconn.alt != nil {
// HTTP/2 path.
t.setReqCanceler(req, nil) // not cancelable with CancelRequest
t.setReqCanceler(cancelKey, nil) // not cancelable with CancelRequest
resp, err = pconn.alt.RoundTrip(req)
} else {
resp, err = pconn.roundTrip(treq)
@ -753,14 +762,14 @@ func (t *Transport) CloseIdleConnections() {
// cancelable context instead. CancelRequest cannot cancel HTTP/2
// requests.
func (t *Transport) CancelRequest(req *Request) {
t.cancelRequest(req, errRequestCanceled)
t.cancelRequest(cancelKey{req}, errRequestCanceled)
}
// Cancel an in-flight request, recording the error value.
func (t *Transport) cancelRequest(req *Request, err error) {
func (t *Transport) cancelRequest(key cancelKey, err error) {
t.reqMu.Lock()
cancel := t.reqCanceler[req]
delete(t.reqCanceler, req)
cancel := t.reqCanceler[key]
delete(t.reqCanceler, key)
t.reqMu.Unlock()
if cancel != nil {
cancel(err)
@ -1093,16 +1102,16 @@ func (t *Transport) removeIdleConnLocked(pconn *persistConn) bool {
return removed
}
func (t *Transport) setReqCanceler(r *Request, fn func(error)) {
func (t *Transport) setReqCanceler(key cancelKey, fn func(error)) {
t.reqMu.Lock()
defer t.reqMu.Unlock()
if t.reqCanceler == nil {
t.reqCanceler = make(map[*Request]func(error))
t.reqCanceler = make(map[cancelKey]func(error))
}
if fn != nil {
t.reqCanceler[r] = fn
t.reqCanceler[key] = fn
} else {
delete(t.reqCanceler, r)
delete(t.reqCanceler, key)
}
}
@ -1110,17 +1119,17 @@ func (t *Transport) setReqCanceler(r *Request, fn func(error)) {
// for the request, we don't set the function and return false.
// Since CancelRequest will clear the canceler, we can use the return value to detect if
// the request was canceled since the last setReqCancel call.
func (t *Transport) replaceReqCanceler(r *Request, fn func(error)) bool {
func (t *Transport) replaceReqCanceler(key cancelKey, fn func(error)) bool {
t.reqMu.Lock()
defer t.reqMu.Unlock()
_, ok := t.reqCanceler[r]
_, ok := t.reqCanceler[key]
if !ok {
return false
}
if fn != nil {
t.reqCanceler[r] = fn
t.reqCanceler[key] = fn
} else {
delete(t.reqCanceler, r)
delete(t.reqCanceler, key)
}
return true
}
@ -1324,12 +1333,12 @@ func (t *Transport) getConn(treq *transportRequest, cm connectMethod) (pc *persi
// set request canceler to some non-nil function so we
// can detect whether it was cleared between now and when
// we enter roundTrip
t.setReqCanceler(req, func(error) {})
t.setReqCanceler(treq.cancelKey, func(error) {})
return pc, nil
}
cancelc := make(chan error, 1)
t.setReqCanceler(req, func(err error) { cancelc <- err })
t.setReqCanceler(treq.cancelKey, func(err error) { cancelc <- err })
// Queue for permission to dial.
t.queueForDial(w)
@ -2078,7 +2087,7 @@ func (pc *persistConn) readLoop() {
}
if !hasBody || bodyWritable {
pc.t.setReqCanceler(rc.req, nil)
pc.t.setReqCanceler(rc.cancelKey, nil)
// Put the idle conn back into the pool before we send the response
// so if they process it quickly and make another request, they'll
@ -2151,7 +2160,7 @@ func (pc *persistConn) readLoop() {
// reading the response body. (or for cancellation or death)
select {
case bodyEOF := <-waitForBodyRead:
pc.t.setReqCanceler(rc.req, nil) // before pc might return to idle pool
pc.t.setReqCanceler(rc.cancelKey, nil) // before pc might return to idle pool
alive = alive &&
bodyEOF &&
!pc.sawEOF &&
@ -2165,7 +2174,7 @@ func (pc *persistConn) readLoop() {
pc.t.CancelRequest(rc.req)
case <-rc.req.Context().Done():
alive = false
pc.t.cancelRequest(rc.req, rc.req.Context().Err())
pc.t.cancelRequest(rc.cancelKey, rc.req.Context().Err())
case <-pc.closech:
alive = false
}
@ -2408,9 +2417,10 @@ type responseAndError struct {
}
type requestAndChan struct {
_ incomparable
req *Request
ch chan responseAndError // unbuffered; always send in select on callerGone
_ incomparable
req *Request
cancelKey cancelKey
ch chan responseAndError // unbuffered; always send in select on callerGone
// whether the Transport (as opposed to the user client code)
// added the Accept-Encoding gzip header. If the Transport
@ -2472,7 +2482,7 @@ var (
func (pc *persistConn) roundTrip(req *transportRequest) (resp *Response, err error) {
testHookEnterRoundTrip()
if !pc.t.replaceReqCanceler(req.Request, pc.cancelRequest) {
if !pc.t.replaceReqCanceler(req.cancelKey, pc.cancelRequest) {
pc.t.putOrCloseIdleConn(pc)
return nil, errRequestCanceled
}
@ -2524,7 +2534,7 @@ func (pc *persistConn) roundTrip(req *transportRequest) (resp *Response, err err
defer func() {
if err != nil {
pc.t.setReqCanceler(req.Request, nil)
pc.t.setReqCanceler(req.cancelKey, nil)
}
}()
@ -2540,6 +2550,7 @@ func (pc *persistConn) roundTrip(req *transportRequest) (resp *Response, err err
resc := make(chan responseAndError)
pc.reqch <- requestAndChan{
req: req.Request,
cancelKey: req.cancelKey,
ch: resc,
addedGzip: requestedGzip,
continueCh: continueCh,
@ -2591,10 +2602,10 @@ func (pc *persistConn) roundTrip(req *transportRequest) (resp *Response, err err
}
return re.res, nil
case <-cancelChan:
pc.t.CancelRequest(req.Request)
pc.t.cancelRequest(req.cancelKey, errRequestCanceled)
cancelChan = nil
case <-ctxDoneChan:
pc.t.cancelRequest(req.Request, req.Context().Err())
pc.t.cancelRequest(req.cancelKey, req.Context().Err())
cancelChan = nil
ctxDoneChan = nil
}

View File

@ -2364,6 +2364,50 @@ func TestTransportCancelRequest(t *testing.T) {
}
}
func testTransportCancelRequestInDo(t *testing.T, body io.Reader) {
setParallel(t)
defer afterTest(t)
if testing.Short() {
t.Skip("skipping test in -short mode")
}
unblockc := make(chan bool)
ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
<-unblockc
}))
defer ts.Close()
defer close(unblockc)
c := ts.Client()
tr := c.Transport.(*Transport)
donec := make(chan bool)
req, _ := NewRequest("GET", ts.URL, body)
go func() {
defer close(donec)
c.Do(req)
}()
start := time.Now()
timeout := 10 * time.Second
for time.Since(start) < timeout {
time.Sleep(100 * time.Millisecond)
tr.CancelRequest(req)
select {
case <-donec:
return
default:
}
}
t.Errorf("Do of canceled request has not returned after %v", timeout)
}
func TestTransportCancelRequestInDo(t *testing.T) {
testTransportCancelRequestInDo(t, nil)
}
func TestTransportCancelRequestWithBodyInDo(t *testing.T) {
testTransportCancelRequestInDo(t, bytes.NewBuffer([]byte{0}))
}
func TestTransportCancelRequestInDial(t *testing.T) {
defer afterTest(t)
if testing.Short() {

View File

@ -6,8 +6,8 @@ To update the .syso files use golang.org/x/build/cmd/racebuild.
race_darwin_amd64.syso built with LLVM 3496d6e4bea9cb99cb382939b7e79a50a3b863a5 and Go 553e003414d3aa90cc39830ee22f08453d9f3408.
race_freebsd_amd64.syso built with LLVM 3496d6e4bea9cb99cb382939b7e79a50a3b863a5 and Go 553e003414d3aa90cc39830ee22f08453d9f3408.
race_linux_amd64.syso built with LLVM 3496d6e4bea9cb99cb382939b7e79a50a3b863a5 and Go 553e003414d3aa90cc39830ee22f08453d9f3408.
race_linux_ppc64le.syso built with LLVM 3496d6e4bea9cb99cb382939b7e79a50a3b863a5 and Go 553e003414d3aa90cc39830ee22f08453d9f3408.
race_linux_amd64.syso built with LLVM 6c75db8b4bc59eace18143ce086419d37da24746 and Go 7388956b76ce15a11346cebefcf6193db044caaf.
race_linux_ppc64le.syso built with LLVM 6c75db8b4bc59eace18143ce086419d37da24746 and Go 7388956b76ce15a11346cebefcf6193db044caaf.
race_netbsd_amd64.syso built with LLVM 3496d6e4bea9cb99cb382939b7e79a50a3b863a5 and Go 553e003414d3aa90cc39830ee22f08453d9f3408.
race_windows_amd64.syso built with LLVM 3496d6e4bea9cb99cb382939b7e79a50a3b863a5 and Go 553e003414d3aa90cc39830ee22f08453d9f3408.
race_linux_arm64.syso built with LLVM 3496d6e4bea9cb99cb382939b7e79a50a3b863a5 and Go 553e003414d3aa90cc39830ee22f08453d9f3408.
race_linux_arm64.syso built with LLVM 6c75db8b4bc59eace18143ce086419d37da24746 and Go 7388956b76ce15a11346cebefcf6193db044caaf.

View File

@ -0,0 +1,39 @@
// Copyright 2020 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 !android,!js,!ppc64le
// Note: we don't run on Android or ppc64 because if there is any non-race test
// file in this package, the OS tries to link the .syso file into the
// test (even when we're not in race mode), which fails. I'm not sure
// why, but easiest to just punt - as long as a single builder runs
// this test, we're good.
package race
import (
"bytes"
"os/exec"
"path/filepath"
"runtime"
"testing"
)
func TestIssue37485(t *testing.T) {
files, err := filepath.Glob("./*.syso")
if err != nil {
t.Fatalf("can't find syso files: %s", err)
}
for _, f := range files {
cmd := exec.Command(filepath.Join(runtime.GOROOT(), "bin", "go"), "tool", "nm", f)
res, err := cmd.CombinedOutput()
if err != nil {
t.Errorf("nm of %s failed: %s", f, err)
continue
}
if bytes.Contains(res, []byte("getauxval")) {
t.Errorf("%s contains getauxval", f)
}
}
}