Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

x/mobile: gomobile bind: Crash on android: dlopen failed: TLS symbol "(null)" in dlopened x86_64/libgojni.so using IE access model #69109

Open
marius-enlock opened this issue Aug 28, 2024 · 7 comments
Labels
mobile Android, iOS, and x/mobile NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one.
Milestone

Comments

@marius-enlock
Copy link

marius-enlock commented Aug 28, 2024

Go version

go version go1.21.0 linux/amd64

Output of go env in your module/workspace:

GO111MODULE=''
GOARCH='amd64'
GOBIN=''
GOCACHE='/home/marius/.cache/go-build'
GOENV='/home/marius/.config/go/env'
GOEXE=''
GOEXPERIMENT=''
GOFLAGS=''
GOHOSTARCH='amd64'
GOHOSTOS='linux'
GOINSECURE=''
GOMODCACHE='/home/marius/go/pkg/mod'
GONOPROXY=''
GONOSUMDB=''
GOOS='linux'
GOPATH='/home/marius/go'
GOPRIVATE=''
GOPROXY='https://proxy.golang.org,direct'
GOROOT='/usr/local/go'
GOSUMDB='sum.golang.org'
GOTMPDIR=''
GOTOOLCHAIN='auto'
GOTOOLDIR='/usr/local/go/pkg/tool/linux_amd64'
GOVCS=''
GOVERSION='go1.21.0'
GCCGO='gccgo'
GOAMD64='v1'
AR='ar'
CC='gcc'
CXX='g++'
CGO_ENABLED='1'
GOMOD='/home/marius/work/project/go.mod'
GOWORK='/home/marius/work/go.work'
CGO_CFLAGS='-O2 -g'
CGO_CPPFLAGS=''
CGO_CXXFLAGS='-O2 -g'
CGO_FFLAGS='-O2 -g'
CGO_LDFLAGS='-O2 -g'
PKG_CONFIG='pkg-config'
GOGCCFLAGS='-fPIC -m64 -pthread -Wl,--no-gc-sections -fmessage-length=0 -ffile-prefix-map=/tmp/go-build238633052=/tmp/go-build -gno-record-gcc-switches'

What did you do?

I am creating a go library for Android that I use in React Native. The go library uses CGO (and has a as a dependency a static library that is built against android ndk llvm libc++ ), and also uses gRPC for communication with the server (However in the gRPC package I do not rely on TLS - I have a custom connection protocol, nor anywhere in the library I rely on TLS)

CC_FOR_TARGET=/home/marius/work/android-ndk-r26b/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/lib/x86_64-linux-android34-clang gomobile bind -target android/amd64 -androidapi 34 -o enlockd.aar ./mobile/

And then I load the .aar archive into a react native project in the respective android project, and created the library data bindings in Kotlin. The project compiles.

What did you see happen?

My Android Kotlin binding that loads the library compiles and I can build it from react native, but when loading it into the Android emulator (Pixel 3a API 34 x86_64) I get the following Crash:

--------- beginning of crash
08-28 18:23:13.711 11376 11425 E AndroidRuntime: FATAL EXCEPTION: create_react_context
08-28 18:23:13.711 11376 11425 E AndroidRuntime: Process: com.enlockmobile, PID: 11376
08-28 18:23:13.711 11376 11425 E AndroidRuntime: java.lang.UnsatisfiedLinkError: dlopen failed: TLS symbol "(null)" in dlopened "/data/app/~~DwBiQaHdfiu5-dwMAj1Ulw==/com.enlockmobile-6XrWB7ekbVezJa8jWGp8QQ==/base.apk!/lib/x86_64/libgojni.so" referenced from "/data/app/~~DwBiQaHdfiu5-dwMAj1Ulw==/com.enlockmobile-6XrWB7ekbVezJa8jWGp8QQ==/base.apk!/lib/x86_64/libgojni.so" using IE access model
08-28 18:23:13.711 11376 11425 E AndroidRuntime: 	at java.lang.Runtime.loadLibrary0(Runtime.java:1082)
08-28 18:23:13.711 11376 11425 E AndroidRuntime: 	at java.lang.Runtime.loadLibrary0(Runtime.java:1003)
08-28 18:23:13.711 11376 11425 E AndroidRuntime: 	at java.lang.System.loadLibrary(System.java:1661)
08-28 18:23:13.711 11376 11425 E AndroidRuntime: 	at go.Seq.<clinit>(Seq.java:37)
08-28 18:23:13.711 11376 11425 E AndroidRuntime: 	at mobile.Mobile.<clinit>(Mobile.java:12)
08-28 18:23:13.711 11376 11425 E AndroidRuntime: 	at mobile.API.<clinit>(API.java:11)
08-28 18:23:13.711 11376 11425 E AndroidRuntime: 	at com.enlockmobile.Service.<init>(Service.kt:38)
08-28 18:23:13.711 11376 11425 E AndroidRuntime: 	at com.enlockmobile.ServicePackage.createNativeModules(Service.kt:27)
08-28 18:23:13.711 11376 11425 E AndroidRuntime: 	at com.facebook.react.ReactPackageHelper.getNativeModuleIterator(ReactPackageHelper.java:35)
08-28 18:23:13.711 11376 11425 E AndroidRuntime: 	at com.facebook.react.NativeModuleRegistryBuilder.processPackage(NativeModuleRegistryBuilder.java:40)
08-28 18:23:13.711 11376 11425 E AndroidRuntime: 	at com.facebook.react.ReactInstanceManager.processPackage(ReactInstanceManager.java:1510)
08-28 18:23:13.711 11376 11425 E AndroidRuntime: 	at com.facebook.react.ReactInstanceManager.processPackages(ReactInstanceManager.java:1481)
08-28 18:23:13.711 11376 11425 E AndroidRuntime: 	at com.facebook.react.ReactInstanceManager.createReactContext(ReactInstanceManager.java:1392)
08-28 18:23:13.711 11376 11425 E AndroidRuntime: 	at com.facebook.react.ReactInstanceManager.lambda$runCreateReactContextOnNewThread$2(ReactInstanceManager.java:1161)
08-28 18:23:13.711 11376 11425 E AndroidRuntime: 	at com.facebook.react.ReactInstanceManager.$r8$lambda$PrBhihCbbAFk4ZReAALGanVLCyc(Unknown Source:0)
08-28 18:23:13.711 11376 11425 E AndroidRuntime: 	at com.facebook.react.ReactInstanceManager$$ExternalSyntheticLambda1.run(D8$$SyntheticClass:0)
08-28 18:23:13.711 11376 11425 E AndroidRuntime: 	at java.lang.Thread.run(Thread.java:1012)
08-28 18:23:14.543   418   418 E BpTransactionCompletedListener: Failed to transact (-32)
08-28 18:23:15.144   585  1658 E TaskPersister: File error accessing recents directory (directory doesn't exist?).

(I think a relevant document is this one: https://android.googlesource.com/platform/bionic/+/HEAD/docs/elf-tls.md)

What did you expect to see?

I was expecting for the react native program to not crash.

@marius-enlock
Copy link
Author

marius-enlock commented Aug 28, 2024

I have also tried with go version 1.23.0, the exact same problem.

@prattmic prattmic changed the title gomobile bind: Crash on android: dlopen failed: TLS symbol "(null)" in dlopened x86_64/libgojni.so using IE access model x/mobile: gomobile bind: Crash on android: dlopen failed: TLS symbol "(null)" in dlopened x86_64/libgojni.so using IE access model Aug 28, 2024
@prattmic
Copy link
Member

cc @hyangah

@prattmic prattmic added this to the Unreleased milestone Aug 28, 2024
@prattmic prattmic added the NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. label Aug 28, 2024
@gopherbot gopherbot added the mobile Android, iOS, and x/mobile label Aug 28, 2024
@marius-enlock
Copy link
Author

marius-enlock commented Sep 2, 2024

I have went through all the above links and they do not solve this problem.
The NDK build tools and the CC must be the above ones due to React Native version 0.75.2.

The exact same crash error messages occurs in this Issue: mjansson/rpmalloc#332
For my project I think it comes from a different symbol, not the TLS_MODEL

I have checked the symbols from the libgojni.so with nm -j and the following ones mention TLS

crypto/tls.aesgcmCiphers
crypto/tls.CipherSuites
crypto/tls.(*ConnectionState).ExportKeyingMaterial
crypto/tls._CurveID_index_0
crypto/tls.(*CurveID).String
crypto/tls.CurveID.String
crypto/tls.disabledCipherSuites
crypto/tls.globalCertCache
crypto/tls.hasAESGCMHardwareSupport
crypto/tls.hasGCMAsmAMD64
crypto/tls.hasGCMAsmARM64
crypto/tls.hasGCMAsmS390X
crypto/tls.init
crypto/tls..inittask
crypto/tls.InsecureCipherSuites
crypto/tls..stmp_1
crypto/tls..stmp_2
crypto/tls..stmp_3
crypto/tls..stmp_4
crypto/tls.supportedOnlyTLS12
crypto/tls.supportedOnlyTLS13
crypto/tls.supportedUpToTLS12
crypto/tls.tdesCiphers
__emutls_unregister_key
go:itab.*google.golang.org/grpc/credentials.TLSChannelzSecurityValue,google.golang.org/grpc/credentials.ChannelzSecurityValue
go:itab.google.golang.org/grpc/credentials.TLSInfo,google.golang.org/grpc/credentials.AuthInfo
google.golang.org/grpc/credentials.(*TLSInfo).AuthType
google.golang.org/grpc/credentials.TLSInfo.AuthType
google.golang.org/grpc/credentials.(*TLSInfo).GetCommonAuthInfo
google.golang.org/grpc/credentials.TLSInfo.GetCommonAuthInfo
google.golang.org/grpc/credentials.(*TLSInfo).GetSecurityValue
google.golang.org/grpc/credentials.TLSInfo.GetSecurityValue
inittls
__libc_tls_generation_copy
runtime.settls.abi0
runtime.tls_g
__set_tls
__tls_get_addr
x_cgo_inittls
_Z17__init_static_tlsPv
_Z18__free_dynamic_tlsP10bionic_tcb
_Z22__free_temp_bionic_tlsP10bionic_tls
_Z22__init_bionic_tls_ptrsP10bionic_tcbP10bionic_tls
_Z24__bionic_get_tls_segmentPK10elf64_phdrmyP10TlsSegment
_Z26__allocate_temp_bionic_tlsv
_Z28__bionic_check_tls_alignmentPm
_Z28__set_stack_and_tls_vma_nameb
_ZL22tls_get_addr_slow_pathPK8TlsIndex
_ZN15StaticTlsLayout13finish_layoutEv
_ZN15StaticTlsLayout18reserve_bionic_tlsEv
_ZN15StaticTlsLayout27reserve_exe_segment_and_tcbEPK10TlsSegmentPKc
_ZN15StaticTlsLayout28round_up_with_overflow_checkEmm
_ZN15StaticTlsLayout7reserveEmm
_ZNK15StaticTlsLayout21offset_thread_pointerEv
_ZZL17layout_static_tlsR19KernelArgumentBlockE3mod

I suspect (without proof or good reasoning) it might be from __tls_get_addr() (I might have read a mention in an issue which I can't find),
or crypto/tls.init (I might have read a mention in an issue of an init function which I can't find),
or x_cgo_inittls (based on one of the above metioned links)

In the C library I link with CGO, I do not have any mentions of TLS symbols, nor dependencies on it.

I use this imports that might produce some of the above symbols in my go project:

"crypto/aes"
"crypto/cipher"
"crypto/rand"	

@marius-enlock
Copy link
Author

I have checked the crypto library, and the grpc library, and it doesn't seem to use CGO to load any TLS library, I think the issue is not from there.

@marius-enlock
Copy link
Author

marius-enlock commented Sep 3, 2024

ldd libgojni.so

	linux-vdso.so.1 (0x00007ffd5cd7a000)
	liblog.so => not found
	libandroid.so => not found
	libc++_shared.so => not found

I checked liblog and libandroid with readelf -a and there are no TLS symbols,
I suspect the culprit is libc++_shared.so as there are the TLS symbols
The exact library is this one:

android-ndk-r26b/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/lib/x86_64-linux-android/libc++_shared.so

Where android-ndk-r26b is extracted from the linux archive from here: https://github.com/android/ndk/releases/tag/r26b

I think the issue might originate from here:
android/ndk#1679: Clang will now automatically enable ELF TLS for
minSdkVersion 29 or higher.

@marius-enlock
Copy link
Author

In the file using CGO, I have tried passing the following flags:

-Wl,-plugin-opt=-emulated-tls=0

And in my gomobile bind command this flags:

 CGO_CFLAGS="-fno-emulated-tls" 

And it doesn't solve the issue, it is the same crash and error.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
mobile Android, iOS, and x/mobile NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one.
Projects
None yet
Development

No branches or pull requests

4 participants