fraunhoferhhi / vvenc

VVenC, the Fraunhofer Versatile Video Encoder
https://www.hhi.fraunhofer.de/en/departments/vca/technologies-and-solutions/h266-vvc.html
BSD 3-Clause Clear License
899 stars 158 forks source link

undefined reference to _Unwind_Resume on android 7 (API 24-25) on arm64-v8a #397

Closed feelamee closed 3 days ago

feelamee commented 3 days ago

Hey. I built vvdec/vvenc with cmake and android-ndk-r26b using such command:

NAME="vvenc" \
ANDROID_ABI="arm64-v8a" \
ANDROID_PLATFORM="android-21" \
cmake -S . -B "../../target/{$NAME}_${ANDROID_ABI}_${ANDROID_PLATFORM}" \
-DCMAKE_TOOLCHAIN_FILE="../../toolchain/android-ndk-r26b/build/cmake/android.toolchain.cmake" \
-DANDROID_ABI="${ANDROID_ABI}" \
-DANDROID_PLATFORM="${ANDROID_PLATFORM}" \
-DCMAKE_INSTALL_PREFIX="../../vvc/${NAME}/${ANDROID_ABI}/${ANDROID_PLATFORM}/"

after I followed this guide and built ffmpeg.

In android application I load it using System.loadLibrary, which call dlopen. I tested it on android 13 (API 33) with arm64-v8a and all works. Also my colleague tested it on android < 7 and android > 7 But on android 7 I'm getting a crash Undefined reference to _Unwind_Resume.

This symbol exists in libgcc_s and libunwind. AFAIK, libunwind should be linked on android when exceptions was enabled.

I also tried to build your libs with -fno-exceptions, but you don't support this, as I understand. I saw in android.toolchain.cmake that it set CMAKE_ANDROID_EXCEPTIONS to TRUE if I will use ANDROID_CPP_FEATURES="exceptions". After that cmake should care about linking, but it not.

Have you any ideas how to fix this?

K-os commented 3 days ago

Yes, building without exceptions will not work, since we use exceptions internally in the en-/decoder.

I'll try to find out if we can ensure libunwind is linked also, but it will be difficult for me to reproduce since we don't have such an old android device.

K-os commented 3 days ago

I guess I understand the problem now: You build vvenc as a static library and link that into FFmpeg. Is that correct? The FFmpeg build doesn't know that it needs to link libunwind also, so it does not get loaded. On the non-Android 7 devices, libunwind was probably already loaded in the process, so it was not detected as missing.

I guess there are two options to fix your problem:

  1. Either build libvvenc as a shared library by adding -DBUILD_SHARED_LIBS=1 to your cmake step, and link FFmpeg against that.
  2. Or, you can try adding something like --extra-libs=-lunwind to your FFmpeg configure step
feelamee commented 3 days ago

Is that correct?

Yes, you right

I tried to link -lgcc_eh, -lunwind, but got the same error. I checked libffmpeg.so using llvm-readelf -d and it don't link anyone of this libs.

I also found how to enable exceptions if using ndk-build with Application.mk or Android.mk, but we building ffmpeg manually. So, I tried add --extra-cxxflags="-fexceptions" to ffmpeg ./configure and unfortunately took the same error.

I also found libunwind.so in /system/lib on android phone and tried to load it before loading libffmpeg.so in java source code. I took another error:

java.lang.UnsatisfiedLinkError: dlopen failed: library "/system/lib64/libunwind.so" needed or dlopened by "/system/lib64/libnativeloader.so" is not accessible for the namespace "classloader-namespace"

So, I will try to fix this or link libunwind.so to the ffmpeg and note solution here for other people with the same problem in the future.

Thanks for help.

feelamee commented 3 days ago

So, problem was in our build system.. I tried to add linker flags into ffmpeg configure, but we building static lib and after manually call ld to build shared.

I think, that adding -fexceptions should automatically add linker flags for unwind. I, in turn, added this flags manually to linker call.