1.去除程序调试符号

编译过程中使用-ldflags '-s -w' -trimpath去掉调试符号。

2.buildmode

编译过程中使用-buildmode=pie,生成地址无关的二进制文件(Go v1.6以后)。

https://github.com/golang/go/issues/35192
https://fedoraproject.org/wiki/Changes/golang-buildmode-pie

此模式生成的程序使用反编译插件不能很好的对其反编译。

3.竞争条件检测

只要在go build,go run或者go test命令后面加上-race的flag,就会使编译器创建一个你的应用的“修改”版或者一个附带了能够记录所有运行期对共享变量访问工具的test,并且会记录下每一个读或者写共享变量的goroutine的身份信息。另外,修改版的程序会记录下所有的同步事件,比如go语句,channel操作,以及对(*sync.Mutex).Lock,(*sync.WaitGroup).Wait等等的调用。(完整的同步事件集合是在The Go Memory Model文档中有说明,该文档是和语言文档放在一起的。译注:https://golang.org/ref/mem ) 竞争检查器会检查这些事件,会寻找在哪一个goroutine中出现了这样的case,例如其读或者写了一个共享变量,这个共享变量是被另一个goroutine在没有进行干预同步操作便直接写入的。这种情况也就表明了是对一个共享变量的并发访问,即数据竞争。这个工具会打印一份报告,内容包含变量身份,读取和写入的goroutine中活跃的函数的调用栈。这些信息在定位问题时通常很有用。

在编译中加上-race 即可进行竞争条件检测,生成的程序体积会比不加此参数生成的程序体积大点,而且不能被upx程序压缩(使用 -9最大化压缩会运行报错)。

注意: -race只能和-buildmode=pie二选一

fe4d90a900d801c59c93cfea1ba14574.png

打包对比

  • 未作任何优化
    f87c182956ffe5bac25ebb8ead05f437.png
  • 优化混淆版本
    70309258972bb85fcdab1bea3a120a89.png