-
Notifications
You must be signed in to change notification settings - Fork 2.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
go:linkname
(de)stabilization
#16015
Comments
This usually ends up being a maintenance nightmare though. We'd have to update manually on each |
Tnx, this also surfaced with the testing of recently released Go 1.23 rc1 in: |
Fwiw, this is not going to be in a Vitess release soon yet (v21 is still a bit out, v20 is due very shortly). So Homebrew would either use our pre-built release binaries, build with Go 1.22 (since that's also what is supported to build with atm) or carry their own patches for this. |
Those homebrew formulae that will still be failing at the time of Go 1.23 release will likely be pinned to Go 1.22 for building until they are made compatible with the current (then) stable Go release. |
Fwiw, I fully expect that we will build Vitess with
@vmg I'm realizing that this is not actually enough. The issue is not just about testing. We disable the randomization also for JSON marshaling. I think that randomized field ordering and random spaces injected into vschemas that end-users interact with is not really an acceptable solution.
It's either this, or we keep basically |
FWIW, for now at least the linkname restriction only applies to names in the standard library. You can linkname DisableProtoBufRandomness without any special flags. Whether you should is a different question, of course. I recently hit the same problem and while I did use a linkname for about five minutes, I decided in the end to run the JSON through json.Compact in my tests instead. |
fwiw, at work we're currently using |
This usage is removed in #16016. You can update to latest |
Will #16016 be backported to the current release branch, or do we need to wait until the next major release? |
@seveas It won't be backported. We also don't backport Go major upgrades normally, so it's not necessary for that. It will be in the next major release though which also will use Go 1.23. Existing releases will keep using the Go version that they are on. |
Ack, we temporarily switched one of our projects' go.mod to use the main branch for now and will change back to released versions when the next major version is out. Other projects are using the ldflags workaround, both approaches allow us to upgrade our projects to go 1.23 |
use "go" again after vitessio/vitess#16015 is fixed and released Follow-up to #175310
Upgrading dependences to use Go 1.23 resorts in linker errors, so this pins Vitess to the latest commit in `main` which has fixes to remove `runtime.roundupsize` from the linker. See vitessio/vitess#16015 for more information.
This was fixed in Fix confirmed in |
Fresh off the press, the upcoming Go 1.23 release will ship with some annoying changes to the linker.
Here's the full issue: golang/go#67401
As a summary, the Go authors are concerned by the prevalent use of
go:linkname
throughout the Go ecosystem to access the internals of the runtime. They intend to hamper the usage of this feature in the upcoming release by adding a strict check, so that only runtime symbols that have been explicitly exported inside the runtime can be accessed externally viago:linkname
. To prevent further breakage of the ecosystem, they've scanned the top N most popular Go packages and whitelisted theirgo:linkname
symbol dependencies so they can continue to be linked externally for the foreseeable future.Unfortunately for us, Vitess makes some mild use of
go:linkname
and it's not in the top N packages that have been scanned: although Vitess is plenty popular as an OSS project, their scan measures popularity by number of dependant packages. As a "top level" application, there's very few projects that havevitessio/vitess
as ago.mod
dependency. So we're screwed this way.On the other hand, as a top level package, we have access to a new flag in
ldflags
that allows us (and will always allow, as it'll become part of the Go compatibility guarantees) to disable the whitelisted export checks and access the Go internals indiscriminately. We can always choose to build Vitess with this flag, and we may need to do so in the short term as soon as we upgrade to Go 1.23.Regardless, I think it'd be a good idea to create a tracking issue to enumerate all our
go:linkname
dependencies and eventually remove all of them until we can compile Vitess with the strict linker checks in Go 1.23.//go:linkname strhash runtime.strhash
(hack/runtime.go
): this function is now exported in the new hash packages in the stdlib so there’s no reason to continue to link to it this way.//go:linkname roundupsize runtime.roundupsize
(hack/runtime.go
): this function is kinda important and has not been whitelisted in Go 1.23 for external usage. We use it as part of our caching infrastructure to calculate very accurate measurements for how much memory do cached objects occupy. Thesizeof
of a Go struct is not the actual amount of memory it occupies, because all structs are rounded up to the GC’s allocation sizes; by accessing this internal method, we can calculate the exact memory usage of each allocation in the cache. There are two options here:Sizeof(OUR STRUCT)
is the size it’ll occupy in memory. This will under-report memory usage, but how much of a big deal is it?//go:linkname Atof64 strconv.atof64
,//go:linkname Atof32 strconv.atof32
(hack/runtime.go
): these arestrconv
methods that parse a floating point value and return how many characters were parsed. The public methods exported in thestrconv
package will error out if there’s any trailing data after the floating point value, but this is not MySQL’s behavior, so we need access to this internal method. This doesn’t look like it’ll be whitelisted, but it’s very little code: we should vendor it in theparse
package. Upon further review, these methods implicitly support parsing hexadecimal floating point numbers, something which MySQL does not, so we might as well vendor them and remove this extra functionality that doesn’t match MySQL’s.//go:linkname ParseFloatPrefix strconv.parseFloatPrefix
(go/hack/compat.go
): this is not used anywhere, we get to just remove it ✨//go:linkname writeBarrier runtime.writeBarrier
,//go:linkname atomicwb runtime.atomicwb
(atomic2/atomic128.go
): these methods are used to implement our own 128-bit atomic integers. They’ve actually been whitelisted already, so we can depend on them indefinitely. Furthermore, we’ll only need to keep this implementation temporarily, as 128 bit atomics have been approved for an upcoming Go release, they’re just missing an implementation. As soon as they’re in the standard library we can remove our implementation.//go:linkname sync_runtime_Semacquire sync.runtime_Semacquire
,//go:linkname sync_runtime_Semrelease sync.runtime_Semrelease
(smartconnpool/sema_norace.go
): these are an important but not crucial performance optimization for our connection pool implementation. The methods appear to be whitelisted in the Go standard library, but they use a specific linkage name, so it’s not clear to me whether they can be accessed by Vitess or only by the explicit packages where they’re exported. Regardless, the usage of semaphores can be replaced withsync.WaitGroup
, which is slightly less efficient.//go:linkname DisableProtoBufRandomness google.golang.org/protobuf/internal/detrand.Disable
(hack/detrand.go
): Oh boy. You can see the story behind this linkname in the file where’s it’s created:vitess/go/hack/detrand.go
Lines 23 to 41 in 3773563
protobuf
package that changes one line of code, which is annoying but also very little work.The text was updated successfully, but these errors were encountered: