You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
TestIntendedInlining has been failing occasionally, for example here, with a report of functions not being inlined:
inl_test.go:273: math/big.addVW was not inlined: unknown reason
inl_test.go:273: math/big.subVW was not inlined: unknown reason
inl_test.go:273: math/big.bigEndianWord was not inlined: unknown reason
Unless the compiler is somehow nondeterministic (unlikely), this looks like a glitch in the test itself.
The test works by running go build -a '-gcflags=all=-m -m' packages..., and parsing the 8+ megabytes of output to look for some expected messages about function inlining. After modifying the test to tee the piped output into a strings.Builder, to be logged if the test fails, we can see what's going on:
... line 54312
# net
../../../../net/cgo_stub.go:11:6: can inline init.0 with cost 3 as: func() { netGo = true }
... line 57070
../../../../net/dial.go:628:15: from &OpError{...} (interface-converted) at ../../../../net/dial.go:628:15
../../../../net/dial.go:628:15: from return nil, &OpError{...} (return) at ../../../../ne# math/big
../../../../math/big/accuracy_string.go:11:6: cannot inline Accuracy.String: function too complex: cost 90 exceeds budget 80
... line 57843
../../../../math/big/nat.go:1t/dial.go:628:3
../../../../net/dial.go:625:53: parameter network leaks to {storage for &OpError{...}} with derefs=0:
../../../../net/dial.go:625:53: flow: {storage for &OpError{...}} = network:
... line 58575
../../../../net/hook.go:21:3: lea240:16: inlining call to nat.make
../../../../math/big/int.go:1211:6: can inline (*Int).Sqrt with cost 78 as: method(*Int) func(*Int) *Int { if x.neg { panic("square root of negative number") }; z.neg = false; z.abs = nat.sqrt(z.abs, x.abs); return z }
... and so on
It seems the output from parallel builds is being interleaved. In line 57071, the label for the start of output for package math/big interrupts a partial line from package net, so the parser doesn't recognise the label and misses the inlining messages from math/big.
The Builder struct has a mutex which is supposed to prevent interleaving of output. For example in cmd/go/internal/work/exec.go we see:
func (b *Builder) Showcmd(dir string, format string, args ...interface{}) {
b.output.Lock()
defer b.output.Unlock()
b.Print(b.fmtcmd(dir, format, args...) + "\n")
}
But it turns out that the lock is not being applied consistently. In cmd/go/internal/work/buildid.go we see:
Two possible remedies come to mind:
(a) do the Lock/Unlock inside the (*Builder).Print function itself to ensure it's always used, or
(b) lock the mutex around any calls to Print which could produce an arbitrary amount of output (in particular, more than the limit for atomic writes to a pipe).
Choosing (a) would involve more locking than strictly necessary, so I'll submit a CL to do (b).
The text was updated successfully, but these errors were encountered:
TestIntendedInlining
has been failing occasionally, for example here, with a report of functions not being inlined:Unless the compiler is somehow nondeterministic (unlikely), this looks like a glitch in the test itself.
The test works by running
go build -a '-gcflags=all=-m -m' packages...
, and parsing the 8+ megabytes of output to look for some expected messages about function inlining. After modifying the test to tee the piped output into astrings.Builder
, to be logged if the test fails, we can see what's going on:It seems the output from parallel builds is being interleaved. In line 57071, the label for the start of output for package
math/big
interrupts a partial line from packagenet
, so the parser doesn't recognise the label and misses the inlining messages frommath/big
.The
Builder
struct has a mutex which is supposed to prevent interleaving of output. For example incmd/go/internal/work/exec.go
we see:But it turns out that the lock is not being applied consistently. In
cmd/go/internal/work/buildid.go
we see:Two possible remedies come to mind:
(a) do the
Lock
/Unlock
inside the(*Builder).Print
function itself to ensure it's always used, or(b) lock the mutex around any calls to
Print
which could produce an arbitrary amount of output (in particular, more than the limit for atomic writes to a pipe).Choosing (a) would involve more locking than strictly necessary, so I'll submit a CL to do (b).
The text was updated successfully, but these errors were encountered: