【发布时间】:2020-05-19 07:33:19
【问题描述】:
在 Alpine 映像中内置的 GO 可执行文件存在一个奇怪的行为,其中标准 LD_PRELOAD 功能无法正常工作。
看起来构造函数没有被动态加载器调用!
我有一个示例 Go 应用程序 (getgoogle.go):
package main
import (
"fmt"
"net/http"
)
func main() {
resp, err := http.Get("http://google.com/")
if err == nil {
fmt.Println(resp.StatusCode)
}
}
以及示例共享对象代码 (libldptest.c)
#include <stdio.h>
static void __attribute__((constructor)) StaticConstructor(int argc, char **argv, char **env)
{
printf(">>> LD_PRELOADED!\n");
}
我正在使用这个 Dockerfile(gotest 图像)创建一个基于 debian 的 docker 映像:
FROM golang
COPY libldptest.c hello-world.go /
RUN gcc -shared -o /libldptest.so /libldptest.c
RUN go build -gcflags='-N -l' -o /getgoogle /getgoogle.go
ENV LD_PRELOAD=/libldptest.so
然后运行以下命令:
$docker run -it gotest /getgoogle
>>> LD_PRELOADED!
200
这意味着构造函数在这里工作。
但是当对一个基于 alpine 的 docker 镜像做同样的事情时
FROM golang:1.12-alpine
RUN apk add gcc libc-dev
COPY libldptest.c hello-world.go /
RUN gcc -shared -o /libldptest.so /libldptest.c
RUN go build -gcflags='-N -l' -o /getgoogle /getgoogle.go
ENV LD_PRELOAD=/libldptest.so
并运行与上面相同的命令
$docker run -it gotest /getgoogle
200
$docker run -it gotest ls
>>> LD_PRELOADED!
bin src
意味着运行 go 应用程序时没有调用静态构造函数! (但在运行ls时被调用)
请注意,我已经检查过动态加载器将库添加到进程空间。
如果能理解它为什么不起作用,我将不胜感激。
【问题讨论】:
-
这解释了问题!
-
这个我真的没看过,不过好像和问题有关……
-
需要做的是将我的构造函数添加到
__CTOR_LIST__表中,因为它是在没有GO的Alpine loader中调用的。我正在研究如何做到这一点
标签: c go alpine ld-preload