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二选一
打包对比
- 未作任何优化
- 优化混淆版本