【发布时间】:2021-10-29 17:37:45
【问题描述】:
我试图提交错误报告 (https://github.com/golang/go/issues/48081) 但被发送到这里。
我正在尝试静态链接二进制文件,即使没有操作二进制文件也遇到了陷阱问题。
$ go version
go version go1.17 linux/amd64
请注意,我使用的是 docker golang:1.17-buster 图像,但这也适用于 1.16。
$ go env
GO111MODULE=""
GOARCH="amd64"
GOBIN=""
GOCACHE="/root/.cache/go-build"
GOENV="/root/.config/go/env"
GOEXE=""
GOEXPERIMENT=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOINSECURE=""
GOMODCACHE="/go/pkg/mod"
GONOPROXY=""
GONOSUMDB=""
GOOS="linux"
GOPATH="/go"
GOPRIVATE=""
GOPROXY="https://proxy.golang.org,direct"
GOROOT="/usr/local/go"
GOSUMDB="sum.golang.org"
GOTMPDIR=""
GOTOOLDIR="/usr/local/go/pkg/tool/linux_amd64"
GOVCS=""
GOVERSION="go1.17"
GCCGO="gccgo"
AR="ar"
CC="gcc"
CXX="g++"
CGO_ENABLED="1"
GOMOD="/dev/null"
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build838287027=/tmp/go-build -gno-record-gcc-switches"
我尝试静态编译一个简单的主文件:
$ cat go.mod
module naphatkrit/go-bug-repro
go 1.17
$ cat main.go
package main
func main() {
}
然后我使用静态链接我的二进制文件所需的标志运行 go build,这导致无法找到 cgo 的警告。
$ go build -a -v -o /tmp/my-binary -ldflags "-linkmode external -extldflags -static" -trimpath .
runtime/internal/sys
internal/goexperiment
internal/cpu
internal/abi
runtime/internal/atomic
runtime/internal/math
internal/bytealg
runtime
naphatkrit/go-bug-repro
# naphatkrit/go-bug-repro
loadinternal: cannot find runtime/cgo
执行二进制会导致陷阱错误
$ /tmp/my-binary
Trace/breakpoint trap
此外,以下是 strace 显示的内容:
root@3f441e3ed41c:/code# strace /tmp/my-binary
execve("/tmp/my-binary", ["/tmp/my-binary"], 0x7fff5db80d00 /* 10 vars */) = 0
brk(NULL) = 0xf03000
brk(0xf041c0) = 0xf041c0
arch_prctl(ARCH_SET_FS, 0xf03880) = 0
uname({sysname="Linux", nodename="3f441e3ed41c", ...}) = 0
readlink("/proc/self/exe", "/tmp/my-binary", 4096) = 14
brk(0xf251c0) = 0xf251c0
brk(0xf26000) = 0xf26000
arch_prctl(ARCH_SET_FS, 0x55fd90) = 0
--- SIGTRAP {si_signo=SIGTRAP, si_code=SI_KERNEL} ---
+++ killed by SIGTRAP +++
Trace/breakpoint trap
如果我强行包含 runtime/cgo,构建警告消失,编译后的二进制文件运行良好。
$ cat main.go
package main
import _ "runtime/cgo"
func main() {
}
$ go build -a -v -o /tmp/my-binary -ldflags "-linkmode external -extldflags -static" -trimpath .
internal/race
runtime/internal/sys
internal/abi
internal/cpu
internal/goexperiment
runtime/internal/atomic
sync/atomic
runtime/internal/math
internal/bytealg
runtime
sync
runtime/cgo
naphatkrit/go-bug-repro
$ /tmp/my-binary
$
我做的静态链接错了吗?
为方便起见,我已在https://github.com/naphatkrit/go-bug-repro 发布了我的repro
编辑:我意识到我过于简化了我的重现,这有损于我所面临的问题。我正在尝试做的是静态链接使用net 的二进制文件并关闭其 cgo 使用。
特别是,请考虑一下,看看它与上述问题有何相同:
package main
import _ "net"
func main() {
}
$ go build -a -v -o /tmp/gobuild -ldflags "-linkmode external -extldflags -static" -trimpath -tags 'netgo' .
...
loadinternal: cannot find runtime/cgo
$ /tmp/gobuild
Trace/breakpoint trap
【问题讨论】:
标签: go