当前位置: 首页 > 科技观察

Go1.18新特性:编译后的二进制文件将包含更多信息

时间:2023-03-13 19:12:45 科技观察

大家好,我是建宇。我有一个朋友,他很高兴地进入了工作岗位,想要展示自己的实力。第一项任务是对旧的二进制文件进行研究。他看到这个文件的时候,不知道编译器用的是什么参数,是怎么编译的,环境是什么,更不知道是从哪个代码分支来的?这不仅是项目过程中的问题,Go也有类似的小问题,处理起来比较麻烦。背景每天都很难从Go二进制文件中检索元信息,要么信息完全丢失,要么提取需要对二进制文件进行大量解析。包含的元信息如下:在元信息提取点去构建版本符号表,通过全局变量runtime.buildVersion获取构建信息,例如:模块和版本符号表,通过全局变量runtime/debug.modinfo获取编译器选项,如:buildmode,compiler,gcflags,ldflags等。无法获取用户自定义的自定义数据,如:应用程序版本等。需要在编译前设置全局字符串变量才可以可以注意compile的编译器选项,也就是参数等都是未知的,这意味着会增加获取如何编译它的难度。NewProposalMichaelObermüller提出了一个新的提案《cmd/go: add compiler flags, relevant env vars to 'go version -m' output》来解决上述问题。提案中需要的是JSON格式的结构化输出:{"version":"go1.13.4","compileropts":{"compiler":"gc","mode":"pie","os":"linux",...},"buildinfo":{"path":"我的脑子炸了","main":{"path":"HelloWorld","version":"(devel)",},"deps":[]},"user":{"customkey":"customval",...}}RussCox表示,由于编译信息已经有了现成的格式,默认使用JSON只会让二进制文件更大的。好处少,也没有必要。它已更改为可选支持。在新的Go1.18版本中,可以通过现有的:goversion-m查看提案中提到的信息。例如:$gotipversiongoversiondevelgo1.18-eba0e866faMonOct1822:56:072021+0000darwin/amd64$gotipbuild./$gotipversion-mko...buildcompilergcbuildtagsgoexperiment.regabiwrappers,goexperiment.regabireflect,goexperiment.regabiargsbuildCGO_ENABLEDtruebuildCGO_CPPFLAGSbuildCGO_CFLAGSbuildCGO_CXXFLAGSbuildCGO_LDFLAGSbuildgitrevision6447264ff8b5d48aff64000f81bb0847aefc7bacbuildgituncommittedtrue若需要输出JSON格式,也可以通过指定goversion-json达到一样的效果。Intheaboveoutput,the现有的编译器选项等都会被包含进来,让大家对整体编译后的二进制文件的可追溯性有更好的了解。总结在今天的文章中,我介绍了Go1.18的一个新变化。在新版本中,编译器选项/参数、相关环境变量等都将包含在编译后的二进制文件中,方便后人排查问题和查看信息。