Golang编译时使用旧版Glibc仍会调用Glibc 2.33中的某些符号

Golang编译时使用旧版Glibc仍会调用Glibc 2.33中的某些符号 我正在尝试在 Debian Bookworm 上编译一个与 Debian Bullseye 兼容的二进制文件。我已经解压了适用于 Bullseye 的旧版 Glibc/OpenSSL,并尝试链接它们:

export CGO_LDFLAGS="-Xlinker -rpath=/home/bodqhrohro/git/glibc/lib/x86_64-linux-gnu,-rpath=/home/bodqhrohro/git/libssl/usr/lib/x86_64-linux-gnu,--dynamic-linker=/home/bodqhrohro/git/glibc/lib64/ld-linux-x86-64.so.2 -L/home/bodqhrohro/git/libssl/usr/lib/x86_64-linux-gnu -L/home/bodqhrohro/git/glibc/lib/x86_64-linux-gnu -include /home/bodqhrohro/git/force_link_glibc_2.27.h"

但在生成的二进制文件中,仍然有一些符号需要 Glibc 2.33:

0000000000000000       F *UND*  0000000000000000              lstat64@GLIBC_2.33
0000000000000000       F *UND*  0000000000000000              fstat64@GLIBC_2.33
0000000000000000       F *UND*  0000000000000000              stat64@GLIBC_2.33

我该如何解决这个问题?


更多关于Golang编译时使用旧版Glibc仍会调用Glibc 2.33中的某些符号的实战教程也可以访问 https://www.itying.com/category-94-b0.html

2 回复

我低估了这个问题……还有更多符号需要 Glibc 2.34:

0000000000000000       F *UND*  0000000000000000              pthread_join@GLIBC_2.34
0000000000000000       F *UND*  0000000000000000              pthread_rwlock_destroy@GLIBC_2.34
0000000000000000  w    F *UND*  0000000000000000              __pthread_key_create@GLIBC_2.34
0000000000000000       F *UND*  0000000000000000              pthread_rwlock_rdlock@GLIBC_2.34
0000000000000000       F *UND*  0000000000000000              pthread_mutex_trylock@GLIBC_2.34
0000000000000000       F *UND*  0000000000000000              pthread_mutexattr_settype@GLIBC_2.34
0000000000000000       F *UND*  0000000000000000              pthread_setaffinity_np@GLIBC_2.34
0000000000000000       F *UND*  0000000000000000              pthread_kill@GLIBC_2.34
0000000000000000       F *UND*  0000000000000000              pthread_mutexattr_init@GLIBC_2.34
0000000000000000       F *UND*  0000000000000000              pthread_create@GLIBC_2.34
0000000000000000       F *UND*  0000000000000000              __libc_start_main@GLIBC_2.34
0000000000000000       F *UND*  0000000000000000              pthread_attr_getstacksize@GLIBC_2.34
0000000000000000       F *UND*  0000000000000000              pthread_rwlock_init@GLIBC_2.34
0000000000000000       F *UND*  0000000000000000              pthread_detach@GLIBC_2.34
0000000000000000       F *UND*  0000000000000000              pthread_mutexattr_destroy@GLIBC_2.34
0000000000000000       F *UND*  0000000000000000              pthread_setname_np@GLIBC_2.34
0000000000000000       F *UND*  0000000000000000              pthread_rwlock_unlock@GLIBC_2.34
0000000000000000       F *UND*  0000000000000000              pthread_rwlock_wrlock@GLIBC_2.34

更多关于Golang编译时使用旧版Glibc仍会调用Glibc 2.33中的某些符号的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


在 Go 编译时,即使指定了旧版 Glibc 的路径,某些符号仍可能链接到新版 Glibc,这是因为 Go 的运行时和标准库可能依赖较新的系统调用封装。以下是解决方案:

  1. 使用 CGO_ENABLED=0 进行静态编译(推荐): 这会完全避免链接 Glibc,但可能不适用于依赖 CGO 的项目。

    CGO_ENABLED=0 go build -o output_binary main.go
    
  2. 强制链接旧版符号: 创建包装头文件(如 glibc_compat.h),使用 asm 重定向符号。例如:

    // glibc_compat.h
    #include <sys/stat.h>
    
    // 重定向 stat64 到 stat64@GLIBC_2.2.5
    __asm__(".symver stat64, stat64@GLIBC_2.2.5");
    __asm__(".symver fstat64, fstat64@GLIBC_2.2.5");
    __asm__(".symver lstat64, lstat64@GLIBC_2.2.5");
    

    编译时通过 -include 包含此头文件:

    export CGO_CFLAGS="-include /path/to/glibc_compat.h"
    go build -o output_binary main.go
    
  3. 使用 -static 链接所有库: 如果项目依赖 CGO,可尝试静态链接 Glibc(需确保旧版 Glibc 支持静态链接):

    export CGO_LDFLAGS="-static -L/home/bodqhrohro/git/glibc/lib/x86_64-linux-gnu"
    go build -o output_binary main.go
    
  4. 通过 lddobjdump 验证符号: 编译后检查二进制文件的依赖和符号版本:

    objdump -T output_binary | grep -E "stat64|fstat64|lstat64"
    ldd output_binary
    

示例:完整编译命令(结合方法2):

export CGO_CFLAGS="-include /home/bodqhrohro/glibc_compat.h"
export CGO_LDFLAGS="-L/home/bodqhrohro/git/glibc/lib/x86_64-linux-gnu -Wl,-rpath=/home/bodqhrohro/git/glibc/lib/x86_64-linux-gnu"
go build -o bullseye_compatible_binary main.go

注意:Go 的工具链(如 go 命令本身)可能依赖系统 Glibc,建议在 Bullseye 环境中使用相同版本的 Go 进行编译,或使用 Docker 容器确保环境一致性。

回到顶部