Functions using linkname are checked via checklinkname. Noescape has no
automatic check anymore, but if a future version of Go invalidates the
implementation, the result will be values escaping to the heap (performance
loss), rather than memory corruption, so I think having no check is OK.
PiperOrigin-RevId: 505173611
unsafe.String and unsafe.StringData provide compatibility guarantees that don't
require us to verify compatibility in each release.
For #8422.
PiperOrigin-RevId: 505150667
All remaining uses of gohacks.SliceHeader are to create a slice pointing to
some other backing array. Go 1.20 introduces unsafe.Slice to do exactly this,
so switch to this interface.
For now we want code to continue to build with Go 1.19, so we still use a
gohacks.Slice wrapper, which uses unsafe.Slice on 1.20 and SliceHeader on
<1.20. Once 1.19 support is dropped, uses can drop gohacks altogether.
gohacks.Slice is inlined into callers, and unsafe.Slice is a compiler
intrinsic, so these wrappers have minimal overhead. The primary difference is
the addition of a nil check on the pointer and an overflow check on
ptr+length*size.
I think these are minimal enough to not cause problems, but if they are (e.g.,
in safemem), we could consider adding a SliceUnchecked function that continues
to use SliceHeader. But I'd like to try to avoid that, as it adds process to
verify it is still compatible with new Go releases.
For #8422.
PiperOrigin-RevId: 504926819
Timer metrics are metrics that measure nanosecond-precision operations within
the sentry, and present the results in an aggregated manner using distribution
bucketing.
They have a more convenient API than using distribution metrics directly, but
otherwise are just a convenient wrapper on top of them.
This requires exposing `runtime.nanotime()` from the Go runtime in order to
get the current time without causing system calls.
Intended usage:
```go
m := NewTimerMetric(...)
...
op := m.Start() // Starts measuring time from this point
... do something interesting...
op.Finish() // End the stopwatch.
```
Operation structs are meant to be self-contained to be able to be passed
around in code. Additionally, the timer metrics support multiple fields,
specifiable both at operation `Start` and `Finish` time.
This can be useful for measuring operations that can go down multiple
distinct branches, and creating aggregates that can selectively
differentiate between them. For example:
```go
m := NewTimerMetric("/packet_processing_time", ..., "protocol", "path")
...
func HandleTCPPacket(pkt TCPPacket) {
op := m.Start("tcp")
if fast path {
... do fast TCP handling...
op.Finish("fast")
return
}
doSlowTCPHandling(pkt, op) // `op` can be passed around
}
func doSlowTCPHandling(pkt TCPPacket, op TimerOperation) {
... do slow TCP handling...
op.Finish("slow")
}
func HandleUDPPacket(pkt UDPPacket) {
op := m.Start("udp")
... do UDP packet handling...
op.Finish("")
}
```
PiperOrigin-RevId: 436641265
Upstream Go tip has updated its version to 1.19, so we need to bump these build
tags to allow tip testing.
This CL bumps the minimum version in pkg/sync/runtime_amd64.s from 1.8 to 1.14.
The offset was different prior to Go 1.14.
Ideally we'll get checklinkname (or equivalent) to check these remaining unsafe
uses (like internal struct field offsets) soon.
For golang/go#51445.
PiperOrigin-RevId: 433304124
Go's dev.typeparams branch already claims to be Go 1.18, so our !go1.18 build
tags breaking testing gVisor with that branch.
Normally I would not want to bump the build tags this early, but I plan to
extend checklinkname to check the assumptions in these files and remove the
build tags ASAP. So we just go ahead and bump the tags until then to unblock
testing.
PiperOrigin-RevId: 389037239
This CL introduces a 'checklinkname' analyzer, which provides rudimentary
type-checking that verifies that function signatures on the local and remote
sides of //go:linkname directives match expected values.
If the Go standard library changes the definitions of any of these function,
checklinkname will flag the change as a finding, providing an error informing
the gVisor team to adapt to the upstream changes. This allows us to eliminate
the majority of gVisor's forward-looking negative build tags, as we can catch
mismatches in testing [1].
The remaining forward-looking negative build tags are covering shared struct
definitions, which I hope to add to checklinkname in a future CL.
[1] Of course, semantics/requirements can change without the signature
changing, so we still must be careful, but this covers the common case.
PiperOrigin-RevId: 387873847
See https://github.com/golang/go/issues/19367 for rationale. Note that the
upstream decision arrived at in that thread, while useful for some of our use
cases, doesn't account for all of our SliceHeader use cases (we often use
SliceHeader to extract pointers from slices in a way that avoids bounds
checking and/or handles nil slices correctly) and also doesn't exist yet.
PiperOrigin-RevId: 358071574
Previously, it was not possible to encode/decode an object graph which
contained a pointer to a field within another type. This was because the
encoder was previously unable to disambiguate a pointer to an object and a
pointer within the object.
This CL remedies this by constructing an address map tracking the full memory
range object occupy. The encoded Refvalue message has been extended to allow
references to children objects within another object. Because the encoding
process may learn about object structure over time, we cannot encode any
objects under the entire graph has been generated.
This CL also updates the state package to use standard interfaces intead of
reflection-based dispatch in order to improve performance overall. This
includes a custom wire protocol to significantly reduce the number of
allocations and take advantage of structure packing.
As part of these changes, there are a small number of minor changes in other
places of the code base:
* The lists used during encoding are changed to use intrusive lists with the
objectEncodeState directly, which required that the ilist Len() method is
updated to work properly with the ElementMapper mechanism.
* A bug is fixed in the list code wherein Remove() called on an element that is
already removed can corrupt the list (removing the element if there's only a
single element). Now the behavior is correct.
* Standard error wrapping is introduced.
* Compressio was updated to implement the new wire.Reader and wire.Writer
inteface methods directly. The lack of a ReadByte and WriteByte caused issues
not due to interface dispatch, but because underlying slices for a Read or
Write call through an interface would always escape to the heap!
* Statify has been updated to support the new APIs.
See README.md for a description of how the new mechanism works.
PiperOrigin-RevId: 318010298
pipe and pipe2 aren't ported, pending a slight rework of pipe FDs for VFS2.
mount and umount2 aren't ported out of temporary laziness. access and faccessat
need additional FSImpl methods to implement properly, but are stubbed to
prevent googletest from CHECK-failing. Other syscalls require additional
plumbing.
Updates #1623
PiperOrigin-RevId: 297188448