Prologue
go 1.20 was released on Feb, 2, 2023, which includes some language changes, improvements to tooling and the library, and better overall performance.
However, there’s a thing to notice once you start upgrading you projects to go1.20 toolchain.
The problem
Starting in go1.20, global error created by calling errors.New will be laid out in static data:
$ cat p.go
package p
import "errors"
var FooErr = errors.New("foo")
$ go1.19.5 build -gcflags=-S p.go 2>&1 | grep -q stmp && echo laid out in static data
$ go1.20 build -gcflags=-S p.go 2>&1 | grep -q stmp && echo laid out in static data
laid out in static data
This will reduce the init time, have no link-time overhead, and open room for the linker to perform deadcode elimination.
However, after the release, there’re some regressions reported:
All of them releated to how the compiler handle the inline call at init time.
Though there’re some attempts to fix, and backported to 1.20.1 minor release, there’s still edge case discovered while working on fixing the code.
The conclusion is disabling the optimization for backporting to 1.20 release, then re-enable again during 1.21 development cycle, so we have more time to re-implement or fixing the code properly.
Solution
If you’re going to upgrade your go toolchain to 1.20, remember to add -gcflags=all=-d=inlstaticinit=0
to your CI process.
For 1.20.1 release, just upgrading as usual.
Epilogue
Admittedly, this issue is a bit embarrassing, it will be fixed in go1.20.1, and can be workaround without requiring user to make changes in the code. Please patient while the reported regressions are addressed.
And thank you all for reading so far!
Till next time!