Android NDK: Call to System.loadLibrary Results in SIGSEGV Code=1

2

I have a massive C/C++ library that I'm trying to use through JNI for an Android project. It's comprised of several classes that were originally written for MFC and we've ported them over for execution on the Android environment.

The library builds fine (at least according to ndk-build). The size of the library is 56 MB in size.

When I call System.loadLibrary, the application terminates with the following being logged:

Fatal Signal 11 (SIGSEGV) at 0x00000004 (Code = 1), thread 16123

I performed an objdump on my library and there is nothing at 0004. Here's the first few lines of the dump :

DYNAMIC SYMBOL TABLE:
00000000      DF *UND*  00000000 __cxa_finalize
002fe600 g    D  .bss   00000000 __dso_handle
002f1e9c g    D  .init_array    00000000 __INIT_ARRAY__
002f20a4 g    D  .fini_array    00000000 __FINI_ARRAY__
0011dc58 g    DF .text  000000ec WideToJava
00000000      DF *UND*  00000000 __android_log_print
0021f460 g    DF .text  00000030 wcslen
00000000      DF *UND*  00000000 malloc
00000000      DF *UND*  00000000 free
0011dd44 g    DF .text  000000e4 WideToJava2
0011de28 g    DF .text  0000004e JavaToWSZ
0027443c g    DF .text  0000001c _Znaj
0011dec4  w   DF .text  00000018 

I then performed a readelf to see if there is another library that needs to be loaded, listed here :

Dynamic section at offset 0x2d99e0 contains 28 entries:
  Tag        Type                         Name/Value
 0x00000003 (PLTGOT)                     0x2fe464
 0x00000002 (PLTRELSZ)                   776 (bytes)
 0x00000017 (JMPREL)                     0x11d4a0
 0x00000014 (PLTREL)                     REL
 0x00000011 (REL)                        0x107770
 0x00000012 (RELSZ)                      89392 (bytes)
 0x00000013 (RELENT)                     8 (bytes)
 0x6ffffffa (RELCOUNT)                   11169
 0x00000006 (SYMTAB)                     0x128
 0x0000000b (SYMENT)                     16 (bytes)
 0x00000005 (STRTAB)                     0x31cd8
 0x0000000a (STRSZ)                      791389 (bytes)
 0x00000004 (HASH)                       0xf3038
 0x00000001 (NEEDED)                     Shared library: [liblog.so]
 0x00000001 (NEEDED)                     Shared library: [libandroid.so]
 0x00000001 (NEEDED)                     Shared library: [libstdc++.so]
 0x00000001 (NEEDED)                     Shared library: [libm.so]
 0x00000001 (NEEDED)                     Shared library: [libc.so]
 0x00000001 (NEEDED)                     Shared library: [libdl.so]
 0x0000000e (SONAME)                     Library soname: [libCSEntry.so]
 0x00000019 (INIT_ARRAY)                 0x2f1e9c
 0x0000001b (INIT_ARRAYSZ)               520 (bytes)
 0x0000001a (FINI_ARRAY)                 0x2f20a4
 0x0000001c (FINI_ARRAYSZ)               12 (bytes)
 0x00000016 (TEXTREL)                    0x0
 0x00000010 (SYMBOLIC)                   0x0
 0x0000001e (FLAGS)                      SYMBOLIC TEXTREL
 0x00000000 (NULL)                       0x0

Then I added those libraries before my call to loadLibrary :

public class ApplicationInterface 
{
 static
 {
  System.loadLibrary("log");
  System.loadLibrary("android");
  System.loadLibrary("stdc++");
  System.loadLibrary("m");
  System.loadLibrary("c");
  System.loadLibrary("dl");
  // when i call load library it blows up
  System.loadLibrary("CSEntry");
 }
// code
}

What's stranger is that there is a specific class that blows up this code. When I commented out the constructor to this class the library loads fine. I've verified that the constructor exists in the resulting library using objdump. I then proceeded to comment out the code in the constructor and it fails as well. Here's the offending code in the C++:

// Code
m_pPifFile = new CNPifFile(sPifFilePath);

m_pPifFile->SetAppType(ENTRY_TYPE);
m_pPifFile->SetAppFName(sApplicationFilename);
m_pPifFile->SetBinaryLoad(true);

// load the PIF file
if(m_pPifFile->LoadPifFile())
{
    // PIF file loaded create a new Run App
    // the offending line
    m_pRunAplEntry = new CRunAplEntry(m_pPifFile);
// Code

RunAplEntry.h

class AFX_EXT_CLASS CRunAplEntry : public CRunApl
{
public:
    CRunAplEntry(CNPifFile* pPifFile);
    ~CRunAplEntry();

// code
};

RunApl.h

class CLASS_DECL_ZBRIDGEO CRunApl : public CObject
{
public:
    CRunApl();
    virtual ~CRunApl();
// code
};

AFX_EXT_CLASS and CLASS_DECL_ZBRIDGEO are #defined to empty space.

We wrote a CObject equivalient for the Android NDK.

Here are the makefiles :

Application.mk

# set the platform to the latest processor type
APP_ABI                 := armeabi-v7a
# build for GNU STL
APP_STL                 := gnustl_static
# turn on exceptions and runtime type info
APP_CPPFLAGS            += -fexceptions -frtti

Android.mk

LOCAL_LDLIBS            := -llog -landroid $(BOOST_LIBS) -lgnustl_static
LOCAL_LDFLAGS           := -L$(BOOST_PATH)/lib/arm
LOCAL_CFLAGS            := -D__GLIBC__=1
LOCAL_CFLAGS            += -D_GLIBCXX_USE_C99_MATH=1
LOCAL_CFLAGS            += -DUNICODE=1
LOCAL_CFLAGS            += -D_UNICODE=1
LOCAL_CFLAGS            += -DGENERATE_BINARY=1
LOCAL_CFLAGS            += -DUSE_BINARY=1
LOCAL_CFLAGS            += -DPORTABLE=1
LOCAL_CFLAGS            += -fpermissive
LOCAL_CFLAGS            += $(CSPROMOBILE_INCLUDE)
LOCAL_STATIC_LIBRARIES  := Engine zTbdO zFormO zDictO zToolsO zUtilO zCommonO 

I've noticed that the GCC compiler doesn't handle virtual functions very well and I suspect this could be the problem, but I'm not sure. Here are the details for my environment.

NDK: Crystax r75 ABI Target: 4.6.3 ADT: v21.0.1-543035 Debug Device: Nexus 7

Any help will be greatly appreciated.

If you have any additional info please don't hesitate to ask.

Thanks, Will

c++
android-ndk
java-native-interface
segmentation-fault
loadlibrary
asked on Stack Overflow Jul 26, 2013 by willmapp • edited Dec 22, 2017 by Mathews Sunny

0 Answers

Nobody has answered this question yet.


User contributions licensed under CC BY-SA 3.0