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

[BUG] ndk-build unhandled exception #1043

Closed
Thirumalai opened this issue Jul 13, 2019 · 9 comments
Closed

[BUG] ndk-build unhandled exception #1043

Thirumalai opened this issue Jul 13, 2019 · 9 comments
Assignees
Labels

Comments

@Thirumalai
Copy link

This is yet another report of unhandled exception while using libc++ and more or less same as #533 or #519

The project consists of 2 native libs where the first library will call a function on the second library. When there is an exception, it will try to catch it. When ndk-build is used to build the native libs (even with rtti), the exception is not handled if the second library loaded prior to the first one. But, the same is properly handled when CMake is used to build the libs (except when rtti is disabled).

It looks like ndk-build misses some flags or passing some flags that can cause this issue.

Sample:
https://drive.google.com/open?id=1C3MefjGn0h1uQKC-JThuTrmIpfxjhb1Y

Environment Details

  • NDK Version: r20
  • Build system: ndk-build
  • Host OS: Mac
  • ABI: arm64-v8a, armeabi-v7a
  • NDK API level: 21
  • Device API level: 28
@Thirumalai Thirumalai added the bug label Jul 13, 2019
@alexcohn
Copy link

Maybe for ndk-build, APP_STL is defined differently.

@Thirumalai
Copy link
Author

Thirumalai commented Jul 14, 2019

Maybe for ndk-build, APP_STL is defined differently.

Both are using c++_static. You can confirm the same with the sample I have shared. It consists of multiple modules and product flavours for each configuration.

  1. CMake Build with RTTI (enabled by default on CMake builds)
  2. CMake Build without RTTI
  3. ndk-build with RTTI
  4. ndk-build without RTTI

When RTTI is enabled, the same code works for CMake builds despite the loading sequence of native libraries. But, it crashes with ndk-build.

@alexcohn
Copy link

alexcohn commented Jul 14, 2019 via email

@Thirumalai
Copy link
Author

Thirumalai commented Jul 15, 2019

It's not safe to use static STL when different libraries pass C++ objects one to the other, including exceptions. Essentially, you now have two independent runtime frameworks, and their housekeeping may fail. It's not an immediate disaster, as when you try to mix stlport with gnustl, but having a latent vulnerability that may get triggered by some circumstances beyond your control, is even worse. Try to build your app with c++_shared. BR, Alex

On Sun, 14 Jul 2019, 17:13 ThirumalaiK, @.***> wrote: Maybe for ndk-build, APP_STL is defined differently. Both are using c++_static. You can confirm the same with the sample I have shared. It consists of multiple modules and product flavours for each configuration. 1. CMake Build with RTTI (enabled by default on CMake builds) 2. CMake Build without RTTI 3. ndk-build with RTTI 4. ndk-build without RTTI When RTTI is enabled, the same code works for CMake builds despite the loading sequence of native libraries. But, the same crashes with ndk-build. — You are receiving this because you commented. Reply to this email directly, view it on GitHub <#1043?email_source=notifications&email_token=AAFTZM6W6TLHHSU6XIYE4ADP7MYBJA5CNFSM4IC74E5KYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGODZ4GHCI#issuecomment-511206281>, or mute the thread https://github.com/notifications/unsubscribe-auth/AAFTZM4JFDU2QROECF2JDN3P7MYBJANCNFSM4IC74E5A .

Thanks for the suggestions. We have a larger project that uses c++_static and ndk-build at the moment and it is the only STL used throughout the project. I wonder how CMake manages to build the libs properly while ndk-build fails. I just compared the type info of resulted libraries. CMake build doesn't have any duplicates on the FirstLib and produces 73% smaller library.

TypeInfo for CMake build

    12: 0000000000000000     0 OBJECT  GLOBAL DEFAULT  UND typeinfo for std::exception
    74: 00000000000205e0    24 OBJECT  GLOBAL DEFAULT   18 typeinfo for std::__ndk1::future_error
    95: 00000000000208b8    24 OBJECT  GLOBAL DEFAULT   18 typeinfo for std::length_error
   100: 000000000000d0cd    21 OBJECT  GLOBAL DEFAULT   12 typeinfo name for std::invalid_argument
   105: 000000000000d0f3    17 OBJECT  GLOBAL DEFAULT   12 typeinfo name for std::out_of_range
   111: 0000000000020470    24 OBJECT  GLOBAL DEFAULT   18 typeinfo for std::__ndk1::system_error
   116: 0000000000020878    24 OBJECT  GLOBAL DEFAULT   18 typeinfo for std::invalid_argument
   124: 0000000000020708    16 OBJECT  GLOBAL DEFAULT   18 typeinfo for std::__ndk1::__shared_count
   135: 000000000000d139    20 OBJECT  GLOBAL DEFAULT   12 typeinfo name for std::underflow_error
   147: 0000000000020750    40 OBJECT  GLOBAL DEFAULT   18 typeinfo for std::__ndk1::__shared_weak_count
   171: 000000000000ceec    21 OBJECT  GLOBAL DEFAULT   12 typeinfo name for std::nested_exception
   184: 000000000000d0e2    17 OBJECT  GLOBAL DEFAULT   12 typeinfo name for std::length_error
   185: 0000000000020798    16 OBJECT  GLOBAL DEFAULT   18 typeinfo for std::nested_exception
   194: 000000000000ca8f    28 OBJECT  GLOBAL DEFAULT   12 typeinfo name for std::__ndk1::error_category
   206: 000000000000d114    18 OBJECT  GLOBAL DEFAULT   12 typeinfo name for std::runtime_error
   213: 0000000000020838    24 OBJECT  GLOBAL DEFAULT   18 typeinfo for std::domain_error
   218: 0000000000020938    24 OBJECT  GLOBAL DEFAULT   18 typeinfo for std::runtime_error
   224: 000000000000cdd8    31 OBJECT  GLOBAL DEFAULT   12 typeinfo name for std::__ndk1::__assoc_sub_state
   243: 0000000000020990    24 OBJECT  GLOBAL DEFAULT   18 typeinfo for std::overflow_error
   253: 000000000000d0bd    16 OBJECT  GLOBAL DEFAULT   12 typeinfo name for std::logic_error
   257: 000000000000ce2a    26 OBJECT  GLOBAL DEFAULT   12 typeinfo name for std::__ndk1::bad_weak_ptr
   259: 0000000000020628    24 OBJECT  GLOBAL DEFAULT   18 typeinfo for std::__ndk1::__assoc_sub_state
   261: 00000000000209d0    24 OBJECT  GLOBAL DEFAULT   18 typeinfo for std::underflow_error
   262: 000000000000ce44    28 OBJECT  GLOBAL DEFAULT   12 typeinfo name for std::__ndk1::__shared_count
   268: 000000000000cdbe    26 OBJECT  GLOBAL DEFAULT   12 typeinfo name for std::__ndk1::future_error
   272: 000000000000d104    16 OBJECT  GLOBAL DEFAULT   12 typeinfo name for std::range_error
   274: 000000000000ce60    33 OBJECT  GLOBAL DEFAULT   12 typeinfo name for std::__ndk1::__shared_weak_count
   294: 00000000000208f8    24 OBJECT  GLOBAL DEFAULT   18 typeinfo for std::out_of_range
   301: 0000000000020820    24 OBJECT  GLOBAL DEFAULT   18 typeinfo for std::logic_error
   306: 000000000000d126    19 OBJECT  GLOBAL DEFAULT   12 typeinfo name for std::overflow_error
   307: 000000000000ca75    26 OBJECT  GLOBAL DEFAULT   12 typeinfo name for std::__ndk1::system_error
   312: 0000000000020488    16 OBJECT  GLOBAL DEFAULT   18 typeinfo for std::__ndk1::error_category
   317: 000000000000d0ac    17 OBJECT  GLOBAL DEFAULT   12 typeinfo name for std::domain_error
   322: 0000000000020950    24 OBJECT  GLOBAL DEFAULT   18 typeinfo for std::range_error
   325: 00000000000206c8    24 OBJECT  GLOBAL DEFAULT   18 typeinfo for std::__ndk1::bad_weak_ptr

TypeInfo for ndk-build

    58: 000000000004d1b0    16 OBJECT  GLOBAL DEFAULT   18 typeinfo for float
    60: 000000000004d2a0    16 OBJECT  GLOBAL DEFAULT   18 typeinfo for __float128
    62: 000000000004cda0    16 OBJECT  GLOBAL DEFAULT   18 typeinfo for unsigned char
    64: 000000000004cee0    16 OBJECT  GLOBAL DEFAULT   18 typeinfo for int
    66: 000000000004cf30    16 OBJECT  GLOBAL DEFAULT   18 typeinfo for unsigned int
    69: 000000000004cf80    16 OBJECT  GLOBAL DEFAULT   18 typeinfo for long
    71: 000000000004cfd0    16 OBJECT  GLOBAL DEFAULT   18 typeinfo for unsigned long
    72: 000000000004d0c0    16 OBJECT  GLOBAL DEFAULT   18 typeinfo for __int128
    75: 000000000004d110    16 OBJECT  GLOBAL DEFAULT   18 typeinfo for unsigned __int128
    77: 000000000004ce40    16 OBJECT  GLOBAL DEFAULT   18 typeinfo for short
    78: 000000000004ce90    16 OBJECT  GLOBAL DEFAULT   18 typeinfo for unsigned short
    79: 000000000004c7d8    16 OBJECT  GLOBAL DEFAULT   18 typeinfo for std::__ndk1::error_category
    82: 000000000004cc10    16 OBJECT  GLOBAL DEFAULT   18 typeinfo for void
    83: 000000000004cd00    16 OBJECT  GLOBAL DEFAULT   18 typeinfo for wchar_t
    85: 000000000004d020    16 OBJECT  GLOBAL DEFAULT   18 typeinfo for long long
    87: 000000000004d070    16 OBJECT  GLOBAL DEFAULT   18 typeinfo for unsigned long long
    90: 000000000004d908    24 OBJECT  GLOBAL DEFAULT   18 typeinfo for std::runtime_error
    91: 0000000000033d2d    12 OBJECT  GLOBAL DEFAULT   12 typeinfo name for std::bad_cast
    98: 000000000004caa0    40 OBJECT  GLOBAL DEFAULT   18 typeinfo for std::__ndk1::__shared_weak_count
   101: 0000000000033c29    18 OBJECT  GLOBAL DEFAULT   12 typeinfo name for std::bad_exception
   126: 000000000004d848    24 OBJECT  GLOBAL DEFAULT   18 typeinfo for std::invalid_argument
   129: 0000000000033af7     4 OBJECT  GLOBAL DEFAULT   12 typeinfo name for half*
   130: 0000000000033b3f     4 OBJECT  GLOBAL DEFAULT   12 typeinfo name for char32_t*
   134: 0000000000033a64     4 OBJECT  GLOBAL DEFAULT   12 typeinfo name for decltype(nullptr)*
   137: 0000000000033afb     5 OBJECT  GLOBAL DEFAULT   12 typeinfo name for half const*
   139: 0000000000033b43     5 OBJECT  GLOBAL DEFAULT   12 typeinfo name for char32_t const*
   140: 0000000000033b33     4 OBJECT  GLOBAL DEFAULT   12 typeinfo name for char16_t*
   145: 0000000000033a68     5 OBJECT  GLOBAL DEFAULT   12 typeinfo name for decltype(nullptr) const*
   147: 000000000004cbf8    24 OBJECT  GLOBAL DEFAULT   18 typeinfo for __cxxabiv1::__fundamental_type_info
   150: 0000000000033b37     5 OBJECT  GLOBAL DEFAULT   12 typeinfo name for char16_t const*
   159: 0000000000033cee    20 OBJECT  GLOBAL DEFAULT   12 typeinfo name for std::underflow_error
   162: 000000000004ca18    24 OBJECT  GLOBAL DEFAULT   18 typeinfo for std::__ndk1::bad_weak_ptr
   165: 000000000004cb40    24 OBJECT  GLOBAL DEFAULT   18 typeinfo for __cxxabiv1::__pointer_type_info
   171: 000000000004cb70    24 OBJECT  GLOBAL DEFAULT   18 typeinfo for __cxxabiv1::__pointer_to_member_type_info
   176: 000000000004cae8    16 OBJECT  GLOBAL DEFAULT   18 typeinfo for std::nested_exception
   186: 000000000004d8c8    24 OBJECT  GLOBAL DEFAULT   18 typeinfo for std::out_of_range
   191: 000000000004d9a0    24 OBJECT  GLOBAL DEFAULT   18 typeinfo for std::underflow_error
   201: 000000000004d6f8    16 OBJECT  GLOBAL DEFAULT   18 typeinfo for std::exception
   205: 000000000004d4a0    24 OBJECT  GLOBAL DEFAULT   18 typeinfo for __cxxabiv1::__enum_type_info
   210: 000000000004c930    24 OBJECT  GLOBAL DEFAULT   18 typeinfo for std::__ndk1::future_error
   213: 0000000000033c61    17 OBJECT  GLOBAL DEFAULT   12 typeinfo name for std::domain_error
   215: 0000000000033cc9    18 OBJECT  GLOBAL DEFAULT   12 typeinfo name for std::runtime_error
   220: 0000000000033c1c    13 OBJECT  GLOBAL DEFAULT   12 typeinfo name for std::exception
   225: 0000000000033cdb    19 OBJECT  GLOBAL DEFAULT   12 typeinfo name for std::overflow_error
   235: 0000000000033460    33 OBJECT  GLOBAL DEFAULT   12 typeinfo name for std::__ndk1::__shared_weak_count
   243: 0000000000033d39    15 OBJECT  GLOBAL DEFAULT   12 typeinfo name for std::bad_typeid
   252: 000000000004d170    32 OBJECT  GLOBAL DEFAULT   18 typeinfo for half*
   256: 000000000004d3a0    32 OBJECT  GLOBAL DEFAULT   18 typeinfo for char32_t*
   257: 0000000000033ca8    17 OBJECT  GLOBAL DEFAULT   12 typeinfo name for std::out_of_range
   260: 000000000004cc70    32 OBJECT  GLOBAL DEFAULT   18 typeinfo for decltype(nullptr)*
   262: 000000000004d350    32 OBJECT  GLOBAL DEFAULT   18 typeinfo for char16_t*
   266: 0000000000033078    26 OBJECT  GLOBAL DEFAULT   12 typeinfo name for std::__ndk1::system_error
   275: 000000000004caf8    24 OBJECT  GLOBAL DEFAULT   18 typeinfo for __cxxabiv1::__shim_type_info
   276: 0000000000033444    28 OBJECT  GLOBAL DEFAULT   12 typeinfo name for std::__ndk1::__shared_count
   281: 000000000004cb58    24 OBJECT  GLOBAL DEFAULT   18 typeinfo for __cxxabiv1::__function_type_info
   286: 0000000000033a93     3 OBJECT  GLOBAL DEFAULT   12 typeinfo name for signed char*
   287: 0000000000033a6f     3 OBJECT  GLOBAL DEFAULT   12 typeinfo name for bool*
   288: 0000000000033a81     3 OBJECT  GLOBAL DEFAULT   12 typeinfo name for char*
   290: 0000000000033b0b     3 OBJECT  GLOBAL DEFAULT   12 typeinfo name for double*
   292: 0000000000033b14     3 OBJECT  GLOBAL DEFAULT   12 typeinfo name for long double*
   293: 0000000000033b02     3 OBJECT  GLOBAL DEFAULT   12 typeinfo name for float*
   294: 0000000000033b1d     3 OBJECT  GLOBAL DEFAULT   12 typeinfo name for __float128*
   296: 0000000000033a8a     3 OBJECT  GLOBAL DEFAULT   12 typeinfo name for unsigned char*
   297: 0000000000033aae     3 OBJECT  GLOBAL DEFAULT   12 typeinfo name for int*
   298: 0000000000033ab7     3 OBJECT  GLOBAL DEFAULT   12 typeinfo name for unsigned int*
   299: 0000000000033ac0     3 OBJECT  GLOBAL DEFAULT   12 typeinfo name for long*
   300: 0000000000033ac9     3 OBJECT  GLOBAL DEFAULT   12 typeinfo name for unsigned long*
   302: 0000000000033ae4     3 OBJECT  GLOBAL DEFAULT   12 typeinfo name for __int128*
   303: 0000000000033aed     3 OBJECT  GLOBAL DEFAULT   12 typeinfo name for unsigned __int128*
   305: 0000000000033a9c     3 OBJECT  GLOBAL DEFAULT   12 typeinfo name for short*
   307: 0000000000033aa5     3 OBJECT  GLOBAL DEFAULT   12 typeinfo name for unsigned short*
   310: 0000000000033a5a     3 OBJECT  GLOBAL DEFAULT   12 typeinfo name for void*
   312: 0000000000033a78     3 OBJECT  GLOBAL DEFAULT   12 typeinfo name for wchar_t*
   314: 0000000000033ad2     3 OBJECT  GLOBAL DEFAULT   12 typeinfo name for long long*
   316: 0000000000033adb     3 OBJECT  GLOBAL DEFAULT   12 typeinfo name for unsigned long long*
   321: 0000000000033b6a    33 OBJECT  GLOBAL DEFAULT   12 typeinfo name for __cxxabiv1::__enum_type_info
   325: 0000000000033958    34 OBJECT  GLOBAL DEFAULT   12 typeinfo name for __cxxabiv1::__class_type_info
   329: 000000000004d960    24 OBJECT  GLOBAL DEFAULT   18 typeinfo for std::overflow_error
   330: 00000000000339c0    37 OBJECT  GLOBAL DEFAULT   12 typeinfo name for __cxxabiv1::__function_type_info
   336: 000000000004ce00    32 OBJECT  GLOBAL DEFAULT   18 typeinfo for signed char*
   338: 000000000004ccc0    32 OBJECT  GLOBAL DEFAULT   18 typeinfo for bool*
   340: 000000000004cd60    32 OBJECT  GLOBAL DEFAULT   18 typeinfo for char*
   342: 0000000000033a96     4 OBJECT  GLOBAL DEFAULT   12 typeinfo name for signed char const*
   343: 000000000004d210    32 OBJECT  GLOBAL DEFAULT   18 typeinfo for double*
   344: 0000000000033a72     4 OBJECT  GLOBAL DEFAULT   12 typeinfo name for bool const*
   345: 000000000004d260    32 OBJECT  GLOBAL DEFAULT   18 typeinfo for long double*
   346: 0000000000033a84     4 OBJECT  GLOBAL DEFAULT   12 typeinfo name for char const*
   347: 000000000004d1c0    32 OBJECT  GLOBAL DEFAULT   18 typeinfo for float*
   348: 000000000004c978    24 OBJECT  GLOBAL DEFAULT   18 typeinfo for std::__ndk1::__assoc_sub_state
   349: 0000000000033b0e     4 OBJECT  GLOBAL DEFAULT   12 typeinfo name for double const*
   352: 000000000004d2b0    32 OBJECT  GLOBAL DEFAULT   18 typeinfo for __float128*
   354: 0000000000033b17     4 OBJECT  GLOBAL DEFAULT   12 typeinfo name for long double const*
   355: 000000000004cdb0    32 OBJECT  GLOBAL DEFAULT   18 typeinfo for unsigned char*
   356: 000000000004d888    24 OBJECT  GLOBAL DEFAULT   18 typeinfo for std::length_error
   358: 000000000003399c    36 OBJECT  GLOBAL DEFAULT   12 typeinfo name for __cxxabiv1::__pointer_type_info
   359: 0000000000033b05     4 OBJECT  GLOBAL DEFAULT   12 typeinfo name for float const*
   360: 000000000004cef0    32 OBJECT  GLOBAL DEFAULT   18 typeinfo for int*
   361: 0000000000033b20     4 OBJECT  GLOBAL DEFAULT   12 typeinfo name for __float128 const*
   362: 0000000000033c82    21 OBJECT  GLOBAL DEFAULT   12 typeinfo name for std::invalid_argument
   365: 000000000004cf40    32 OBJECT  GLOBAL DEFAULT   18 typeinfo for unsigned int*
   366: 0000000000033a8d     4 OBJECT  GLOBAL DEFAULT   12 typeinfo name for unsigned char const*
   367: 000000000004cf90    32 OBJECT  GLOBAL DEFAULT   18 typeinfo for long*
   368: 0000000000033ab1     4 OBJECT  GLOBAL DEFAULT   12 typeinfo name for int const*
   369: 0000000000033aba     4 OBJECT  GLOBAL DEFAULT   12 typeinfo name for unsigned int const*
   370: 000000000004cfe0    32 OBJECT  GLOBAL DEFAULT   18 typeinfo for unsigned long*
   371: 000000000004d0d0    32 OBJECT  GLOBAL DEFAULT   18 typeinfo for __int128*
   372: 0000000000033ac3     4 OBJECT  GLOBAL DEFAULT   12 typeinfo name for long const*
   375: 000000000004d120    32 OBJECT  GLOBAL DEFAULT   18 typeinfo for unsigned __int128*
   376: 0000000000033acc     4 OBJECT  GLOBAL DEFAULT   12 typeinfo name for unsigned long const*
   377: 0000000000033ae7     4 OBJECT  GLOBAL DEFAULT   12 typeinfo name for __int128 const*
   379: 0000000000033af0     4 OBJECT  GLOBAL DEFAULT   12 typeinfo name for unsigned __int128 const*
   380: 000000000004ce50    32 OBJECT  GLOBAL DEFAULT   18 typeinfo for short*
   381: 000000000004cea0    32 OBJECT  GLOBAL DEFAULT   18 typeinfo for unsigned short*
   383: 000000000004cc20    32 OBJECT  GLOBAL DEFAULT   18 typeinfo for void*
   384: 0000000000033a9f     4 OBJECT  GLOBAL DEFAULT   12 typeinfo name for short const*
   385: 0000000000033092    28 OBJECT  GLOBAL DEFAULT   12 typeinfo name for std::__ndk1::error_category
   386: 000000000004cd10    32 OBJECT  GLOBAL DEFAULT   18 typeinfo for wchar_t*
   387: 0000000000033aa8     4 OBJECT  GLOBAL DEFAULT   12 typeinfo name for unsigned short const*
   388: 00000000000339e5    46 OBJECT  GLOBAL DEFAULT   12 typeinfo name for __cxxabiv1::__pointer_to_member_type_info
   389: 000000000004d030    32 OBJECT  GLOBAL DEFAULT   18 typeinfo for long long*
   390: 000000000004d080    32 OBJECT  GLOBAL DEFAULT   18 typeinfo for unsigned long long*
   392: 0000000000033a5d     4 OBJECT  GLOBAL DEFAULT   12 typeinfo name for void const*
   394: 0000000000033a7b     4 OBJECT  GLOBAL DEFAULT   12 typeinfo name for wchar_t const*
   396: 0000000000033ad5     4 OBJECT  GLOBAL DEFAULT   12 typeinfo name for long long const*
   398: 0000000000033ade     4 OBJECT  GLOBAL DEFAULT   12 typeinfo name for unsigned long long const*
   401: 0000000000033a91     2 OBJECT  GLOBAL DEFAULT   12 typeinfo name for signed char
   404: 000000000004d730    24 OBJECT  GLOBAL DEFAULT   18 typeinfo for std::bad_exception
   405: 0000000000033a6d     2 OBJECT  GLOBAL DEFAULT   12 typeinfo name for bool
   407: 0000000000033a7f     2 OBJECT  GLOBAL DEFAULT   12 typeinfo name for char
   409: 0000000000033b09     2 OBJECT  GLOBAL DEFAULT   12 typeinfo name for double
   412: 0000000000033b12     2 OBJECT  GLOBAL DEFAULT   12 typeinfo name for long double
   413: 0000000000033b00     2 OBJECT  GLOBAL DEFAULT   12 typeinfo name for float
   415: 0000000000033b1b     2 OBJECT  GLOBAL DEFAULT   12 typeinfo name for __float128
   417: 0000000000033a88     2 OBJECT  GLOBAL DEFAULT   12 typeinfo name for unsigned char
   418: 0000000000033aac     2 OBJECT  GLOBAL DEFAULT   12 typeinfo name for int
   420: 0000000000033ab5     2 OBJECT  GLOBAL DEFAULT   12 typeinfo name for unsigned int
   423: 0000000000033abe     2 OBJECT  GLOBAL DEFAULT   12 typeinfo name for long
   425: 000000000004cb28    24 OBJECT  GLOBAL DEFAULT   18 typeinfo for __cxxabiv1::__pbase_type_info
   426: 0000000000033ac7     2 OBJECT  GLOBAL DEFAULT   12 typeinfo name for unsigned long
   427: 0000000000033ae2     2 OBJECT  GLOBAL DEFAULT   12 typeinfo name for __int128
   428: 0000000000033aeb     2 OBJECT  GLOBAL DEFAULT   12 typeinfo name for unsigned __int128
   431: 000000000004da50    24 OBJECT  GLOBAL DEFAULT   18 typeinfo for std::bad_typeid
   433: 0000000000033a9a     2 OBJECT  GLOBAL DEFAULT   12 typeinfo name for short
   434: 0000000000033aa3     2 OBJECT  GLOBAL DEFAULT   12 typeinfo name for unsigned short
   436: 0000000000033a58     2 OBJECT  GLOBAL DEFAULT   12 typeinfo name for void
   439: 0000000000033a76     2 OBJECT  GLOBAL DEFAULT   12 typeinfo name for wchar_t
   440: 000000000004da28    16 OBJECT  GLOBAL DEFAULT   18 typeinfo for std::type_info
   442: 0000000000033ad0     2 OBJECT  GLOBAL DEFAULT   12 typeinfo name for long long
   443: 000000000003397a    34 OBJECT  GLOBAL DEFAULT   12 typeinfo name for __cxxabiv1::__pbase_type_info
   444: 0000000000033ad9     2 OBJECT  GLOBAL DEFAULT   12 typeinfo name for unsigned long long
   446: 000000000004da38    24 OBJECT  GLOBAL DEFAULT   18 typeinfo for std::bad_cast
   447: 00000000000334ec    21 OBJECT  GLOBAL DEFAULT   12 typeinfo name for std::nested_exception
   450: 000000000004d418    24 OBJECT  GLOBAL DEFAULT   18 typeinfo for __cxxabiv1::__array_type_info
   454: 000000000003342a    26 OBJECT  GLOBAL DEFAULT   12 typeinfo name for std::__ndk1::bad_weak_ptr
   457: 0000000000033937    33 OBJECT  GLOBAL DEFAULT   12 typeinfo name for __cxxabiv1::__shim_type_info
   458: 0000000000033d20    13 OBJECT  GLOBAL DEFAULT   12 typeinfo name for std::type_info
   460: 0000000000033b48    34 OBJECT  GLOBAL DEFAULT   12 typeinfo name for __cxxabiv1::__array_type_info
   463: 000000000004d5c0    24 OBJECT  GLOBAL DEFAULT   18 typeinfo for __cxxabiv1::__vmi_class_type_info
   469: 0000000000033c97    17 OBJECT  GLOBAL DEFAULT   12 typeinfo name for std::length_error
   472: 0000000000033af4     3 OBJECT  GLOBAL DEFAULT   12 typeinfo name for half
   474: 0000000000033b3c     3 OBJECT  GLOBAL DEFAULT   12 typeinfo name for char32_t
   476: 0000000000033a61     3 OBJECT  GLOBAL DEFAULT   12 typeinfo name for decltype(nullptr)
   477: 000000000004cb10    24 OBJECT  GLOBAL DEFAULT   18 typeinfo for __cxxabiv1::__class_type_info
   478: 0000000000033b30     3 OBJECT  GLOBAL DEFAULT   12 typeinfo name for char16_t
   490: 000000000004d190    32 OBJECT  GLOBAL DEFAULT   18 typeinfo for half const*
   491: 00000000000333be    26 OBJECT  GLOBAL DEFAULT   12 typeinfo name for std::__ndk1::future_error
   492: 000000000004d3c0    32 OBJECT  GLOBAL DEFAULT   18 typeinfo for char32_t const*
   496: 000000000004d558    24 OBJECT  GLOBAL DEFAULT   18 typeinfo for __cxxabiv1::__si_class_type_info
   498: 000000000004d7f0    24 OBJECT  GLOBAL DEFAULT   18 typeinfo for std::logic_error
   500: 0000000000033c48    25 OBJECT  GLOBAL DEFAULT   12 typeinfo name for std::bad_array_new_length
   502: 000000000004cc90    32 OBJECT  GLOBAL DEFAULT   18 typeinfo for decltype(nullptr) const*
   507: 0000000000033c72    16 OBJECT  GLOBAL DEFAULT   12 typeinfo name for std::logic_error
   509: 000000000004d370    32 OBJECT  GLOBAL DEFAULT   18 typeinfo for char16_t const*
   522: 000000000004ce20    32 OBJECT  GLOBAL DEFAULT   18 typeinfo for signed char const*
   524: 000000000004cce0    32 OBJECT  GLOBAL DEFAULT   18 typeinfo for bool const*
   525: 000000000004cd80    32 OBJECT  GLOBAL DEFAULT   18 typeinfo for char const*
   526: 000000000004d230    32 OBJECT  GLOBAL DEFAULT   18 typeinfo for double const*
   529: 000000000004d280    32 OBJECT  GLOBAL DEFAULT   18 typeinfo for long double const*
   530: 000000000004d1e0    32 OBJECT  GLOBAL DEFAULT   18 typeinfo for float const*
   531: 000000000004d2d0    32 OBJECT  GLOBAL DEFAULT   18 typeinfo for __float128 const*
   532: 000000000004cdd0    32 OBJECT  GLOBAL DEFAULT   18 typeinfo for unsigned char const*
   533: 000000000004cf10    32 OBJECT  GLOBAL DEFAULT   18 typeinfo for int const*
   534: 000000000004cf60    32 OBJECT  GLOBAL DEFAULT   18 typeinfo for unsigned int const*
   535: 000000000004d160    16 OBJECT  GLOBAL DEFAULT   18 typeinfo for half
   537: 000000000004d390    16 OBJECT  GLOBAL DEFAULT   18 typeinfo for char32_t
   538: 000000000004cfb0    32 OBJECT  GLOBAL DEFAULT   18 typeinfo for long const*
   540: 000000000004d000    32 OBJECT  GLOBAL DEFAULT   18 typeinfo for unsigned long const*
   542: 000000000004d0f0    32 OBJECT  GLOBAL DEFAULT   18 typeinfo for __int128 const*
   544: 000000000004d140    32 OBJECT  GLOBAL DEFAULT   18 typeinfo for unsigned __int128 const*
   545: 000000000004cc60    16 OBJECT  GLOBAL DEFAULT   18 typeinfo for decltype(nullptr)
   546: 0000000000033a30    40 OBJECT  GLOBAL DEFAULT   12 typeinfo name for __cxxabiv1::__fundamental_type_info
   549: 000000000004ce70    32 OBJECT  GLOBAL DEFAULT   18 typeinfo for short const*
   550: 000000000004cec0    32 OBJECT  GLOBAL DEFAULT   18 typeinfo for unsigned short const*
   552: 000000000004d748    24 OBJECT  GLOBAL DEFAULT   18 typeinfo for std::bad_alloc
   553: 000000000004d340    16 OBJECT  GLOBAL DEFAULT   18 typeinfo for char16_t
   554: 000000000004cc40    32 OBJECT  GLOBAL DEFAULT   18 typeinfo for void const*
   556: 000000000004cd30    32 OBJECT  GLOBAL DEFAULT   18 typeinfo for wchar_t const*
   558: 000000000004d050    32 OBJECT  GLOBAL DEFAULT   18 typeinfo for long long const*
   559: 000000000004d0a0    32 OBJECT  GLOBAL DEFAULT   18 typeinfo for unsigned long long const*
   560: 000000000004ca58    16 OBJECT  GLOBAL DEFAULT   18 typeinfo for std::__ndk1::__shared_count
   565: 0000000000033b8b    37 OBJECT  GLOBAL DEFAULT   12 typeinfo name for __cxxabiv1::__si_class_type_info
   568: 0000000000033c3b    13 OBJECT  GLOBAL DEFAULT   12 typeinfo name for std::bad_alloc
   589: 000000000004d920    24 OBJECT  GLOBAL DEFAULT   18 typeinfo for std::range_error
   596: 0000000000033cb9    16 OBJECT  GLOBAL DEFAULT   12 typeinfo name for std::range_error
   604: 000000000004d808    24 OBJECT  GLOBAL DEFAULT   18 typeinfo for std::domain_error
   608: 000000000004c7c0    24 OBJECT  GLOBAL DEFAULT   18 typeinfo for std::__ndk1::system_error
   634: 00000000000333d8    31 OBJECT  GLOBAL DEFAULT   12 typeinfo name for std::__ndk1::__assoc_sub_state
   637: 000000000004cdf0    16 OBJECT  GLOBAL DEFAULT   18 typeinfo for signed char
   639: 0000000000033bb0    38 OBJECT  GLOBAL DEFAULT   12 typeinfo name for __cxxabiv1::__vmi_class_type_info
   643: 000000000004ccb0    16 OBJECT  GLOBAL DEFAULT   18 typeinfo for bool
   644: 000000000004cd50    16 OBJECT  GLOBAL DEFAULT   18 typeinfo for char
   645: 000000000004d200    16 OBJECT  GLOBAL DEFAULT   18 typeinfo for double
   649: 000000000004d760    24 OBJECT  GLOBAL DEFAULT   18 typeinfo for std::bad_array_new_length
   650: 000000000004d250    16 OBJECT  GLOBAL DEFAULT   18 typeinfo for long double

TypeInfo of SecondLib is identical in both builds. Could it be something related to the order of linking on ndk-build?

@DanAlbert
Copy link
Member

Added APP_LDFLAGS := -v to the ndk-build half to get the exact linker command used to match CMake, and the main difference seems to be in the ordering of how things are linked:

ndk-build:

  1. FirstLib.o
  2. libc++_static.a
  3. libc++abi.a
  4. libgcc
  5. libatomic
  6. libSecondLib.so
  7. liblog
    8 ...

CMake:

  1. FirstLib.o
  2. libSecondLib.so
  3. liblog
  4. libatomic
  5. libm
  6. libc++_static.a
  7. libc++abi.a
  8. libm
  9. libgcc

Note specifically how libSecondLib.so is linked very early with CMake, but in the appropriate place with ndk-build. This is causing FirstLib to (incorrectly) load most of libc++/libc++abi from SecondLib, which is preventing you from having multiple copies of the typeinfo for the standard library exceptions in your application. In this case this behavior is actually helping you, but this behavior can cause other issues (see any of the many threads here on crashes with arm32 exception handling caused by loading the unwinder from the wrong library).

gradlew check doesn't actually fail any tests for me, so I don't know how to quickly confirm this, but I suspect if you added -Wl,--exclude-libs,libc++abi.a -Wl,--exclude-libs,libc++_static.a to your cmake flags the CMake case would fail too. (I haven't had the guts to make this change since I don't know of any other build system or platform that does this, but I've often thought it would help solve a lot of problems in the NDK if we implicitly made all non-whole static libs use --exclude-libs)

The good news is that, like @alexcohn initially guessed, this should work for both systems once you get around to switching to libc++_shared. Like he says, using libc++_static when you have more than one shared library is something you really shouldn't do, specifically because it gets you into weird problems like this.

Closing because I think we have the diagnosis here. ndk-build links correctly, but the build as specified includes ODR violations. CMake doesn't link correctly and in doing so accidentally avoids the ODR violation. CMake linking order being wrong is not anything to do with the NDK, and can't realistically be fixed because it would require altering the behavior of upstream CMake.

@alexcohn
Copy link

alexcohn commented Jul 17, 2019

Wouldn't it be prudent to set visibility=hidden for symbols borrowed from libc++_static.a and libc++abi.a?

@DanAlbert
Copy link
Member

That's what --exclude-libs would do, but yes we could do it in the library itself as well. Probably much more reasonable to do it for those two libraries than it would be for all static libraries...

Reopening this to track that. I can't think of any problems off the top of my head.

@DanAlbert DanAlbert reopened this Jul 17, 2019
@DanAlbert DanAlbert self-assigned this Sep 19, 2019
@DanAlbert DanAlbert added this to the r21 milestone Sep 19, 2019
@DanAlbert
Copy link
Member

Testing this now for libc++_static.a, libc++abi.a, and libunwind.a. We already had this for libandroid_support.a. If that goes well it may be worth doing for libgcc.a as well.

@DanAlbert
Copy link
Member

That actually doesn't change much, since these libraries (quite reasonably) mark their API with __attribute__((visibility("default"))). That might be better anyway, but I'm guessing this isn't a common configuration (I'm worried that this is only mostly adhered to, and that we might break on any update) for these libraries so if the benefit is less significant then I'd rather stay on the beaten path here.

@DanAlbert DanAlbert removed this from the r21 milestone Sep 19, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants