今天从git上拉取了项目的最新代码,命令行中的 bee run 自动编译,运行
然而,这次却跟往常不一样,没有看到启动的输出,反而是丢了一个异常出来

取消 bee run 自动编译,换成 go run main.go 希望获取蛛丝马迹。便获取了如下信息:

1
2
bin/ld.exe: Error: export ordinal too large: 75040
collect2.exe: error: ld returned 1 exit status

于是撸起袖子,开始解决问题

最开始想从提交的代码中,查看是否有异常。但是大概翻了近几天的提交,没发现有价值的线索。
于是

分析问题

简单过了一下脑子,可能有如下几个问题引发的该bug

  1. 新引入了第三方的库,必须使用新版本的GCC
  2. Golang的bug
  3. 本地环境问题
  4. 代码问题

简单排查

问题一: 可以通过升级排查
问题二: 可以通过升级排查
问题三: 同事的编译结果对比
问题四: 检查每一个提交

询问同事后,得出的结果为:可以正常运行,有的则不行。
则将重点放在了问题一和问题二上了(也是最容易解决的)

着手解决

从互联网获取经验

升级GolangSDK

Github 发现有开发者碰到了一样的问题,但是似乎官方已经修复了这个问题。
抱着试试的态度,升级了本地SDK。然并卵,涛声依旧

修改build-mode

开发者解释说:新版的SDK中,可以将build-mode传给gcc,可以解决类似的问题。
于是尝试了如下三个值

1
2
3
go run main.go -build-mode=exe
go run main.go -build-mode=c-shared
go run main.go -build-mode=pie

然而它像钉子户一样,仍然停留在console窗口中

升级GCC

在做上面的流程的时候,也同时询问了做C++的同事。

“在C/C++中有没有这样的说法,单个exe中,函数不能超过多少个”

为什么会有这样的问题呢,因为Android中就有函数个数的限制,所以才有了“Multidex”这样的解决方案。
我们的项目开发了接近两年了,是否也碰到了类似的天花板。
(如果真是这个问题的话,那就要加快推进微服务化拆分)

同事的答复:

没有

并且在看过我的异常后,给出的建议是,可能是配置的问题

检查代码

既然最简单的方法都试过了,那就比对代码吧

  1. 切换到每次提交的版本上,运行项目。直到找到不报错的版本
  2. 使用 BCompare 查看该正常版本,与最近的报错版本之间有什么改动
1
2
3
4
5
6
7
8
9
10
11
12
import "C"
import (
"fmt"
"github.com/astaxie/beego"
"github.com/astaxie/beego/logs"
"github.com/astaxie/beego/orm"
"strings"
"sync"
"time"
)
// 具体业务代码
...

终于发现了不太正常的部分 import "C"
去掉之后,happy ending

复盘

这个是一个代码自动补全的坑
场景如下:
敲击代码的时候,输入了c,还没有键入后续单词内容。接着手动触发了自动补全。于是乎,自动 import

结语

果然是自己动手,丰衣足食。别人跑着没问题,不代表代码没有问题