android / ndk

The Android Native Development Kit
1.99k stars 257 forks source link

[BUG] Throwing Inside a Catch Block Triggers a Segmentation Fault ARM 32 bit with c++_shared #1240

Closed Devacor closed 4 years ago

Devacor commented 4 years ago

Description

I get the following Segmentation Fault in vs2019 using NDK 21.1.6352462 when attempting to throw from within a catch block:

libSDL2.so!__gnu_Unwind_Resume(_Unwind_Control_Block * ucbp, phase2_vrs * entry_vrs) Line 482   C++
libSDL2.so!___Unwind_Resume() Line 357  C++
libbindstonemain.so!throwtest() Line 9  C++
libbindstonemain.so!SDL_main(int argc, char ** argv) Line 14    C++
libSDL2.so!Java_org_libsdl_app_SDLActivity_nativeRunMain(JNIEnv * env, jclass cls, jstring library, jstring function, jobject array) Line 674   C

When excecuting the following (built as a .so file for SDL2).

#include <iostream>
#include "SDL.h"

void throwtest() {
    try {
        throw std::exception(); //This is fine.
    } catch (...) {
        throw std::exception(); //Segmentation Fault occurs here.
    }
}

int main(int argc, char *argv[]) {
    try {
        throwtest();
    } catch (...) {
        std::cout << "Caught!";
    }
    std::cout << "YAY!";

    return 0;
}

When looking in vs2019 at my linker command line options I have the following:

-o"C:\git\Bindstone\Builds\Android\ARM\Debug\libbindstonemain.so" -Wl,-rpath-link="C:\android-studio-android-sdk\ndk\21.1.6352462\platforms\android-29\arch-arm\usr\lib" -Wl,-z,relro "C:\git\Bindstone\Builds\Android\ARM\Debug\libs\libSDL2.so" "C:\git\Bindstone\Builds\Android\ARM\Debug\libSDL2_Image.so" "C:\git\Bindstone\Builds\Android\ARM\Debug\libSDL2_ttf.so" -Wl,-soname="libbindstonemain.so" -shared -Wl,-z,noexecstack -Wl,--no-undefined -l"android_support" -l"c++_shared" -l"c++abi" -l"log" -l"android" -l"GLESv1_CM" -l"GLESv2" -l"OpenSLES" -l"m" -l"z" -Wl,-L"C:\android-studio-android-sdk\ndk\21.1.6352462\platforms\android-29\arch-arm\usr\lib" -Wl,-L"C:\android-studio-android-sdk\ndk\21.1.6352462\toolchains\arm-linux-androideabi-4.9\prebuilt\windows-x86_64\lib\gcc\arm-linux-androideabi\4.9.x\armv7-a" -Wl,-L"C:\android-studio-android-sdk\ndk\21.1.6352462\sources\cxx-stl\llvm-libc++\libs\armeabi-v7a" -Wl,-L"C:\git\Bindstone\ARM\Debug" -Wl,-L"C:\git\Bindstone\Builds\Android\ARM\Debug\libs\" -Wl,-L"C:\git\Bindstone\Builds\Android\ARM\Debug\" -Wl,-L"C:\git\Bindstone\External\boost_1.71.0\libs\llvm-ndk20\libs\armv7-a" -Wl,-z,now 

My C++ build options are as follows:

-fpic -std=c++1z -fstack-protector -x c++ "C:\git\Bindstone\Builds\Intermediate\Android\BindstoneClient\main\ARM\Debug\" -Wall -fno-strict-aliasing -I "C:\android-studio-android-sdk\ndk\21.1.6352462\sysroot\usr\include" -I "C:\android-studio-android-sdk\ndk\21.1.6352462\sources\cxx-stl\llvm-libc++\include" -I "C:\android-studio-android-sdk\ndk\21.1.6352462\sources\cxx-stl\llvm-libc++abi\includeC:\android-studio-android-sdk\ndk\21.1.6352462\sources\cxx-stl\llvm-libc++\include" -I "C:\android-studio-android-sdk\ndk\21.1.6352462\sources\cxx-stl\llvm-libc++abi\include" -I "C:\android-studio-android-sdk\ndk\21.1.6352462\sysroot\usr\include\arm-linux-androideabi" -I "C:\android-studio-android-sdk\ndk\21.1.6352462\sources\android\support\include" -I "C:\git\Bindstone\VSProjects\SDL2\include" -I "C:\git\Bindstone\VSProjects\SDL2_ttf\include" -I "C:\git\Bindstone\VSProjects\SDL2_Image\include" -I "C:\git\Bindstone\Source" -I "C:\git\Bindstone\External" -I "C:\git\Bindstone\External\cereal\include" -I "C:\git\Bindstone\External\ChaiScript-6.1.0\include" -I "C:\git\Bindstone\External\gl3w\include" -I "C:\git\Bindstone\External\wolfssl-4.3.0" -I "C:\git\Bindstone\External\wolfssl-4.3.0\wolfssl" -I "C:\git\Bindstone\External\wolfssljni\native" -I "C:\git\Bindstone\External\boost_1.71.0\include" -g2 -gdwarf-2 -O0 -isystem "C:\android-studio-android-sdk\ndk\21.1.6352462\sysroot\usr\include\arm-linux-androideabi" -x c++-header -D "__ANDROID_API__=29" -D "CEREAL_FUTURE_EXPERIMENTAL" -D "OPENSSL_NO_SSL3" -D "OPENSSL_NO_SSL2" -D "ASIO_USE_WOLFSSL" -D "BOOST_ASIO_USE_WOLFSSL" -D "OPENSSL_ALL" -D "WOLFSSL_JNI" -D "WOLFSSL_DTLS" -D "HAVE_CRL" -D "HAVE_CRL_MONITOR" -D "HAVE_OCSP" -D "PERSIST_SEASON_CACHE" -D "PERSIST_CERT_CACHE" -D "ATOMIC_USER" -D "HAVE_ECC" -D "TFM_ECC356" -D "HAVE_PK_CALLBACKS" -D "HAVE_DH" -D "USE_FAST_MATH" -D "TFM_TIMING_RESISTANT" -D "ECC_TIMING_RESISTANT" -D "WC_RSA_BLINDING" -D "TFM_NO_ASM" -D "HAVE_TLS_EXTENSIONS" -frtti -fno-omit-frame-pointer -mthumb -fexceptions -mfloat-abi=softfp -o "C:\git\Bindstone\Builds\Intermediate\Android\BindstoneClient\main\ARM\Debug\%(filename).o" -fno-short-enums 

This does not reproduce under any other ABI except for 32 bit armeabi-v7a. I'm running this on an Amazon Kindle HD 8.

Arm64, and x64 both work fine. I have not tested x86.

I struggle to throw an exception at all when utilizing c++_static and it crashes for a different reason.

Here is a minimum repro example, requires visual studio 2019: http://mutedvision.com/docs/NDKArmExceptionRepro.zip

Environment Details

Filed with Microsoft/Visual Studio Here: https://developercommunity.visualstudio.com/content/problem/999749/ndk-armeabi-v7a-gnu-unwind-resume-sigsegv-upon-thr.html

DanAlbert commented 4 years ago

I'm not seeing --exclude-libs anywhere in the link flags, so that's most likely the problem. https://android.googlesource.com/platform/ndk/+/master/docs/BuildSystemMaintainers.md is the doc for setting up a build system to use the NDK.

You might also want to read through https://github.com/android/ndk/issues/1192

Devacor commented 4 years ago

Apologies I did not update the issue, I've followed the directions there as best I could by adding:

--exclude-libs,libgcc.a --exclude-libs,libgcc_real.a --exclude-libs,libunwind.a

I am able to get the exception to throw, but throwing from within the catch is failing. For some reason I'm able to in android studio so I'm not sure if it's due to different .so files being built.

If anyone has a moment to download my min repro and see for yourself, please let me know!

Devacor commented 4 years ago

Reading through the story it was very similar to mine. I did read all the same docs, but nowhere did I see I needed to add unwind to my list of library dependencies!

Adding that resolved my issue: In VS2019 I set Library Dependencies to: GLESv1_CM;GLESv2;android;log;OpenSLES;m;z;unwind;c++_shared;c++abi;

And added the following to my Linker/Additional Options: -Wl,--exclude-libs,libgcc.a -Wl,--exclude-libs,libgcc_real.a -Wl,--exclude-libs,libunwind.a

And I am using c++_shared for my use of STL in the VS2019 project options and in my Application.mk file for good measure: APP_STL := c++_shared APP_CPPFLAGS += -fexceptions -frtti -fno-gnu-unique

I set this up in all of my .so files (I have SDL dependencies and so set it up on each of those as well as my main .so)

It works!

DanAlbert commented 4 years ago

It's not necessary. For some reason Visual Studio appears to be requiring it, but that's almost certainly a bug in their system because this isn't required anywhere else.

I'm confused though, are you using ndk-build or visual studio?

Devacor commented 4 years ago

I'm using Visual Studio, but I wasn't sure if Visual Studio drills down and calls ndk-build or not, apologies for my ignorance here, the ide wraps a bunch of clang calls and I'm not an android expert so I likely just mis-labeled it.

I believe msbuild is the name of their system but I was confused due to the use of clang + android ndk toolchains it's really invoking under the hood.

DanAlbert commented 4 years ago

Are your edits to Android.mk/Application.mk having any effect? If so, sounds like it's using ndk-build? I really have no idea how this works either. We don't support Visual Studio (but I'm happy to try to help if I can).

DanAlbert commented 4 years ago

What do I actually do with your test case? It seems to just be your entire VSProjects directory.

DanAlbert commented 4 years ago

VSProjects/BindstoneClient/BindstoneClient_AndroidGradle/app/src/main/jniLibs/x86_64/libc++_shared.so is not r21's libc++. I don't know what it is, but it's missing the Android note section. It might be the library from r16, which iirc was the only NDK Visual Studio ever supported. I don't think your configuration is valid.

Devacor commented 4 years ago

As far as the x86_64 folder, do not worry about that one, I haven't built for it in some time and Visual Studio only copies libraries to that folder from your android ndk folder at the time of building so it is totally stale.

With that said, I'll take a moment to share with you my setup and help you familiarize with Visual Studio's android support as best I can since you have downloaded my repro case and I'd love to empower the Android team to know a little more about this tool flow!

1) You'll need to download VS2019. 2) Installing VS2019 requires these packages (available through the visual studio installer) to build an NDK project: a) Desktop development with C++ b) Mobile development with .NET c) Mobile development with C++ d) Possibly: Linux development with C++

Then in individual components, make sure you also have: e) HAXM - Beware if you are on a bootcamp installation of mac osx you may need this work-around: https://medium.com/@andrea.bresolin/windows-10-on-mac-with-boot-camp-making-intel-haxm-work-without-crashing-the-system-39555854f815 f) OpenJDK

3) Now that you have visual studio installed, you'll need to set it up to build android projects. To do so, you will want to go to "tools/Android/Android SDK Manager" and then it is suggested to use the Microsoft repo which supports up to NDK 20.1.5948944 at the time of writing. You'll want to get the appropriate Android SDK Tools, LLDB, Extras, optionally the Android Emulator, Platform Tools, and SDK Build Tools, and the appropriate platforms. (NOTE: I am manually pointing my NDK at the latest I got through Android Studio's SDK Manager in the process of trying to see if the exception issue I was encountering would repro with the latest. I saw no difference between Google's hosted v21 vs Microsoft hosted v20.)

  1. Select Tools/Options/Xamarin. Set up paths to your JDK & Android SDK Mine are: C:\Program Files\Android\Jdk\microsoft_dist_openjdk_1.8.0.25 C:\android-sdk

5) Go to Tools/Options/Cross Platform/C++ and set up your Android SDK (again, really) and Android NDK folders: Here I have C:\android-sdk C:\android-studio-android-sdk\ndk\21.1.6352462

But before when I was using microsoft's hosted NDK I had my NDK folder set to: C:\android-sdk\ndk-bundle

At this point in time you should be able to build and run!

Please let me know if you have any questions, I think it would be extremely beneficial to facilitate more familiarity with Visual Studio across the NDK teams (and on Microsoft's side I think they could really stand to be more in-touch with the NDK so they wrap this stuff properly!)

Whatever small amount I can do to help I am happy to do. I am a novice with build systems and the primary reason I'm using Visual Studio for this is because I am not terribly familiar with CMake and ported an existing project to Android from PC and wanted to keep everything within the same IDE I was familiar with (and enjoy) and avoid maintaining multiple build systems.

Visual Studio does have cmake support now too, but I hadn't spent time investigating that just yet.

Devacor commented 4 years ago

In addition to see all my build parameters for each project it's a mixture of values set by right clicking on each project and going to "Properties" and the gradle template files. This stuff all seems to be driving microsoft's build system which seems to wrap the ndk build system (I think).

DanAlbert commented 4 years ago

Thanks for the info!

I think it would be extremely beneficial to facilitate more familiarity with Visual Studio across the NDK teams (and on Microsoft's side I think they could really stand to be more in-touch with the NDK so they wrap this stuff properly!)

Yeah, we're more than happy to give them guidance, but we unfortunately don't have the bandwidth to support more build systems than we already do. I'll try to find some time to play with this and/or the case in #1192 because I'm genuinely curious as to what's broken here, but getting the environment needed to test this will be a non-trivial amount of time that I can't spend right now. I suspect it is an msbuild issue, and you both have workarounds, so that shouldn't leave either of you blocked.