libc : @@@ ABORTING: LIBC: ARGUMENT IS INVALID HEAP ADDRESS IN dlfree addr=0x00006ccc
DEBUG : backtrace:
DEBUG : #00 pc 0000f15c /system/lib/libc.so
DEBUG : #01 pc 00011f03 /system/lib/libc.so (dlfree+1458)
DEBUG : #02 pc 0000d073 /system/lib/libc.so (free+10)Hello,I encountered a problem sharing std::string's across library boundaries.We have a shared object that loads other shared objects at runtime using dlopen(). Part of the interface passes back a pointer to an object allocated with new. This object holds a std::string. We've been getting segfaults when the string in that object is empty and is being destructed.It seems that when an empty string is created, the data is set to the static member &std::string::_Rep::_S_empty_rep_storage. When the string is deleted, it is checked against this address, and if it differs the data is free'd.The problem seems to be that the empty string is created in the plugin, setting the address of _S_empty_rep_storage is the plugin one. Then when it is deleted in the main shared object the address checked in the dtor is the main shared object's _S_empty_rep_storage. It is different, so the dtor assumes that it is an allocated string and tries to delete it. I've confirmed this to be happening by stepping through and taking note of the addresses compared.Both the library and plugin SO are compiled using the libgnustl_static.a library provided by the NDK. Deploying with the libgnustl_shared.so fixes the issue, but I would like to avoid that if possible. Any ideas on workarounds?
As an aside, it seems in other GNU distributions of the static libstdc++ libraries STB_GNU_UNIQUE is set on _S_empty_rep_storage (as it is a static member variable), and so only one address exists for the whole process. At least that's the case on the one from the Linux Mint repo.
The logcat errors are something like this:libc : @@@ ABORTING: LIBC: ARGUMENT IS INVALID HEAP ADDRESS IN dlfree addr=0x00006ccc
DEBUG : backtrace:
DEBUG : #00 pc 0000f15c /system/lib/libc.so
DEBUG : #01 pc 00011f03 /system/lib/libc.so (dlfree+1458)
DEBUG : #02 pc 0000d073 /system/lib/libc.so (free+10)
--
You received this message because you are subscribed to the Google Groups "android-ndk" group.
To unsubscribe from this group and stop receiving emails from it, send an email to android-ndk...@googlegroups.com.
To post to this group, send email to andro...@googlegroups.com.
Visit this group at http://groups.google.com/group/android-ndk.
For more options, visit https://groups.google.com/d/optout.
II.3. Static runtimes:
Please keep in mind that the static library variant of a given C++ runtime SHALL ONLY BE LINKED INTO A SINGLE BINARY for optimal conditions.
What this means is that if your project consists of a single shared library, you can link against, e.g., stlport_static, and everything will work correctly.
On the other hand, if you have two shared libraries in your project (e.g. libfoo.so and libbar.so) which both link against the same static runtime, each one of them will include a copy of the runtime's code in its final binary image. This is problematic because certain global variables used/provided internally by the runtime are duplicated.
This is likely to result in code that doesn't work correctly, for example:
- memory allocated in one library, and freed in the other would leak or even corrupt the heap.
- exceptions raised in libfoo.so cannot be caught in libbar.so (and may simply crash the program).
- the buffering of std::cout not working properly
This problem also happens if you want to link an executable and a shared library to the same static library.
In other words, if your project requires several shared library modules, then use the shared library variant of your C++ runtime.