2 Qt issues with Crypto++ on Android

177 views
Skip to first unread message

jh...@emocha.com

unread,
Jan 4, 2016, 2:44:37 PM1/4/16
to Crypto++ Users
I have two sets of issues. One seems to be linker related:

E/art ( 8857): dlopen("/data/app/com.app/lib/arm/libcryptopp-and.so", RTLD_LAZY) failed: dlopen failed: library "libstlport_shared.so" not found

So I add:

ANDROID_EXTRA_LIBS += /Users/jhihn/Downloads/android-ndk-r10e/sources/cxx-stl/stlport/libs/armeabi-v7a/libstlport_shared.so
That satisfied the linker, but that produces the std:string 0xdeadcab1 crash, as previously posted. This seems to be a result of a linking problem. The wiki says:

The second optional argument is a STL library. The default is STLport as a shared library due to GNU licensing requirements. STL libraries can be one of:

  • stlport (shared)
  • stlport-static
  • stlport-shared
  • gnu (shared)
  • gnu-static
  • gnu-shared

But I don't know why one would be better than the other. The Crypto++ docs seem to prefer stlport-shared. But why?

The std:string crash does not happen on OSX/iOS. It also doesn't happen on android until I use Crypto++ with std::strings.

Meanwhile, on all platforms, QString/QByteArray does not seem to "play nice" with Crypto++. QString when using constData() function just returns the .constData() toUtf8() byte array. Very weird things happen, like nulls being missed (QByteArray places a null at the end in most cases). I've used Qt's classes extensively and never had this issue. Does anyone know what is going on?

And that beings me to the third topic (not an issue):
Would anyone be interested in a Crypto Qt classes/overloads?







Jeffrey Walton

unread,
Jan 4, 2016, 3:28:14 PM1/4/16
to Crypto++ Users

The second optional argument is a STL library. The default is STLport as a shared library due to GNU licensing requirements. STL libraries can be one of:

  • stlport (shared)
  • stlport-static
  • stlport-shared
  • gnu (shared)
  • gnu-static
  • gnu-shared

But I don't know why one would be better than the other. The Crypto++ docs seem to prefer stlport-shared. But why?

This is simple, and has nothing to do with technical reasons.

Using GNU's C++ runtime means you are encumbered by a license. The license basically requires you (or your company) to share the source code with anyone using the product. Some folks are OK with the sharing, other folks are not.

There are no such encumbrances with STLport, so we use it by default.

Jeff

Jeffrey Walton

unread,
Jan 4, 2016, 3:39:03 PM1/4/16
to Crypto++ Users
> The std:string crash does not happen on OSX/iOS. It also doesn't happen on android until
> I use Crypto++ with std::strings.
> Meanwhile, on all platforms, QString/QByteArray does not seem to "play nice" with Crypto++.
> QString when using constData() function just returns the .constData() toUtf8() byte
> array. I've used Qt's classes extensively and never had this issue. Does anyone know
> what is going on?


This has earmarks of memory issues tied to low-level component incompatibility. Is the GNU C++ runtime being mixed with the STLport runtime? That is, do you know what Qt is using by default? If runtimes are being mixed and matched, then its one of the first things I would change.

I would also look at C++03 versus C++11.


> Very weird things happen, like nulls being missed (QByteArray places a null at the end
> in most cases).

This does not sound right (to me). I would expect a QString to have the NULL and perhaps perform the UTF-8 conversion. But I would not expect it from QByteArray, which should be closer to a std::vector.

Also, you can't modify things through a const-pointer. That's undefined behavior, IIRC. For the case of a std::string, that usually means you get the non-const pointer via &str[0]. I don't know what QString offers, but you might need to do the same.

Jeff

Jeffrey Walton

unread,
Jan 4, 2016, 3:51:07 PM1/4/16
to Crypto++ Users
> I have two sets of issues. One seems to be linker related:
>
> E/art ( 8857): dlopen("/data/app/com.app/lib/arm/libcryptopp-and.so",
> RTLD_LAZY) failed: dlopen failed: library "libstlport_shared.so" not found
>
> So I add:
>
> ANDROID_EXTRA_LIBS += /Users/jhihn/Downloads/android-ndk-r10e/sources/cxx-stl/
> stlport/libs/armeabi-v7a/libstlport_shared.so
>

This is always a point of frustration (for me)... How to get the libraries copied properly and in the right place in the lib/ folder. Under NDK-build, you use LOCAL_MODULE and LOCAL_SHARED_LIBRARIES. One ensures you compile/link against a library like stlport_shared, the other ensures stlport_shared is included in the libs/ directory.

Also see this Android.mk: http://github.com/noloader/Android-PRNG/blob/master/jni/Android.mk. It produces a prng.so called by Java, and it uses stlport_shared.so and cryptopp.so.

I’m not sure how Qt does things.

*****

Also note that getting the dlopen flags correct can be challenging. I use the following code (when needed) code because something that works on one platform does not work on another (from http://cryptopp.com/wiki/Linux#Note_for_Shared_Object_Callers):

  void* cryptlib = NULL;

  cryptlib = dlopen("libcryptopp.so", RTLD_GLOBAL);

  if(!cryptlib)
    cryptlib = dlopen("libcryptopp.so", RTLD_GLOBAL | RTLD_LAZY);

  if(!cryptlib)
    cryptlib = dlopen("libcrypto++.so", RTLD_GLOBAL);

  if(!cryptlib)
    cryptlib = dlopen("libcrypto++.so", RTLD_GLOBAL | RTLD_LAZY);

  if(!cryptlib)
    throw runtime_error("Failed to load crypto++ shared object");

  ...

  dlclose(cryptlib);

Jeff

jh...@emocha.com

unread,
Jan 4, 2016, 5:54:45 PM1/4/16
to Crypto++ Users
I think you figured it out for me, I need  RTLD_GLOBAL  in the dlopen() qt-generated android activity to load the library so that crypto++ can access it. Be default it is only specifying RTLD_LAZY

Jeffrey Walton

unread,
Jan 20, 2016, 4:21:48 PM1/20/16
to Crypto++ Users

Also note that getting the dlopen flags correct can be challenging. I use the following code (when needed) code because something that works on one platform does not work on another (from http://cryptopp.com/wiki/Linux#Note_for_Shared_Object_Callers):

  void* cryptlib = NULL;

  cryptlib = dlopen("libcryptopp.so", RTLD_GLOBAL);

  if(!cryptlib)
    cryptlib = dlopen("libcryptopp.so", RTLD_GLOBAL | RTLD_LAZY);

  if(!cryptlib)
    cryptlib = dlopen("libcrypto++.so", RTLD_GLOBAL);

  if(!cryptlib)
    cryptlib = dlopen("libcrypto++.so", RTLD_GLOBAL | RTLD_LAZY);

  if(!cryptlib)
    throw runtime_error("Failed to load crypto++ shared object");

  ...

  dlclose(cryptlib);

I think you figured it out for me, I need  RTLD_GLOBAL  in the dlopen() qt-generated android activity to load the library so that crypto++ can access it. Be default it is only specifying RTLD_LAZY
Reply all
Reply to author
Forward
0 new messages