alpine ctypes loadlibrary() 上的 python 失败并出现 OSError: 重新定位 ./cc.so: 时出错: : 初始执行 TLS 解析为 ./cc.so 中的动态定义

Cha*_*hen 5 python go docker alpine-linux

我致力于在基于 alpine 的容器上使用 golang 在 python 脚本(ctypes loadlibrary)中构建共享库。

但失败如下,

/usr/src/app # **go build -o cc.so -buildmode=c-shared main.go**

/usr/src/app # **readelf -d cc.so**

Dynamic section at offset 0x10cd10 contains 22 entries: Tag Type
Name/Value 0x0000000000000001 (NEEDED) Shared library:
[libc.musl-x86_64.so.1] 0x0000000000000010 (SYMBOLIC) 0x0
0x000000000000000c (INIT) 0x42000 0x000000000000000d (FINI) 0x92ed9
0x0000000000000019 (INIT_ARRAY) 0xa2078 0x000000000000001b
(INIT_ARRAYSZ) 8 (bytes) 0x000000006ffffef5 (GNU_HASH) 0x270
0x0000000000000005 (STRTAB) 0xa50 0x0000000000000006 (SYMTAB) 0x378
0x000000000000000a (STRSZ) 1026 (bytes) 0x000000000000000b (SYMENT) 24
(bytes) 0x0000000000000003 (PLTGOT) 0x10deb0 0x0000000000000002
(PLTRELSZ) 720 (bytes) 0x0000000000000014 (PLTREL) RELA
0x0000000000000017 (JMPREL) 0x41a00 0x0000000000000007 (RELA) 0xe58
0x0000000000000008 (RELASZ) 265128 (bytes) 0x0000000000000009
(RELAENT) 24 (bytes) 0x000000000000001e (FLAGS) SYMBOLIC BIND_NOW
STATIC_TLS 0x000000006ffffffb (FLAGS_1) Flags: NOW NODELETE
0x000000006ffffff9 (RELACOUNT) 11040 0x0000000000000000 (NULL) 0x0

/usr/src/app # **python test.py** 
Traceback (most recent call last): File
"test.py", line 2, in  lib = ctypes.cdll.LoadLibrary('./cc.so') File
"/usr/lib/python2.7/ctypes/init.py", line 444, in LoadLibrary return
self._dlltype(name) File "/usr/lib/python2.7/ctypes/init.py", line
366, in init self._handle = _dlopen(self._name, mode) OSError: Error
relocating ./cc.so: : initial-exec TLS resolves to dynamic definition
in ./cc.so
Run Code Online (Sandbox Code Playgroud)

我尝试过以下 docker 镜像

  1. Alpine 3.9安装go和python 2.7

  2. go1.12:alpine 和 python2.7:alpine 运行 go build 创建共享库(go build -o cc.so -buildmode=c-shared main.go) 然后将 cc.so 复制到 python2.7:alpine 容器,运行蟒蛇测试.py

一样的问题。

但如果我使用 ubuntu16.04 映像并安装 go 和 python 进行相同的测试,它就可以工作。

main.go和test.py如下,

//main.go
package main

import "C"

//export add
func add(left, right int) int {
return left + right
}

//export minus
func minus(left, right int) int {
return left - right
}

//export multiply
func multiply(left, right int) int {
return left * right
}

//export divide
func divide(left, right int) int {
return left / right
}

//export testPrint
func testPrint(){
print("test")
}

func main() {
}

// test.py
import ctypes
lib = ctypes.cdll.LoadLibrary('./cc.so')
if lib is not None:
print ("can load so")
Run Code Online (Sandbox Code Playgroud)