【问题标题】:Go libstd.so with errors on AlpineGo libstd.so 在 Alpine 上出现错误
【发布时间】:2020-03-26 14:49:42
【问题描述】:

我正在尝试使用共享库构建一个 Go 可执行文件。在使用 GNU libc 的 Ubuntu 中,它可以工作。但是,当我尝试在使用 MUSL libc 的 Alpine(Docker 映像 golang:alpine 或 1.14.1-alpine3.11)上使用相同的过程时,生成的 libstd.so 被破坏了。之后,如果我尝试编译可执行文件,则编译失败。

这是程序:

$ docker run -it golang:alpine sh
/go # apk add --update alpine-sdk
fetch http://dl-cdn.alpinelinux.org/alpine/v3.11/main/x86_64/APKINDEX.tar.gz
fetch http://dl-cdn.alpinelinux.org/alpine/v3.11/community/x86_64/APKINDEX.tar.gz
(1/38) Installing fakeroot (1.24-r0)
(2/38) Installing sudo (1.8.31-r0)
(3/38) Installing libcap (2.27-r0)
(4/38) Installing pax-utils (1.2.4-r0)
(5/38) Installing openssl (1.1.1d-r3)
(6/38) Installing libattr (2.4.48-r0)
(7/38) Installing attr (2.4.48-r0)
(8/38) Installing libacl (2.2.53-r0)
(9/38) Installing tar (1.32-r1)
(10/38) Installing pkgconf (1.6.3-r0)
(11/38) Installing patch (2.7.6-r6)
(12/38) Installing libgcc (9.2.0-r4)
(13/38) Installing libstdc++ (9.2.0-r4)
(14/38) Installing lzip (1.21-r0)
(15/38) Installing nghttp2-libs (1.40.0-r0)
(16/38) Installing libcurl (7.67.0-r0)
(17/38) Installing curl (7.67.0-r0)
(18/38) Installing abuild (3.5.0-r0)
Executing abuild-3.5.0-r0.pre-install
(19/38) Installing binutils (2.33.1-r0)
(20/38) Installing libmagic (5.37-r1)
(21/38) Installing file (5.37-r1)
(22/38) Installing gmp (6.1.2-r1)
(23/38) Installing isl (0.18-r0)
(24/38) Installing libgomp (9.2.0-r4)
(25/38) Installing libatomic (9.2.0-r4)
(26/38) Installing mpfr4 (4.0.2-r1)
(27/38) Installing mpc1 (1.1.0-r1)
(28/38) Installing gcc (9.2.0-r4)
(29/38) Installing musl-dev (1.1.24-r2)
(30/38) Installing libc-dev (0.7.2-r0)
(31/38) Installing g++ (9.2.0-r4)
(32/38) Installing make (4.2.1-r2)
(33/38) Installing fortify-headers (1.1-r0)
(34/38) Installing build-base (0.5-r1)
(35/38) Installing expat (2.2.9-r1)
(36/38) Installing pcre2 (10.34-r1)
(37/38) Installing git (2.24.1-r0)
(38/38) Installing alpine-sdk (1.0-r0)
Executing busybox-1.31.1-r9.trigger
OK: 196 MiB in 53 packages
/go # go install -a -buildmode=shared -linkshared std
/go # ldd /usr/local/go/pkg/linux_amd64_dynlink/libstd.so 
    /lib/ld-musl-x86_64.so.1 (0x7f689af41000)
    libc.musl-x86_64.so.1 => /lib/ld-musl-x86_64.so.1 (0x7f689af41000)
Error relocating /usr/local/go/pkg/linux_amd64_dynlink/libstd.so: __libc_malloc: symbol not found
Error relocating /usr/local/go/pkg/linux_amd64_dynlink/libstd.so: __libc_realloc: symbol not found
Error relocating /usr/local/go/pkg/linux_amd64_dynlink/libstd.so: __libc_free: symbol not found
Error relocating /usr/local/go/pkg/linux_amd64_dynlink/libstd.so: main.main: symbol not found
Error relocating /usr/local/go/pkg/linux_amd64_dynlink/libstd.so: __libc_stack_end: symbol not found
/go # go version
go version go1.14.1 linux/amd64
/go # go env
GO111MODULE=""
GOARCH="amd64"
GOBIN=""
GOCACHE="/root/.cache/go-build"
GOENV="/root/.config/go/env"
GOEXE=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOINSECURE=""
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"
GCCGO="gccgo"
AR="ar"
CC="gcc"
CXX="g++"
CGO_ENABLED="1"
GOMOD=""
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-build202809585=/tmp/go-build -gno-record-gcc-switches"
/go # 

当我使用相同的 Golang 版本但其他具有 GNU libc 的发行版执行相同的过程时,它按预期工作:

$ docker run -it golang:buster sh
# go install -a -buildmode=shared -linkshared std
# ldd /usr/local/go/pkg/linux_amd64_dynlink/libstd.so
    linux-vdso.so.1 (0x00007ffe54bea000)
    libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f12f79a3000)
    libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f12f7982000)
    libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f12f77c1000)
    /lib64/ld-linux-x86-64.so.2 (0x00007f12fa0d2000)
# go version
go version go1.14.1 linux/amd64
# go env
GO111MODULE=""
GOARCH="amd64"
GOBIN=""
GOCACHE="/root/.cache/go-build"
GOENV="/root/.config/go/env"
GOEXE=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOINSECURE=""
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"
GCCGO="gccgo"
AR="ar"
CC="gcc"
CXX="g++"
CGO_ENABLED="1"
GOMOD=""
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-build609530787=/tmp/go-build -gno-record-gcc-switches"
# 

我是否遗漏了一些细节? Golang 或 Alpine 有 bug 吗?

【问题讨论】:

  • 我在 SO 上搜索了“[go] musl libc”并找到了这个,也许它会有所帮助:stackoverflow.com/questions/54524785/…
  • 试试这个solution
  • @Eldar 很有希望,但我遇到了同样的错误。谢谢。
  • @Adrian,情况并不完全相同,但我会尝试在 Ubuntu 上使用 MUSL 进行“交叉编译”,看看会发生什么。谢谢。

标签: go shared-libraries symbols alpine musl


【解决方案1】:

似乎 Go 运行时有一些明确的 GNU libc 依赖项,如链接错误所示:

Error relocating /usr/local/go/pkg/linux_amd64_dynlink/libstd.so: __libc_malloc: symbol not found
Error relocating /usr/local/go/pkg/linux_amd64_dynlink/libstd.so: __libc_realloc: symbol not found
Error relocating /usr/local/go/pkg/linux_amd64_dynlink/libstd.so: __libc_free: symbol not found
Error relocating /usr/local/go/pkg/linux_amd64_dynlink/libstd.so: main.main: symbol not found
Error relocating /usr/local/go/pkg/linux_amd64_dynlink/libstd.so: __libc_stack_end: symbol not found

轻量级 glibc 兼容性(安装 libc6-compat 包)在这种情况下可能不会做,因为它主要添加存根,并且仍然缺少一些 glibc 功能。

试图找到有问题的 Go 模块,在 go install -a -buildmode=shared -linkshared std 后面的 Go 构建缓存中挑选(.cache/go-build 下的目标文件,用 grep -R libc 寻找 glibc 依赖项),一个大的目标文件脱颖而出。使用nm 列出对象符号表明它是消耗所需符号的对象:

        U __libc_free
        U __libc_malloc
        U __libc_realloc
        U __libc_stack_end

那个对象原来是race.go

Google 搜索显示 Alpine libc 兼容性确实是一个已知的种族问题,记录在这里:
https://github.com/golang/go/issues/14481

幸运的是,票证中提到了几个建议的解决方法,例如从源代码构建 compiler-rt。

【讨论】:

  • 非常感谢。我自己不会得出这个结论。我会看看建议的解决方法并尝试一下。
  • 它几乎可以通过在问题线程中使用建议的 Dockerfile 来工作。只缺少一个符号。但该线程与最近的新闻有关,我会跟进这些事件。看来他们已经接近修复了。 ldd /usr/local/go/pkg/linux_amd64_dynlink/libstd.so /lib/ld-musl-x86_64.so.1 (0x7f03e5e0b000) libc.musl-x86_64.so.1 => /lib/ld-musl-x86_64.so.1 (0x7f03e5e0b000) Error relocating /usr/local/go/pkg/linux_amd64_dynlink/libstd.so: main.main: symbol not found
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-27
  • 2022-08-16
  • 2021-10-20
  • 2019-03-17
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多