C++ exceptions within Android environment

2,035 views
Skip to first unread message

Nathan Holstein

unread,
May 26, 2009, 11:14:46 AM5/26/09
to andro...@googlegroups.com, b...@lampreynetworks.com
I'm working on porting an existing C/C++ library and application suite from a desktop Linux environment to the Android platform.  The base is fairly large and complex (on the order of ~38000 loc), and uses some of the more advanced aspects of the C++ language, including exceptions and portions of the STL.

Since Bionic's libstdc++ does not include support for either the STL of exceptions, I created a support library to handle these portions of the code.  Adding the necessary STL support was fairly simple, however I've encountered issues with exceptions.

First, I added a simple modification to the build scripts allowing me to override Android's default '-fno-exceptions -fno-rtti' options, and ported the gcc suite's libsupc++ exception code into a standalone library.  Using this resultant library, I was able to successfully build and link an application using exceptions.  However, the code segfaults at runtime within the exception handling code, even when running a simple application which does nothing more than throw/catch an exception.

I've spent some time debugging this, to no avail.  The code seems to crash after entering __cxa_throw, however past that point I've had no luck following the execution. Inspecting core dumps is of limited usefulness due to the lack of frame pointer.

I know gcc has support for exceptions on the arm-eabi platform, however it appears that I haven't correctly compiled this support into my libraries.  Has anyone here attempted something similar on Android, or encountered a similar issue on other arm platforms?


   -Nathan

David Turner

unread,
May 26, 2009, 2:46:13 PM5/26/09
to andro...@googlegroups.com, b...@lampreynetworks.com
I can only confirm that C++ Exceptions and RTTI are not currently supported by the Android platform.

I doubt you would be able to have something like your code base run properly on Android-1.5 systems.
Proper support requires further modification to a few key system components that, while planned, are
not there yet.

Feel free to contribute system patches to r.android.com. You may find interesting details in the following
document: http://infocenter.arm.com/help/topic/com.arm.doc.ihi0041b/

Nathan Holstein

unread,
May 27, 2009, 8:50:33 PM5/27/09
to andro...@googlegroups.com
I've isolated where the crash occurs.  Within __cxa_type_match(...) the exception routines attempt to determine the type_info of the thrown exception.  In my simple test application, this is nothing more than a std::exception.  This type_info object lives in the .dynsym section of the executable, and shows up in gdb as the following:

(gdb) x /2 0xd490
0xd490 <_ZTISt9exception (typeinfo for std::exception)>:      0x00000000      0x00000000

(That's a null pointer to the vtable and typename, respectively).  Conversely, the libsupc--.so library does have correct the correct type information: by copying these values manually, I was able to successfully throw and catch the exception.

This problem seems to be due to Android's default use of the -Bsymbolic linker option [1].  By removing this option from the affected libraries, it indeed changes the linking of the type_info objects.  The resulting symbols all have the relocation type R_ARM_REL32.  Unfortunately, neither the runtime or prelinker have support for this symbol type.  I added the following code to the dynamic linker:

@@ -1236,6 +1236,13 @@ static int reloc_library(soinfo *si, Elf32_Rel *rel, unsigned count)
             break;
         case R_ARM_NONE:
             break;
+        case R_ARM_REL32:
+            COUNT_RELOC(RELOC_RELATIVE);
+            MARK(rel->r_offset);
+            TRACE_TYPE(RELO, "%5d RELO REL32 %08x <- %08x - %08x %s\n", pid,
+                       reloc, sym_addr, rel->r_offset, sym_name);
+            *((unsigned*)reloc) += sym_addr - rel->r_offset;
+            break;

This causes the type_info objects to link correctly, however the vtables still contain nulls, so the code isn't yet fully functional.


   --nathan


[1] http://www.gnu.org/software/gcc/faq.html#dso

David Turner

unread,
Jun 2, 2009, 9:23:19 AM6/2/09
to andro...@googlegroups.com
Thanks a lot for the information you submitted. We're looking at the issue but can't give you any estimate at when C++ exceptions and RTTI will be properly
supported on Android. It seems a lot of what you're doing is pushing the envelope, and it's likely you're going to face some restrictions on our current platform.

For the record, R_ARM_REL32 is not a valid relocation in dynamic executables. That's why it is not supported by the dynamic linker.
It is normally generated in object files, and must be removed/converted by the static linker at build time when generating your shared library.

See section 4.6.1.2 "Relocation Types" of the "Elf for the ARM Architecture" document for more details (a.k.a. ARM IHI 0044C)

I suspect a correct fix for the problem might require further fixes in the toolchain and/or C library.

Nathan Holstein

unread,
Jun 2, 2009, 10:09:30 AM6/2/09
to andro...@googlegroups.com
Looking again, you're right: my error from R_ARM_REL32 looks to be from when I was attempting to use the prelinker.  The current .so I've built doesn't have any R_ARM_REL32 symbols in it (and I'm currently not prelinking any of the libraries I have).

I did however find one major error with the dynamic linker apropos R_ARM_COPY symbols: they were being copied from/to identical addresses.  This was because /system/bin/linker was first looking in the local object before searching any others.  The result was the target symbol was found as the source symbol.  I posted this in android-development, but received no response[1].  Is there a bug tracker I can file this so it doesn't get lost?  I have patches against both bionic and the build scripts which allow compiling with exception support: it would be nice to have a central place to aggregate this.


   --nathan


[1] http://groups.google.com/group/android-platform/browse_thread/thread/2f654fc46335ad8c/71ca18f36c63af62?lnk=gst

David Turner

unread,
Jun 2, 2009, 10:17:13 AM6/2/09
to andro...@googlegroups.com
On Tue, Jun 2, 2009 at 4:09 PM, Nathan Holstein <nathan....@gmail.com> wrote:
Looking again, you're right: my error from R_ARM_REL32 looks to be from when I was attempting to use the prelinker.  The current .so I've built doesn't have any R_ARM_REL32 symbols in it (and I'm currently not prelinking any of the libraries I have).

I did however find one major error with the dynamic linker apropos R_ARM_COPY symbols: they were being copied from/to identical addresses.  This was because /system/bin/linker was first looking in the local object before searching any others.  The result was the target symbol was found as the source symbol.

Yes, this is a known issue. Essentially the dynamic linker doesn't implement RTLD_LOCAL at the moment, so everything is kept in a global context.
Just one of the many things that need to be fixed before reliably supporting C++ RTTI on Android !
 
  I posted this in android-development, but received no response[1].  Is there a bug tracker I can file this so it doesn't get lost?  I have patches against both bionic and the build scripts which allow compiling with exception support: it would be nice to have a central place to aggregate this.

You can still use b.android.com to file bug reports, but I would advise you to send a link to the newly entered bug on this list too.
The Android team is unfortunately still using an internal bug database for many system-related issues, and the public one is read much more infrequently.

You can send patches for review on r.android.com as well, it is by far the preferred way to submit and discuss them.

Thanks a lot in advance.
 
Reply all
Reply to author
Forward
0 new messages