Golang构建过程中遇到的无效汇编代码问题
Golang构建过程中遇到的无效汇编代码问题 为什么 Go 无法正常工作?
go -version go version go1.10.3 gccgo (GCC) 8.2.0 linux/arm
hello.go 文件内容:
package main
import "fmt"
func main() {
fmt.Println("Hello, world.")
}
当我执行
Go build -work hello.go
得到以下输出:
pi@raspberrypi-Desktop:~/go/src/github.com/ctday/learning/hello$ go build -work hello.go
WORK=/tmp/go-build950159161
command-line-arguments
/tmp/go-build950159161/b001/_buildid.s: 汇编器消息:
/tmp/go-build950159161/b001/_buildid.s:8: 错误:行尾出现无效字符,第一个无法识别的字符是,
/tmp/go-build950159161/b001/_buildid.s:9: 错误:行尾出现无效字符,第一个无法识别的字符是,
生成的汇编文件内容:
pi@raspberrypi-Desktop:/tmp/go-build950159161/b001$ less _buildid.s
.section .go.buildid,"e"
.byte 0x31,0x45,0x77,0x53,0x6a,0x55,0x76,0x6d
.byte 0x35,0x36,0x58,0x50,0x54,0x67,0x6a,0x39
.byte 0x34,0x74,0x53,0x42,0x2f,0x31,0x45,0x77
.byte 0x53,0x6a,0x55,0x76,0x6d,0x35,0x36,0x58
.byte 0x50,0x54,0x67,0x6a,0x39,0x34,0x74,0x53
.byte 0x42
.section .note.GNU-stack,"",@progbits
.section .note.GNU-split-stack,"",@progbits
显然,.section 行是无效的。
更多关于Golang构建过程中遇到的无效汇编代码问题的实战教程也可以访问 https://www.itying.com/category-94-b0.html
更多关于Golang构建过程中遇到的无效汇编代码问题的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
这个问题是由于您使用的 GCC Go 编译器(gccgo)版本与 ARM 架构的汇编器兼容性问题导致的。特别是 .section 指令的语法在 ARM 平台的汇编器中可能不被正确支持。
以下是问题的具体分析和解决方案:
问题分析
生成的 _buildid.s 汇编文件包含以下指令:
.section .go.buildid,"e"
.section .note.GNU-stack,"",@progbits
.section .note.GNU-split-stack,"",@progbits
在 ARM 架构的汇编器中,.section 指令的语法可能不支持 "e" 和 @progbits 这样的参数格式,导致汇编器无法识别这些字符而报错。
解决方案
方案1:使用官方 Go 编译器
推荐使用官方的 Go 编译器而不是 gccgo:
# 下载官方 Go 编译器
wget https://golang.org/dl/go1.19.linux-armv6l.tar.gz
sudo tar -C /usr/local -xzf go1.19.linux-armv6l.tar.gz
export PATH=$PATH:/usr/local/go/bin
# 重新编译
go build hello.go
方案2:如果必须使用 gccgo,尝试更新 GCC 版本
# 更新系统包
sudo apt update
sudo apt upgrade
# 或者安装更新的 GCC 版本
sudo apt install gcc-9
方案3:修改编译标志
尝试使用不同的编译标志:
# 禁用构建 ID 生成
go build -ldflags="-buildid=" hello.go
# 或者使用静态链接
go build -ldflags="-linkmode=internal" hello.go
方案4:手动验证汇编文件
创建一个简单的测试汇编文件来验证问题:
# 创建测试文件 test.s
.section .text
.global _start
_start:
mov r0, #1
bx lr
然后使用 ARM 汇编器测试:
as test.s -o test.o
如果这个简单的汇编文件也无法编译,说明是系统汇编器的问题。
验证修复
修复后,使用以下命令验证:
package main
import "fmt"
func main() {
fmt.Println("Build successful!")
}
go build hello.go
./hello
预期输出:
Build successful!
这个问题主要是 gccgo 在 ARM 平台上的兼容性问题,切换到官方 Go 编译器通常能解决此类汇编相关的构建错误。

