Which version of Go was used to compile this binary?
Sometimes it can be handy to work out what version of Go a given binary was complied with, for instance to find out if it's affected by any CVEs.
One option we can follow is this post, where we can dig into the binary with a debugger:
### NOTE that can be unsafe, as it requires actually parsing the file
gdb `which gopls`
(gdb) p 'runtime.buildVersion'
$1 = 0x4d8f78 "go1.20.4"
This can be a little awkward, and as mentioned, can be unsafe, so what about if we follow this StackOverflow and use go version
?
% go version `which zsh`
/usr/bin/zsh: could not read Go build info from /usr/bin/zsh: not a Go executable
% go version `which gopls`
/usr/bin/gopls: go1.21.0
Finally, we could also follow the Go source code for the version
command and see that it uses the debug/buildinfo#ReadFile
method, which means we can write a similar piece of code:
package main
import (
"debug/buildinfo"
"fmt"
"os"
)
func main() {
f, err := buildinfo.ReadFile(os.Args[1])
if err != nil {
log.Fatal(err)
}
fmt.Printf("f.GoVersion: %v\n", f.GoVersion)
}
Which gives us a purely programmatic way of determining this version, which outputs i.e.
% go run main.go `which zsh`
2023/10/14 14:07:52 could not read Go build info from /usr/bin/zsh: not a Go executable
exit status 1
% go run main.go `which gopls`
f.GoVersion: go1.21.0